blob: 40526a465ed330046e237fbbc5933e461b2641bc [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
125#define HAVE_POPEN 1
126#define HAVE_SYSTEM 1
127#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000128#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000129#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#endif /* _MSC_VER */
131#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000132#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000133#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000134
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000136
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000137#if defined(sun) && !defined(__SVR4)
138/* SunOS 4.1.4 doesn't have prototypes for these: */
139extern int rename(const char *, const char *);
140extern int pclose(FILE *);
141extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000142extern int fsync(int);
143extern int lstat(const char *, struct stat *);
144extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000145#endif
146
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000147#if defined(__sgi)&&_COMPILER_VERSION>=700
148/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
149 (default) */
150extern char *ctermid_r(char *);
151#endif
152
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000153#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000156#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000157#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000158extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000161#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000162#endif
163#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000164extern int chdir(char *);
165extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000166#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int chdir(const char *);
168extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000169#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000170#ifdef __BORLANDC__
171extern int chmod(const char *, int);
172#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000173extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000174#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int chown(const char *, uid_t, gid_t);
176extern char *getcwd(char *, int);
177extern char *strerror(int);
178extern int link(const char *, const char *);
179extern int rename(const char *, const char *);
180extern int stat(const char *, struct stat *);
181extern int unlink(const char *);
182extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000185#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000188#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000190
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000191#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192
Guido van Rossumb6775db1994-08-01 11:34:53 +0000193#ifdef HAVE_UTIME_H
194#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000195#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000197#ifdef HAVE_SYS_UTIME_H
198#include <sys/utime.h>
199#define HAVE_UTIME_H /* pretend we do for the rest of this file */
200#endif /* HAVE_SYS_UTIME_H */
201
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYS_TIMES_H
203#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000204#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205
206#ifdef HAVE_SYS_PARAM_H
207#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000208#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
210#ifdef HAVE_SYS_UTSNAME_H
211#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000212#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000214#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000216#define NAMLEN(dirent) strlen((dirent)->d_name)
217#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000218#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000219#include <direct.h>
220#define NAMLEN(dirent) strlen((dirent)->d_name)
221#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000223#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000224#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000225#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000227#endif
228#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000230#endif
231#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#endif
234#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237#include <direct.h>
238#include <io.h>
239#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000240#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000241#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000243#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000245#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000246#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247
Guido van Rossumd48f2521997-12-05 22:19:34 +0000248#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000250#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251
Tim Petersbc2e10e2002-03-03 23:17:02 +0000252#ifndef MAXPATHLEN
253#define MAXPATHLEN 1024
254#endif /* MAXPATHLEN */
255
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000256#ifdef UNION_WAIT
257/* Emulate some macros on systems that have a union instead of macros */
258
259#ifndef WIFEXITED
260#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
261#endif
262
263#ifndef WEXITSTATUS
264#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
265#endif
266
267#ifndef WTERMSIG
268#define WTERMSIG(u_wait) ((u_wait).w_termsig)
269#endif
270
271#endif /* UNION_WAIT */
272
Greg Wardb48bc172000-03-01 21:51:56 +0000273/* Don't use the "_r" form if we don't need it (also, won't have a
274 prototype for it, at least on Solaris -- maybe others as well?). */
275#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
276#define USE_CTERMID_R
277#endif
278
279#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
280#define USE_TMPNAM_R
281#endif
282
Fred Drake699f3522000-06-29 21:12:41 +0000283/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000284#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000285#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000286# define STAT _stati64
287# define FSTAT _fstati64
288# define STRUCT_STAT struct _stati64
289#else
290# define STAT stat
291# define FSTAT fstat
292# define STRUCT_STAT struct stat
293#endif
294
Tim Peters11b23062003-04-23 02:39:17 +0000295#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000296#include <sys/mkdev.h>
297#else
298#if defined(MAJOR_IN_SYSMACROS)
299#include <sys/sysmacros.h>
300#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000301#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
302#include <sys/mkdev.h>
303#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000304#endif
Fred Drake699f3522000-06-29 21:12:41 +0000305
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000307#ifdef WITH_NEXT_FRAMEWORK
308/* On Darwin/MacOSX a shared library or framework has no access to
309** environ directly, we must obtain it with _NSGetEnviron().
310*/
311#include <crt_externs.h>
312static char **environ;
313#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000314extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000315#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316
Barry Warsaw53699e91996-12-10 23:23:01 +0000317static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000318convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319{
Barry Warsaw53699e91996-12-10 23:23:01 +0000320 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000321 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000322 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323 if (d == NULL)
324 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000325#ifdef WITH_NEXT_FRAMEWORK
326 if (environ == NULL)
327 environ = *_NSGetEnviron();
328#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 if (environ == NULL)
330 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000331 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000332 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000333 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000334 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335 char *p = strchr(*e, '=');
336 if (p == NULL)
337 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000338 k = PyString_FromStringAndSize(*e, (int)(p-*e));
339 if (k == NULL) {
340 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000342 }
343 v = PyString_FromString(p+1);
344 if (v == NULL) {
345 PyErr_Clear();
346 Py_DECREF(k);
347 continue;
348 }
349 if (PyDict_GetItem(d, k) == NULL) {
350 if (PyDict_SetItem(d, k, v) != 0)
351 PyErr_Clear();
352 }
353 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000354 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000355 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000356#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000357 {
358 APIRET rc;
359 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
360
361 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000362 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000363 PyObject *v = PyString_FromString(buffer);
364 PyDict_SetItemString(d, "BEGINLIBPATH", v);
365 Py_DECREF(v);
366 }
367 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
368 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
369 PyObject *v = PyString_FromString(buffer);
370 PyDict_SetItemString(d, "ENDLIBPATH", v);
371 Py_DECREF(v);
372 }
373 }
374#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000375 return d;
376}
377
378
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379/* Set a POSIX-specific error from errno, and return NULL */
380
Barry Warsawd58d7641998-07-23 16:14:40 +0000381static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000382posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000383{
Barry Warsawca74da41999-02-09 19:31:45 +0000384 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385}
Barry Warsawd58d7641998-07-23 16:14:40 +0000386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000387posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000388{
Barry Warsawca74da41999-02-09 19:31:45 +0000389 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000390}
391
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000392#ifdef Py_WIN_WIDE_FILENAMES
393static PyObject *
394posix_error_with_unicode_filename(Py_UNICODE* name)
395{
396 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
397}
398#endif /* Py_WIN_WIDE_FILENAMES */
399
400
Mark Hammondef8b6542001-05-13 08:04:26 +0000401static PyObject *
402posix_error_with_allocated_filename(char* name)
403{
404 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
405 PyMem_Free(name);
406 return rc;
407}
408
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000409#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000410static PyObject *
411win32_error(char* function, char* filename)
412{
Mark Hammond33a6da92000-08-15 00:46:38 +0000413 /* XXX We should pass the function name along in the future.
414 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000415 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000416 Windows error object, which is non-trivial.
417 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000418 errno = GetLastError();
419 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000420 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000421 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000422 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000423}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000424
425#ifdef Py_WIN_WIDE_FILENAMES
426static PyObject *
427win32_error_unicode(char* function, Py_UNICODE* filename)
428{
429 /* XXX - see win32_error for comments on 'function' */
430 errno = GetLastError();
431 if (filename)
432 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
433 else
434 return PyErr_SetFromWindowsErr(errno);
435}
436
437static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
438{
439 /* XXX Perhaps we should make this API an alias of
440 PyObject_Unicode() instead ?! */
441 if (PyUnicode_CheckExact(obj)) {
442 Py_INCREF(obj);
443 return obj;
444 }
445 if (PyUnicode_Check(obj)) {
446 /* For a Unicode subtype that's not a Unicode object,
447 return a true Unicode object with the same data. */
448 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
449 PyUnicode_GET_SIZE(obj));
450 }
Tim Peters11b23062003-04-23 02:39:17 +0000451 return PyUnicode_FromEncodedObject(obj,
452 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000453 "strict");
454}
455
456#endif /* Py_WIN_WIDE_FILENAMES */
457
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000458#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459
Guido van Rossumd48f2521997-12-05 22:19:34 +0000460#if defined(PYOS_OS2)
461/**********************************************************************
462 * Helper Function to Trim and Format OS/2 Messages
463 **********************************************************************/
464 static void
465os2_formatmsg(char *msgbuf, int msglen, char *reason)
466{
467 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
468
469 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
470 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
471
472 while (lastc > msgbuf && isspace(*lastc))
473 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
474 }
475
476 /* Add Optional Reason Text */
477 if (reason) {
478 strcat(msgbuf, " : ");
479 strcat(msgbuf, reason);
480 }
481}
482
483/**********************************************************************
484 * Decode an OS/2 Operating System Error Code
485 *
486 * A convenience function to lookup an OS/2 error code and return a
487 * text message we can use to raise a Python exception.
488 *
489 * Notes:
490 * The messages for errors returned from the OS/2 kernel reside in
491 * the file OSO001.MSG in the \OS2 directory hierarchy.
492 *
493 **********************************************************************/
494 static char *
495os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
496{
497 APIRET rc;
498 ULONG msglen;
499
500 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
501 Py_BEGIN_ALLOW_THREADS
502 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
503 errorcode, "oso001.msg", &msglen);
504 Py_END_ALLOW_THREADS
505
506 if (rc == NO_ERROR)
507 os2_formatmsg(msgbuf, msglen, reason);
508 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000509 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000510 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000511
512 return msgbuf;
513}
514
515/* Set an OS/2-specific error and return NULL. OS/2 kernel
516 errors are not in a global variable e.g. 'errno' nor are
517 they congruent with posix error numbers. */
518
519static PyObject * os2_error(int code)
520{
521 char text[1024];
522 PyObject *v;
523
524 os2_strerror(text, sizeof(text), code, "");
525
526 v = Py_BuildValue("(is)", code, text);
527 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000528 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000529 Py_DECREF(v);
530 }
531 return NULL; /* Signal to Python that an Exception is Pending */
532}
533
534#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000535
536/* POSIX generic methods */
537
Barry Warsaw53699e91996-12-10 23:23:01 +0000538static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000539posix_fildes(PyObject *fdobj, int (*func)(int))
540{
541 int fd;
542 int res;
543 fd = PyObject_AsFileDescriptor(fdobj);
544 if (fd < 0)
545 return NULL;
546 Py_BEGIN_ALLOW_THREADS
547 res = (*func)(fd);
548 Py_END_ALLOW_THREADS
549 if (res < 0)
550 return posix_error();
551 Py_INCREF(Py_None);
552 return Py_None;
553}
Guido van Rossum21142a01999-01-08 21:05:37 +0000554
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000555#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000556static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000557unicode_file_names(void)
558{
559 static int canusewide = -1;
560 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000561 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000562 the Windows NT family. */
563 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
564 }
565 return canusewide;
566}
567#endif
Tim Peters11b23062003-04-23 02:39:17 +0000568
Guido van Rossum21142a01999-01-08 21:05:37 +0000569static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000570posix_1str(PyObject *args, char *format, int (*func)(const char*),
571 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000572{
Mark Hammondef8b6542001-05-13 08:04:26 +0000573 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000574 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000575#ifdef Py_WIN_WIDE_FILENAMES
576 if (unicode_file_names()) {
577 PyUnicodeObject *po;
578 if (PyArg_ParseTuple(args, wformat, &po)) {
579 Py_BEGIN_ALLOW_THREADS
580 /* PyUnicode_AS_UNICODE OK without thread
581 lock as it is a simple dereference. */
582 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
583 Py_END_ALLOW_THREADS
584 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000585 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000586 Py_INCREF(Py_None);
587 return Py_None;
588 }
589 /* Drop the argument parsing error as narrow
590 strings are also valid. */
591 PyErr_Clear();
592 }
593#else
594 /* Platforms that don't support Unicode filenames
595 shouldn't be passing these extra params */
596 assert(wformat==NULL && wfunc == NULL);
597#endif
598
Tim Peters5aa91602002-01-30 05:46:57 +0000599 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000600 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000601 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000602 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000603 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000604 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000605 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000606 return posix_error_with_allocated_filename(path1);
607 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000608 Py_INCREF(Py_None);
609 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000610}
611
Barry Warsaw53699e91996-12-10 23:23:01 +0000612static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000613posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000614 char *format,
615 int (*func)(const char *, const char *),
616 char *wformat,
617 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000618{
Mark Hammondef8b6542001-05-13 08:04:26 +0000619 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000620 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000621#ifdef Py_WIN_WIDE_FILENAMES
622 if (unicode_file_names()) {
623 PyObject *po1;
624 PyObject *po2;
625 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
626 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
627 PyObject *wpath1;
628 PyObject *wpath2;
629 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
630 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
631 if (!wpath1 || !wpath2) {
632 Py_XDECREF(wpath1);
633 Py_XDECREF(wpath2);
634 return NULL;
635 }
636 Py_BEGIN_ALLOW_THREADS
637 /* PyUnicode_AS_UNICODE OK without thread
638 lock as it is a simple dereference. */
639 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
640 PyUnicode_AS_UNICODE(wpath2));
641 Py_END_ALLOW_THREADS
642 Py_XDECREF(wpath1);
643 Py_XDECREF(wpath2);
644 if (res != 0)
645 return posix_error();
646 Py_INCREF(Py_None);
647 return Py_None;
648 }
649 /* Else flow through as neither is Unicode. */
650 }
651 /* Drop the argument parsing error as narrow
652 strings are also valid. */
653 PyErr_Clear();
654 }
655#else
656 /* Platforms that don't support Unicode filenames
657 shouldn't be passing these extra params */
658 assert(wformat==NULL && wfunc == NULL);
659#endif
660
Mark Hammondef8b6542001-05-13 08:04:26 +0000661 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000662 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000663 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000664 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000665 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000666 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000667 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000668 PyMem_Free(path1);
669 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000670 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000671 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000672 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000673 Py_INCREF(Py_None);
674 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000675}
676
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000677PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000678"stat_result: Result from stat or lstat.\n\n\
679This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000680 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000681or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
682\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000683Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000684they are available as attributes only.\n\
685\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000686See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000687
688static PyStructSequence_Field stat_result_fields[] = {
689 {"st_mode", "protection bits"},
690 {"st_ino", "inode"},
691 {"st_dev", "device"},
692 {"st_nlink", "number of hard links"},
693 {"st_uid", "user ID of owner"},
694 {"st_gid", "group ID of owner"},
695 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000696 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
697 {NULL, "integer time of last access"},
698 {NULL, "integer time of last modification"},
699 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000700 {"st_atime", "time of last access"},
701 {"st_mtime", "time of last modification"},
702 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000703#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000704 {"st_blksize", "blocksize for filesystem I/O"},
705#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000706#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000707 {"st_blocks", "number of blocks allocated"},
708#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000709#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000710 {"st_rdev", "device type (if inode device)"},
711#endif
712 {0}
713};
714
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000715#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000716#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000717#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000718#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000719#endif
720
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000721#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000722#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
723#else
724#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
725#endif
726
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000727#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000728#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
729#else
730#define ST_RDEV_IDX ST_BLOCKS_IDX
731#endif
732
733static PyStructSequence_Desc stat_result_desc = {
734 "stat_result", /* name */
735 stat_result__doc__, /* doc */
736 stat_result_fields,
737 10
738};
739
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000740PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000741"statvfs_result: Result from statvfs or fstatvfs.\n\n\
742This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000743 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000744or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000745\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000746See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000747
748static PyStructSequence_Field statvfs_result_fields[] = {
749 {"f_bsize", },
750 {"f_frsize", },
751 {"f_blocks", },
752 {"f_bfree", },
753 {"f_bavail", },
754 {"f_files", },
755 {"f_ffree", },
756 {"f_favail", },
757 {"f_flag", },
758 {"f_namemax",},
759 {0}
760};
761
762static PyStructSequence_Desc statvfs_result_desc = {
763 "statvfs_result", /* name */
764 statvfs_result__doc__, /* doc */
765 statvfs_result_fields,
766 10
767};
768
769static PyTypeObject StatResultType;
770static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000771static newfunc structseq_new;
772
773static PyObject *
774statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
775{
776 PyStructSequence *result;
777 int i;
778
779 result = (PyStructSequence*)structseq_new(type, args, kwds);
780 if (!result)
781 return NULL;
782 /* If we have been initialized from a tuple,
783 st_?time might be set to None. Initialize it
784 from the int slots. */
785 for (i = 7; i <= 9; i++) {
786 if (result->ob_item[i+3] == Py_None) {
787 Py_DECREF(Py_None);
788 Py_INCREF(result->ob_item[i]);
789 result->ob_item[i+3] = result->ob_item[i];
790 }
791 }
792 return (PyObject*)result;
793}
794
795
796
797/* If true, st_?time is float. */
798static int _stat_float_times = 0;
799
800PyDoc_STRVAR(stat_float_times__doc__,
801"stat_float_times([newval]) -> oldval\n\n\
802Determine whether os.[lf]stat represents time stamps as float objects.\n\
803If newval is True, future calls to stat() return floats, if it is False,\n\
804future calls return ints. \n\
805If newval is omitted, return the current setting.\n");
806
807static PyObject*
808stat_float_times(PyObject* self, PyObject *args)
809{
810 int newval = -1;
811 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
812 return NULL;
813 if (newval == -1)
814 /* Return old value */
815 return PyBool_FromLong(_stat_float_times);
816 _stat_float_times = newval;
817 Py_INCREF(Py_None);
818 return Py_None;
819}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000820
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000821static void
822fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
823{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000824 PyObject *fval,*ival;
825#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000826 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000827#else
828 ival = PyInt_FromLong((long)sec);
829#endif
830 if (_stat_float_times) {
831 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
832 } else {
833 fval = ival;
834 Py_INCREF(fval);
835 }
836 PyStructSequence_SET_ITEM(v, index, ival);
837 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000838}
839
Tim Peters5aa91602002-01-30 05:46:57 +0000840/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000841 (used by posix_stat() and posix_fstat()) */
842static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000843_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000844{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000845 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000846 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000847 if (v == NULL)
848 return NULL;
849
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000850 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000851#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000852 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000853 PyLong_FromLongLong((PY_LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000854#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000855 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000856#endif
857#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000858 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000859 PyLong_FromLongLong((PY_LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000860#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000861 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000862#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000863 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
864 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
865 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000866#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000867 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000868 PyLong_FromLongLong((PY_LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000869#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000870 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000871#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000872
873#ifdef HAVE_STAT_TV_NSEC
874 ansec = st.st_atim.tv_nsec;
875 mnsec = st.st_mtim.tv_nsec;
876 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000877#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000878 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000879#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000880 fill_time(v, 7, st.st_atime, ansec);
881 fill_time(v, 8, st.st_mtime, mnsec);
882 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000883
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000884#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000885 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000886 PyInt_FromLong((long)st.st_blksize));
887#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000888#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000889 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000890 PyInt_FromLong((long)st.st_blocks));
891#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000892#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000893 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
894 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000895#endif
896
897 if (PyErr_Occurred()) {
898 Py_DECREF(v);
899 return NULL;
900 }
901
902 return v;
903}
904
Barry Warsaw53699e91996-12-10 23:23:01 +0000905static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000906posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000907 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000908#ifdef __VMS
909 int (*statfunc)(const char *, STRUCT_STAT *, ...),
910#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000911 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000912#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000913 char *wformat,
914 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000915{
Fred Drake699f3522000-06-29 21:12:41 +0000916 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000917 char *path = NULL; /* pass this to stat; do not free() it */
918 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000919 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000920
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000921#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000922 int pathlen;
923 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000924#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000925
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000926
927#ifdef Py_WIN_WIDE_FILENAMES
928 /* If on wide-character-capable OS see if argument
929 is Unicode and if so use wide API. */
930 if (unicode_file_names()) {
931 PyUnicodeObject *po;
932 if (PyArg_ParseTuple(args, wformat, &po)) {
933 Py_UNICODE wpath[MAX_PATH+1];
934 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
935 /* the library call can blow up if the file name is too long! */
936 if (pathlen > MAX_PATH) {
937 errno = ENAMETOOLONG;
938 return posix_error();
939 }
940 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
941 /* Remove trailing slash or backslash, unless it's the current
942 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
943 */
944 if (pathlen > 0 &&
945 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
946 /* It does end with a slash -- exempt the root drive cases. */
947 /* XXX UNC root drives should also be exempted? */
948 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
949 /* leave it alone */;
950 else {
951 /* nuke the trailing backslash */
952 wpath[pathlen-1] = L'\0';
953 }
954 }
955 Py_BEGIN_ALLOW_THREADS
956 /* PyUnicode_AS_UNICODE result OK without
957 thread lock as it is a simple dereference. */
958 res = wstatfunc(wpath, &st);
959 Py_END_ALLOW_THREADS
960 if (res != 0)
961 return posix_error_with_unicode_filename(wpath);
962 return _pystat_fromstructstat(st);
963 }
964 /* Drop the argument parsing error as narrow strings
965 are also valid. */
966 PyErr_Clear();
967 }
968#endif
969
Tim Peters5aa91602002-01-30 05:46:57 +0000970 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000971 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000972 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000973 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000974
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000975#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000976 pathlen = strlen(path);
977 /* the library call can blow up if the file name is too long! */
978 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000979 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000980 errno = ENAMETOOLONG;
981 return posix_error();
982 }
983
Tim Peters500bd032001-12-19 19:05:01 +0000984 /* Remove trailing slash or backslash, unless it's the current
985 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
986 */
987 if (pathlen > 0 &&
988 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
989 /* It does end with a slash -- exempt the root drive cases. */
990 /* XXX UNC root drives should also be exempted? */
991 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
992 /* leave it alone */;
993 else {
994 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000995 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000996 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000997 path = pathcopy;
998 }
999 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001000#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001001
Barry Warsaw53699e91996-12-10 23:23:01 +00001002 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001003 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001004 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001005 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001006 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001007
Tim Peters500bd032001-12-19 19:05:01 +00001008 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001009 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001010}
1011
1012
1013/* POSIX methods */
1014
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001015PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001016"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001017Use the real uid/gid to test for access to a path. Note that most\n\
1018operations will use the effective uid/gid, therefore this routine can\n\
1019be used in a suid/sgid environment to test if the invoking user has the\n\
1020specified access to the path. The mode argument can be F_OK to test\n\
1021existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001022
1023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001024posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001025{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001026 char *path;
1027 int mode;
1028 int res;
1029
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001030 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001031 return NULL;
1032 Py_BEGIN_ALLOW_THREADS
1033 res = access(path, mode);
1034 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001035 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001036}
1037
Guido van Rossumd371ff11999-01-25 16:12:23 +00001038#ifndef F_OK
1039#define F_OK 0
1040#endif
1041#ifndef R_OK
1042#define R_OK 4
1043#endif
1044#ifndef W_OK
1045#define W_OK 2
1046#endif
1047#ifndef X_OK
1048#define X_OK 1
1049#endif
1050
1051#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001052PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001053"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001054Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001055
1056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001057posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001058{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001059 int id;
1060 char *ret;
1061
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001062 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001063 return NULL;
1064
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001065#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001066 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001067 if (id == 0) {
1068 ret = ttyname();
1069 }
1070 else {
1071 ret = NULL;
1072 }
1073#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001074 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001075#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001076 if (ret == NULL)
1077 return(posix_error());
1078 return(PyString_FromString(ret));
1079}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001080#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001081
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001082#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001083PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001084"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001085Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001086
1087static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001088posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001089{
1090 char *ret;
1091 char buffer[L_ctermid];
1092
Greg Wardb48bc172000-03-01 21:51:56 +00001093#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001094 ret = ctermid_r(buffer);
1095#else
1096 ret = ctermid(buffer);
1097#endif
1098 if (ret == NULL)
1099 return(posix_error());
1100 return(PyString_FromString(buffer));
1101}
1102#endif
1103
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001104PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001105"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001106Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001107
Barry Warsaw53699e91996-12-10 23:23:01 +00001108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001109posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001110{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001111#ifdef MS_WINDOWS
1112 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1113#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1114 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001115#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001116 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001117 NULL, NULL);
1118#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001119 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001120#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001121}
1122
Fred Drake4d1e64b2002-04-15 19:40:07 +00001123#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001124PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001125"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001126Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001127opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001128
1129static PyObject *
1130posix_fchdir(PyObject *self, PyObject *fdobj)
1131{
1132 return posix_fildes(fdobj, fchdir);
1133}
1134#endif /* HAVE_FCHDIR */
1135
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001136
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001137PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001138"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001139Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001140
Barry Warsaw53699e91996-12-10 23:23:01 +00001141static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001142posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001143{
Mark Hammondef8b6542001-05-13 08:04:26 +00001144 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001145 int i;
1146 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001147 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001148 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001149 return NULL;
1150 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001151 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001152 Py_END_ALLOW_THREADS
1153 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001154 return posix_error_with_allocated_filename(path);
1155 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001156 Py_INCREF(Py_None);
1157 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001158}
1159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001160
Martin v. Löwis244edc82001-10-04 22:44:26 +00001161#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001162PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001163"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001164Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001165
1166static PyObject *
1167posix_chroot(PyObject *self, PyObject *args)
1168{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001169 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001170}
1171#endif
1172
Guido van Rossum21142a01999-01-08 21:05:37 +00001173#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001174PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001175"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001176force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001177
1178static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001179posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001180{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001181 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001182}
1183#endif /* HAVE_FSYNC */
1184
1185#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001186
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001187#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001188extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1189#endif
1190
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001191PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001192"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001193force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001194 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001195
1196static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001197posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001198{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001199 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001200}
1201#endif /* HAVE_FDATASYNC */
1202
1203
Fredrik Lundh10723342000-07-10 16:38:09 +00001204#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001205PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001206"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001207Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001208
Barry Warsaw53699e91996-12-10 23:23:01 +00001209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001210posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001211{
Mark Hammondef8b6542001-05-13 08:04:26 +00001212 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001213 int uid, gid;
1214 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001215 if (!PyArg_ParseTuple(args, "etii:chown",
1216 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001217 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001218 return NULL;
1219 Py_BEGIN_ALLOW_THREADS
1220 res = chown(path, (uid_t) uid, (gid_t) gid);
1221 Py_END_ALLOW_THREADS
1222 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001223 return posix_error_with_allocated_filename(path);
1224 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001225 Py_INCREF(Py_None);
1226 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001227}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001228#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001229
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001230#ifdef HAVE_LCHOWN
1231PyDoc_STRVAR(posix_lchown__doc__,
1232"lchown(path, uid, gid)\n\n\
1233Change the owner and group id of path to the numeric uid and gid.\n\
1234This function will not follow symbolic links.");
1235
1236static PyObject *
1237posix_lchown(PyObject *self, PyObject *args)
1238{
1239 char *path = NULL;
1240 int uid, gid;
1241 int res;
1242 if (!PyArg_ParseTuple(args, "etii:lchown",
1243 Py_FileSystemDefaultEncoding, &path,
1244 &uid, &gid))
1245 return NULL;
1246 Py_BEGIN_ALLOW_THREADS
1247 res = lchown(path, (uid_t) uid, (gid_t) gid);
1248 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001249 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001250 return posix_error_with_allocated_filename(path);
1251 PyMem_Free(path);
1252 Py_INCREF(Py_None);
1253 return Py_None;
1254}
1255#endif /* HAVE_LCHOWN */
1256
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001257
Guido van Rossum36bc6801995-06-14 22:54:23 +00001258#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001259PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001260"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001261Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001262
Barry Warsaw53699e91996-12-10 23:23:01 +00001263static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001264posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001265{
1266 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001267 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001268
Barry Warsaw53699e91996-12-10 23:23:01 +00001269 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001270#if defined(PYOS_OS2) && defined(PYCC_GCC)
1271 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001272#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001273 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001274#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001275 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001276 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001277 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001278 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001279}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001280
Walter Dörwald3b918c32002-11-21 20:18:46 +00001281#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001282PyDoc_STRVAR(posix_getcwdu__doc__,
1283"getcwdu() -> path\n\n\
1284Return a unicode string representing the current working directory.");
1285
1286static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001287posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001288{
1289 char buf[1026];
1290 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001291
1292#ifdef Py_WIN_WIDE_FILENAMES
1293 if (unicode_file_names()) {
1294 wchar_t *wres;
1295 wchar_t wbuf[1026];
1296 Py_BEGIN_ALLOW_THREADS
1297 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1298 Py_END_ALLOW_THREADS
1299 if (wres == NULL)
1300 return posix_error();
1301 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1302 }
1303#endif
1304
1305 Py_BEGIN_ALLOW_THREADS
1306#if defined(PYOS_OS2) && defined(PYCC_GCC)
1307 res = _getcwd2(buf, sizeof buf);
1308#else
1309 res = getcwd(buf, sizeof buf);
1310#endif
1311 Py_END_ALLOW_THREADS
1312 if (res == NULL)
1313 return posix_error();
1314 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1315}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001316#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001317#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001319
Guido van Rossumb6775db1994-08-01 11:34:53 +00001320#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001321PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001322"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001323Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001324
Barry Warsaw53699e91996-12-10 23:23:01 +00001325static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001326posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001327{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001328 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001329}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001330#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001332
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001333PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001334"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335Return a list containing the names of the entries in the directory.\n\
1336\n\
1337 path: path of directory to list\n\
1338\n\
1339The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001340entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001341
Barry Warsaw53699e91996-12-10 23:23:01 +00001342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001343posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001344{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001345 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001346 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001347#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001348
Barry Warsaw53699e91996-12-10 23:23:01 +00001349 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001350 HANDLE hFindFile;
1351 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001352 /* MAX_PATH characters could mean a bigger encoded string */
1353 char namebuf[MAX_PATH*2+5];
1354 char *bufptr = namebuf;
1355 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001356
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001357#ifdef Py_WIN_WIDE_FILENAMES
1358 /* If on wide-character-capable OS see if argument
1359 is Unicode and if so use wide API. */
1360 if (unicode_file_names()) {
1361 PyUnicodeObject *po;
1362 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1363 WIN32_FIND_DATAW wFileData;
1364 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1365 Py_UNICODE wch;
1366 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1367 wnamebuf[MAX_PATH] = L'\0';
1368 len = wcslen(wnamebuf);
1369 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1370 if (wch != L'/' && wch != L'\\' && wch != L':')
1371 wnamebuf[len++] = L'/';
1372 wcscpy(wnamebuf + len, L"*.*");
1373 if ((d = PyList_New(0)) == NULL)
1374 return NULL;
1375 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1376 if (hFindFile == INVALID_HANDLE_VALUE) {
1377 errno = GetLastError();
1378 if (errno == ERROR_FILE_NOT_FOUND) {
1379 return d;
1380 }
1381 Py_DECREF(d);
1382 return win32_error_unicode("FindFirstFileW", wnamebuf);
1383 }
1384 do {
1385 if (wFileData.cFileName[0] == L'.' &&
1386 (wFileData.cFileName[1] == L'\0' ||
1387 wFileData.cFileName[1] == L'.' &&
1388 wFileData.cFileName[2] == L'\0'))
1389 continue;
1390 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1391 if (v == NULL) {
1392 Py_DECREF(d);
1393 d = NULL;
1394 break;
1395 }
1396 if (PyList_Append(d, v) != 0) {
1397 Py_DECREF(v);
1398 Py_DECREF(d);
1399 d = NULL;
1400 break;
1401 }
1402 Py_DECREF(v);
1403 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1404
1405 if (FindClose(hFindFile) == FALSE) {
1406 Py_DECREF(d);
1407 return win32_error_unicode("FindClose", wnamebuf);
1408 }
1409 return d;
1410 }
1411 /* Drop the argument parsing error as narrow strings
1412 are also valid. */
1413 PyErr_Clear();
1414 }
1415#endif
1416
Tim Peters5aa91602002-01-30 05:46:57 +00001417 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001418 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001419 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001420 if (len > 0) {
1421 char ch = namebuf[len-1];
1422 if (ch != SEP && ch != ALTSEP && ch != ':')
1423 namebuf[len++] = '/';
1424 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001425 strcpy(namebuf + len, "*.*");
1426
Barry Warsaw53699e91996-12-10 23:23:01 +00001427 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001428 return NULL;
1429
1430 hFindFile = FindFirstFile(namebuf, &FileData);
1431 if (hFindFile == INVALID_HANDLE_VALUE) {
1432 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001433 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001434 return d;
1435 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001436 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001437 }
1438 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001439 if (FileData.cFileName[0] == '.' &&
1440 (FileData.cFileName[1] == '\0' ||
1441 FileData.cFileName[1] == '.' &&
1442 FileData.cFileName[2] == '\0'))
1443 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001444 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001445 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001446 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001447 d = NULL;
1448 break;
1449 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001450 if (PyList_Append(d, v) != 0) {
1451 Py_DECREF(v);
1452 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001453 d = NULL;
1454 break;
1455 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001456 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001457 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1458
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001459 if (FindClose(hFindFile) == FALSE) {
1460 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001461 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001462 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001463
1464 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001465
Tim Peters0bb44a42000-09-15 07:44:49 +00001466#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001467
1468#ifndef MAX_PATH
1469#define MAX_PATH CCHMAXPATH
1470#endif
1471 char *name, *pt;
1472 int len;
1473 PyObject *d, *v;
1474 char namebuf[MAX_PATH+5];
1475 HDIR hdir = 1;
1476 ULONG srchcnt = 1;
1477 FILEFINDBUF3 ep;
1478 APIRET rc;
1479
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001480 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001481 return NULL;
1482 if (len >= MAX_PATH) {
1483 PyErr_SetString(PyExc_ValueError, "path too long");
1484 return NULL;
1485 }
1486 strcpy(namebuf, name);
1487 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001488 if (*pt == ALTSEP)
1489 *pt = SEP;
1490 if (namebuf[len-1] != SEP)
1491 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001492 strcpy(namebuf + len, "*.*");
1493
1494 if ((d = PyList_New(0)) == NULL)
1495 return NULL;
1496
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001497 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1498 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001499 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001500 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1501 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1502 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001503
1504 if (rc != NO_ERROR) {
1505 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001506 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001507 }
1508
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001509 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001510 do {
1511 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001512 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001513 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001514
1515 strcpy(namebuf, ep.achName);
1516
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001517 /* Leave Case of Name Alone -- In Native Form */
1518 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001519
1520 v = PyString_FromString(namebuf);
1521 if (v == NULL) {
1522 Py_DECREF(d);
1523 d = NULL;
1524 break;
1525 }
1526 if (PyList_Append(d, v) != 0) {
1527 Py_DECREF(v);
1528 Py_DECREF(d);
1529 d = NULL;
1530 break;
1531 }
1532 Py_DECREF(v);
1533 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1534 }
1535
1536 return d;
1537#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001538
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001539 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001540 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001541 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001542 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001543 int arg_is_unicode = 1;
1544
1545 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1546 arg_is_unicode = 0;
1547 PyErr_Clear();
1548 }
1549 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001550 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001551 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001552 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001553 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001554 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001555 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001556 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001557 return NULL;
1558 }
1559 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001560 if (ep->d_name[0] == '.' &&
1561 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001562 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001563 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001564 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001565 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001566 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001567 d = NULL;
1568 break;
1569 }
Just van Rossum46c97842003-02-25 21:42:15 +00001570#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001571 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001572 PyObject *w;
1573
1574 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001575 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001576 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001577 if (w != NULL) {
1578 Py_DECREF(v);
1579 v = w;
1580 }
1581 else {
1582 /* fall back to the original byte string, as
1583 discussed in patch #683592 */
1584 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001585 }
Just van Rossum46c97842003-02-25 21:42:15 +00001586 }
1587#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001588 if (PyList_Append(d, v) != 0) {
1589 Py_DECREF(v);
1590 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001591 d = NULL;
1592 break;
1593 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001594 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001595 }
1596 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001597 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001598
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001599 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001600
Tim Peters0bb44a42000-09-15 07:44:49 +00001601#endif /* which OS */
1602} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001603
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001604#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001605/* A helper function for abspath on win32 */
1606static PyObject *
1607posix__getfullpathname(PyObject *self, PyObject *args)
1608{
1609 /* assume encoded strings wont more than double no of chars */
1610 char inbuf[MAX_PATH*2];
1611 char *inbufp = inbuf;
1612 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1613 char outbuf[MAX_PATH*2];
1614 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001615#ifdef Py_WIN_WIDE_FILENAMES
1616 if (unicode_file_names()) {
1617 PyUnicodeObject *po;
1618 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1619 Py_UNICODE woutbuf[MAX_PATH*2];
1620 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001621 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001622 sizeof(woutbuf)/sizeof(woutbuf[0]),
1623 woutbuf, &wtemp))
1624 return win32_error("GetFullPathName", "");
1625 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1626 }
1627 /* Drop the argument parsing error as narrow strings
1628 are also valid. */
1629 PyErr_Clear();
1630 }
1631#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001632 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1633 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001634 &insize))
1635 return NULL;
1636 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1637 outbuf, &temp))
1638 return win32_error("GetFullPathName", inbuf);
1639 return PyString_FromString(outbuf);
1640} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001641#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001642
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001643PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001644"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001645Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001646
Barry Warsaw53699e91996-12-10 23:23:01 +00001647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001648posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001649{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001650 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001651 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001652 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001653
1654#ifdef Py_WIN_WIDE_FILENAMES
1655 if (unicode_file_names()) {
1656 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001657 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001658 Py_BEGIN_ALLOW_THREADS
1659 /* PyUnicode_AS_UNICODE OK without thread lock as
1660 it is a simple dereference. */
1661 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1662 Py_END_ALLOW_THREADS
1663 if (res < 0)
1664 return posix_error();
1665 Py_INCREF(Py_None);
1666 return Py_None;
1667 }
1668 /* Drop the argument parsing error as narrow strings
1669 are also valid. */
1670 PyErr_Clear();
1671 }
1672#endif
1673
Tim Peters5aa91602002-01-30 05:46:57 +00001674 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001675 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001676 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001677 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001678#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001679 res = mkdir(path);
1680#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001681 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001682#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001683 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001684 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001685 return posix_error_with_allocated_filename(path);
1686 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001687 Py_INCREF(Py_None);
1688 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001689}
1690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001691
Guido van Rossumb6775db1994-08-01 11:34:53 +00001692#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001693#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1694#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1695#include <sys/resource.h>
1696#endif
1697#endif
1698
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001699PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001700"nice(inc) -> new_priority\n\n\
1701Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001702
Barry Warsaw53699e91996-12-10 23:23:01 +00001703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001704posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001705{
1706 int increment, value;
1707
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001708 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001709 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001710
1711 /* There are two flavours of 'nice': one that returns the new
1712 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001713 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1714 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001715
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001716 If we are of the nice family that returns the new priority, we
1717 need to clear errno before the call, and check if errno is filled
1718 before calling posix_error() on a returnvalue of -1, because the
1719 -1 may be the actual new priority! */
1720
1721 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001722 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001723#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001724 if (value == 0)
1725 value = getpriority(PRIO_PROCESS, 0);
1726#endif
1727 if (value == -1 && errno != 0)
1728 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001729 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001730 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001731}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001732#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001733
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001734
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001735PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001736"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001737Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001738
Barry Warsaw53699e91996-12-10 23:23:01 +00001739static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001740posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001741{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001742#ifdef MS_WINDOWS
1743 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1744#else
1745 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1746#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001747}
1748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001749
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001750PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001751"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001752Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001753
Barry Warsaw53699e91996-12-10 23:23:01 +00001754static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001755posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001756{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001757#ifdef MS_WINDOWS
1758 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1759#else
1760 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1761#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001762}
1763
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001764
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001765PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001766"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001767Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001768
Barry Warsaw53699e91996-12-10 23:23:01 +00001769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001770posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001771{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001772#ifdef MS_WINDOWS
1773 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1774#else
1775 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1776#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001777}
1778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001779
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001780#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001781PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001782"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001783Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001784
Barry Warsaw53699e91996-12-10 23:23:01 +00001785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001786posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001787{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001788 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001789 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001790 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001791 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001792 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001793 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001794 Py_END_ALLOW_THREADS
1795 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001796}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001797#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001798
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001799
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001800PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001801"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001802Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001803
Barry Warsaw53699e91996-12-10 23:23:01 +00001804static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001805posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001806{
1807 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001808 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001809 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001810 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001811 if (i < 0)
1812 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001813 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001814}
1815
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001818"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001820
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001821PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001822"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001823Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001824
Barry Warsaw53699e91996-12-10 23:23:01 +00001825static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001826posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001827{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001828#ifdef MS_WINDOWS
1829 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1830#else
1831 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1832#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001833}
1834
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001835
Guido van Rossumb6775db1994-08-01 11:34:53 +00001836#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001837PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001838"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001840
Barry Warsaw53699e91996-12-10 23:23:01 +00001841static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001842posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001843{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001844 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001845 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001846
Barry Warsaw53699e91996-12-10 23:23:01 +00001847 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001848 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001849 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001850 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001851 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001852 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001853 u.sysname,
1854 u.nodename,
1855 u.release,
1856 u.version,
1857 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001858}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001859#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001860
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001861static int
1862extract_time(PyObject *t, long* sec, long* usec)
1863{
1864 long intval;
1865 if (PyFloat_Check(t)) {
1866 double tval = PyFloat_AsDouble(t);
1867 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1868 if (!intobj)
1869 return -1;
1870 intval = PyInt_AsLong(intobj);
1871 Py_DECREF(intobj);
1872 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001873 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001874 if (*usec < 0)
1875 /* If rounding gave us a negative number,
1876 truncate. */
1877 *usec = 0;
1878 return 0;
1879 }
1880 intval = PyInt_AsLong(t);
1881 if (intval == -1 && PyErr_Occurred())
1882 return -1;
1883 *sec = intval;
1884 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001885 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001886}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001887
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001888PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001889"utime(path, (atime, utime))\n\
1890utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001891Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001892second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001893
Barry Warsaw53699e91996-12-10 23:23:01 +00001894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001895posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001896{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001897 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001898 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001899 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001900 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001901
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001902#if defined(HAVE_UTIMES)
1903 struct timeval buf[2];
1904#define ATIME buf[0].tv_sec
1905#define MTIME buf[1].tv_sec
1906#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001907/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001908 struct utimbuf buf;
1909#define ATIME buf.actime
1910#define MTIME buf.modtime
1911#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001912#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001913 time_t buf[2];
1914#define ATIME buf[0]
1915#define MTIME buf[1]
1916#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001917#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001918
Barry Warsaw3cef8562000-05-01 16:17:24 +00001919 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001920 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001921 if (arg == Py_None) {
1922 /* optional time values not given */
1923 Py_BEGIN_ALLOW_THREADS
1924 res = utime(path, NULL);
1925 Py_END_ALLOW_THREADS
1926 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001927 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001928 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001929 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001930 return NULL;
1931 }
1932 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001933 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1934 &atime, &ausec) == -1)
1935 return NULL;
1936 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1937 &mtime, &musec) == -1)
1938 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001939 ATIME = atime;
1940 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001941#ifdef HAVE_UTIMES
1942 buf[0].tv_usec = ausec;
1943 buf[1].tv_usec = musec;
1944 Py_BEGIN_ALLOW_THREADS
1945 res = utimes(path, buf);
1946 Py_END_ALLOW_THREADS
1947#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00001948 Py_BEGIN_ALLOW_THREADS
1949 res = utime(path, UTIME_ARG);
1950 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001951#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00001952 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001953 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001954 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001955 Py_INCREF(Py_None);
1956 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001957#undef UTIME_ARG
1958#undef ATIME
1959#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001960}
1961
Guido van Rossum85e3b011991-06-03 12:42:10 +00001962
Guido van Rossum3b066191991-06-04 19:40:25 +00001963/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001964
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001965PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001966"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001967Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001968
Barry Warsaw53699e91996-12-10 23:23:01 +00001969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001970posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001971{
1972 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001973 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001974 return NULL;
1975 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001976 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001977}
1978
Martin v. Löwis114619e2002-10-07 06:44:21 +00001979#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
1980static void
1981free_string_array(char **array, int count)
1982{
1983 int i;
1984 for (i = 0; i < count; i++)
1985 PyMem_Free(array[i]);
1986 PyMem_DEL(array);
1987}
1988#endif
1989
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001990
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001991#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001992PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001993"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001994Execute an executable path with arguments, replacing current process.\n\
1995\n\
1996 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001997 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001998
Barry Warsaw53699e91996-12-10 23:23:01 +00001999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002000posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002001{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002002 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002003 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002004 char **argvlist;
2005 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002006 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002007
Guido van Rossum89b33251993-10-22 14:26:06 +00002008 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002009 argv is a list or tuple of strings. */
2010
Martin v. Löwis114619e2002-10-07 06:44:21 +00002011 if (!PyArg_ParseTuple(args, "etO:execv",
2012 Py_FileSystemDefaultEncoding,
2013 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002014 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002015 if (PyList_Check(argv)) {
2016 argc = PyList_Size(argv);
2017 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002018 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002019 else if (PyTuple_Check(argv)) {
2020 argc = PyTuple_Size(argv);
2021 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002022 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002023 else {
Fred Drake661ea262000-10-24 19:57:45 +00002024 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002025 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002026 return NULL;
2027 }
2028
2029 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002030 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002031 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002032 return NULL;
2033 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002034
Barry Warsaw53699e91996-12-10 23:23:01 +00002035 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002036 if (argvlist == NULL) {
2037 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002038 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002039 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002040 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002041 if (!PyArg_Parse((*getitem)(argv, i), "et",
2042 Py_FileSystemDefaultEncoding,
2043 &argvlist[i])) {
2044 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002045 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002046 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002047 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002048 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002049
Guido van Rossum85e3b011991-06-03 12:42:10 +00002050 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002051 }
2052 argvlist[argc] = NULL;
2053
Guido van Rossumb6775db1994-08-01 11:34:53 +00002054#ifdef BAD_EXEC_PROTOTYPES
2055 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002056#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002057 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002058#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002059
Guido van Rossum85e3b011991-06-03 12:42:10 +00002060 /* If we get here it's definitely an error */
2061
Martin v. Löwis114619e2002-10-07 06:44:21 +00002062 free_string_array(argvlist, argc);
2063 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002064 return posix_error();
2065}
2066
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002068PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002069"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002070Execute a path with arguments and environment, replacing current process.\n\
2071\n\
2072 path: path of executable file\n\
2073 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002074 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002075
Barry Warsaw53699e91996-12-10 23:23:01 +00002076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002077posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002078{
2079 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002080 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002081 char **argvlist;
2082 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002083 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002084 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002085 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002086 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002087
2088 /* execve has three arguments: (path, argv, env), where
2089 argv is a list or tuple of strings and env is a dictionary
2090 like posix.environ. */
2091
Martin v. Löwis114619e2002-10-07 06:44:21 +00002092 if (!PyArg_ParseTuple(args, "etOO:execve",
2093 Py_FileSystemDefaultEncoding,
2094 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002095 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002096 if (PyList_Check(argv)) {
2097 argc = PyList_Size(argv);
2098 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002099 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002100 else if (PyTuple_Check(argv)) {
2101 argc = PyTuple_Size(argv);
2102 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002103 }
2104 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002105 PyErr_SetString(PyExc_TypeError,
2106 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002107 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002108 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002109 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002110 PyErr_SetString(PyExc_TypeError,
2111 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002112 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002113 }
2114
Guido van Rossum50422b42000-04-26 20:34:28 +00002115 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002116 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002117 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002118 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002119 }
2120
Barry Warsaw53699e91996-12-10 23:23:01 +00002121 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002122 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002123 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002124 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002125 }
2126 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002127 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002128 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002129 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002130 &argvlist[i]))
2131 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002132 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002133 goto fail_1;
2134 }
2135 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002136 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002137 argvlist[argc] = NULL;
2138
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002139 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002140 if (i < 0)
2141 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002142 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002143 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002144 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002145 goto fail_1;
2146 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002147 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002148 keys = PyMapping_Keys(env);
2149 vals = PyMapping_Values(env);
2150 if (!keys || !vals)
2151 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002152 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2153 PyErr_SetString(PyExc_TypeError,
2154 "execve(): env.keys() or env.values() is not a list");
2155 goto fail_2;
2156 }
Tim Peters5aa91602002-01-30 05:46:57 +00002157
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002158 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002159 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002160 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002161
2162 key = PyList_GetItem(keys, pos);
2163 val = PyList_GetItem(vals, pos);
2164 if (!key || !val)
2165 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002166
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002167 if (!PyArg_Parse(
2168 key,
2169 "s;execve() arg 3 contains a non-string key",
2170 &k) ||
2171 !PyArg_Parse(
2172 val,
2173 "s;execve() arg 3 contains a non-string value",
2174 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002175 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002176 goto fail_2;
2177 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002178
2179#if defined(PYOS_OS2)
2180 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2181 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2182#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002183 len = PyString_Size(key) + PyString_Size(val) + 2;
2184 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002185 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002186 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002187 goto fail_2;
2188 }
Tim Petersc8996f52001-12-03 20:41:00 +00002189 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002190 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002191#if defined(PYOS_OS2)
2192 }
2193#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002194 }
2195 envlist[envc] = 0;
2196
Guido van Rossumb6775db1994-08-01 11:34:53 +00002197
2198#ifdef BAD_EXEC_PROTOTYPES
2199 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002200#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002201 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002202#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002203
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002204 /* If we get here it's definitely an error */
2205
2206 (void) posix_error();
2207
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002208 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002209 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002210 PyMem_DEL(envlist[envc]);
2211 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002212 fail_1:
2213 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002214 Py_XDECREF(vals);
2215 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002216 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002217 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002218 return NULL;
2219}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002220#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002221
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002222
Guido van Rossuma1065681999-01-25 23:20:23 +00002223#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002224PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002225"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002226Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002227\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002228 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002229 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002230 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002231
2232static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002233posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002234{
2235 char *path;
2236 PyObject *argv;
2237 char **argvlist;
2238 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002239 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002240 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002241
2242 /* spawnv has three arguments: (mode, path, argv), where
2243 argv is a list or tuple of strings. */
2244
Martin v. Löwis114619e2002-10-07 06:44:21 +00002245 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2246 Py_FileSystemDefaultEncoding,
2247 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002248 return NULL;
2249 if (PyList_Check(argv)) {
2250 argc = PyList_Size(argv);
2251 getitem = PyList_GetItem;
2252 }
2253 else if (PyTuple_Check(argv)) {
2254 argc = PyTuple_Size(argv);
2255 getitem = PyTuple_GetItem;
2256 }
2257 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002258 PyErr_SetString(PyExc_TypeError,
2259 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002260 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002261 return NULL;
2262 }
2263
2264 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002265 if (argvlist == NULL) {
2266 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002267 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002268 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002269 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002270 if (!PyArg_Parse((*getitem)(argv, i), "et",
2271 Py_FileSystemDefaultEncoding,
2272 &argvlist[i])) {
2273 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002274 PyErr_SetString(
2275 PyExc_TypeError,
2276 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002277 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002278 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002279 }
2280 }
2281 argvlist[argc] = NULL;
2282
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002283#if defined(PYOS_OS2) && defined(PYCC_GCC)
2284 Py_BEGIN_ALLOW_THREADS
2285 spawnval = spawnv(mode, path, argvlist);
2286 Py_END_ALLOW_THREADS
2287#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002288 if (mode == _OLD_P_OVERLAY)
2289 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002290
Tim Peters25059d32001-12-07 20:35:43 +00002291 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002292 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002293 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002294#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002295
Martin v. Löwis114619e2002-10-07 06:44:21 +00002296 free_string_array(argvlist, argc);
2297 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002298
Fred Drake699f3522000-06-29 21:12:41 +00002299 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002300 return posix_error();
2301 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002302#if SIZEOF_LONG == SIZEOF_VOID_P
2303 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002304#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002305 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002306#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002307}
2308
2309
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002310PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002311"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002312Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002313\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002314 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002315 path: path of executable file\n\
2316 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002317 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002318
2319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002320posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002321{
2322 char *path;
2323 PyObject *argv, *env;
2324 char **argvlist;
2325 char **envlist;
2326 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2327 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002328 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002329 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002330 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002331
2332 /* spawnve has four arguments: (mode, path, argv, env), where
2333 argv is a list or tuple of strings and env is a dictionary
2334 like posix.environ. */
2335
Martin v. Löwis114619e2002-10-07 06:44:21 +00002336 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2337 Py_FileSystemDefaultEncoding,
2338 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002339 return NULL;
2340 if (PyList_Check(argv)) {
2341 argc = PyList_Size(argv);
2342 getitem = PyList_GetItem;
2343 }
2344 else if (PyTuple_Check(argv)) {
2345 argc = PyTuple_Size(argv);
2346 getitem = PyTuple_GetItem;
2347 }
2348 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002349 PyErr_SetString(PyExc_TypeError,
2350 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002351 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002352 }
2353 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002354 PyErr_SetString(PyExc_TypeError,
2355 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002356 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002357 }
2358
2359 argvlist = PyMem_NEW(char *, argc+1);
2360 if (argvlist == NULL) {
2361 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002362 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002363 }
2364 for (i = 0; i < argc; i++) {
2365 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002366 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002367 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002368 &argvlist[i]))
2369 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002370 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002371 goto fail_1;
2372 }
2373 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002374 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002375 argvlist[argc] = NULL;
2376
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002377 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002378 if (i < 0)
2379 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002380 envlist = PyMem_NEW(char *, i + 1);
2381 if (envlist == NULL) {
2382 PyErr_NoMemory();
2383 goto fail_1;
2384 }
2385 envc = 0;
2386 keys = PyMapping_Keys(env);
2387 vals = PyMapping_Values(env);
2388 if (!keys || !vals)
2389 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002390 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2391 PyErr_SetString(PyExc_TypeError,
2392 "spawnve(): env.keys() or env.values() is not a list");
2393 goto fail_2;
2394 }
Tim Peters5aa91602002-01-30 05:46:57 +00002395
Guido van Rossuma1065681999-01-25 23:20:23 +00002396 for (pos = 0; pos < i; pos++) {
2397 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002398 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002399
2400 key = PyList_GetItem(keys, pos);
2401 val = PyList_GetItem(vals, pos);
2402 if (!key || !val)
2403 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002404
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002405 if (!PyArg_Parse(
2406 key,
2407 "s;spawnve() arg 3 contains a non-string key",
2408 &k) ||
2409 !PyArg_Parse(
2410 val,
2411 "s;spawnve() arg 3 contains a non-string value",
2412 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002413 {
2414 goto fail_2;
2415 }
Tim Petersc8996f52001-12-03 20:41:00 +00002416 len = PyString_Size(key) + PyString_Size(val) + 2;
2417 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002418 if (p == NULL) {
2419 PyErr_NoMemory();
2420 goto fail_2;
2421 }
Tim Petersc8996f52001-12-03 20:41:00 +00002422 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002423 envlist[envc++] = p;
2424 }
2425 envlist[envc] = 0;
2426
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002427#if defined(PYOS_OS2) && defined(PYCC_GCC)
2428 Py_BEGIN_ALLOW_THREADS
2429 spawnval = spawnve(mode, path, argvlist, envlist);
2430 Py_END_ALLOW_THREADS
2431#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002432 if (mode == _OLD_P_OVERLAY)
2433 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002434
2435 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002436 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002437 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002438#endif
Tim Peters25059d32001-12-07 20:35:43 +00002439
Fred Drake699f3522000-06-29 21:12:41 +00002440 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002441 (void) posix_error();
2442 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002443#if SIZEOF_LONG == SIZEOF_VOID_P
2444 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002445#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002446 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002447#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002448
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002449 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002450 while (--envc >= 0)
2451 PyMem_DEL(envlist[envc]);
2452 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002453 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002454 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002455 Py_XDECREF(vals);
2456 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002457 fail_0:
2458 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002459 return res;
2460}
2461#endif /* HAVE_SPAWNV */
2462
2463
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002464#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002465PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002466"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002467Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2468\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002469Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002470
2471static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002472posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002473{
Neal Norwitze241ce82003-02-17 18:17:05 +00002474 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002475 if (pid == -1)
2476 return posix_error();
2477 PyOS_AfterFork();
2478 return PyInt_FromLong((long)pid);
2479}
2480#endif
2481
2482
Guido van Rossumad0ee831995-03-01 10:34:45 +00002483#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002484PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002485"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002486Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002487Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002488
Barry Warsaw53699e91996-12-10 23:23:01 +00002489static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002490posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002491{
Neal Norwitze241ce82003-02-17 18:17:05 +00002492 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002493 if (pid == -1)
2494 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002495 if (pid == 0)
2496 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002497 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002498}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002499#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002500
Neal Norwitzb59798b2003-03-21 01:43:31 +00002501/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00002502/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2503#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00002504#define DEV_PTY_FILE "/dev/ptc"
2505#define HAVE_DEV_PTMX
2506#else
2507#define DEV_PTY_FILE "/dev/ptmx"
2508#endif
2509
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002510#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002511#ifdef HAVE_PTY_H
2512#include <pty.h>
2513#else
2514#ifdef HAVE_LIBUTIL_H
2515#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002516#endif /* HAVE_LIBUTIL_H */
2517#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002518#ifdef HAVE_STROPTS_H
2519#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002520#endif
2521#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002522
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002523#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002524PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002525"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002526Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002527
2528static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002529posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002530{
2531 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002532#ifndef HAVE_OPENPTY
2533 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002534#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002535#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002536 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002537#ifdef sun
2538 extern char *ptsname();
2539#endif
2540#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002541
Thomas Wouters70c21a12000-07-14 14:28:33 +00002542#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002543 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2544 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002545#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00002546 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2547 if (slave_name == NULL)
2548 return posix_error();
2549
2550 slave_fd = open(slave_name, O_RDWR);
2551 if (slave_fd < 0)
2552 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002553#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00002554 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002555 if (master_fd < 0)
2556 return posix_error();
2557 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002558 /* change permission of slave */
2559 if (grantpt(master_fd) < 0) {
2560 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002561 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002562 }
2563 /* unlock slave */
2564 if (unlockpt(master_fd) < 0) {
2565 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002566 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002567 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002568 signal(SIGCHLD, sig_saved);
2569 slave_name = ptsname(master_fd); /* get name of slave */
2570 if (slave_name == NULL)
2571 return posix_error();
2572 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2573 if (slave_fd < 0)
2574 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002575#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002576 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2577 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002578#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002579 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002580#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002581#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002582#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002583
Fred Drake8cef4cf2000-06-28 16:40:38 +00002584 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002585
Fred Drake8cef4cf2000-06-28 16:40:38 +00002586}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002587#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002588
2589#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002590PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002591"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002592Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2593Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002594To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002595
2596static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002597posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002598{
2599 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002600
Fred Drake8cef4cf2000-06-28 16:40:38 +00002601 pid = forkpty(&master_fd, NULL, NULL, NULL);
2602 if (pid == -1)
2603 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002604 if (pid == 0)
2605 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002606 return Py_BuildValue("(ii)", pid, master_fd);
2607}
2608#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002609
Guido van Rossumad0ee831995-03-01 10:34:45 +00002610#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002611PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002612"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002613Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002614
Barry Warsaw53699e91996-12-10 23:23:01 +00002615static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002616posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002617{
Barry Warsaw53699e91996-12-10 23:23:01 +00002618 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002619}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002620#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002622
Guido van Rossumad0ee831995-03-01 10:34:45 +00002623#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002624PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002625"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002626Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002627
Barry Warsaw53699e91996-12-10 23:23:01 +00002628static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002629posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002630{
Barry Warsaw53699e91996-12-10 23:23:01 +00002631 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002632}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002633#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002634
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002635
Guido van Rossumad0ee831995-03-01 10:34:45 +00002636#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002637PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002638"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002639Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002640
Barry Warsaw53699e91996-12-10 23:23:01 +00002641static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002642posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002643{
Barry Warsaw53699e91996-12-10 23:23:01 +00002644 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002645}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002646#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002647
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002648
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002649PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002650"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002651Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002652
Barry Warsaw53699e91996-12-10 23:23:01 +00002653static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002654posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002655{
Barry Warsaw53699e91996-12-10 23:23:01 +00002656 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002657}
2658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002659
Fred Drakec9680921999-12-13 16:37:25 +00002660#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002661PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002662"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002663Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002664
2665static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002666posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00002667{
2668 PyObject *result = NULL;
2669
Fred Drakec9680921999-12-13 16:37:25 +00002670#ifdef NGROUPS_MAX
2671#define MAX_GROUPS NGROUPS_MAX
2672#else
2673 /* defined to be 16 on Solaris7, so this should be a small number */
2674#define MAX_GROUPS 64
2675#endif
2676 gid_t grouplist[MAX_GROUPS];
2677 int n;
2678
2679 n = getgroups(MAX_GROUPS, grouplist);
2680 if (n < 0)
2681 posix_error();
2682 else {
2683 result = PyList_New(n);
2684 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00002685 int i;
2686 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00002687 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00002688 if (o == NULL) {
2689 Py_DECREF(result);
2690 result = NULL;
2691 break;
2692 }
2693 PyList_SET_ITEM(result, i, o);
2694 }
2695 }
2696 }
Neal Norwitze241ce82003-02-17 18:17:05 +00002697
Fred Drakec9680921999-12-13 16:37:25 +00002698 return result;
2699}
2700#endif
2701
Martin v. Löwis606edc12002-06-13 21:09:11 +00002702#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002703PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002704"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002705Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002706
2707static PyObject *
2708posix_getpgid(PyObject *self, PyObject *args)
2709{
2710 int pid, pgid;
2711 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2712 return NULL;
2713 pgid = getpgid(pid);
2714 if (pgid < 0)
2715 return posix_error();
2716 return PyInt_FromLong((long)pgid);
2717}
2718#endif /* HAVE_GETPGID */
2719
2720
Guido van Rossumb6775db1994-08-01 11:34:53 +00002721#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002722PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002723"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002724Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002725
Barry Warsaw53699e91996-12-10 23:23:01 +00002726static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002727posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00002728{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002729#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002730 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002731#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002732 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002733#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002734}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002735#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002736
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002737
Guido van Rossumb6775db1994-08-01 11:34:53 +00002738#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002739PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002740"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002741Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002742
Barry Warsaw53699e91996-12-10 23:23:01 +00002743static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002744posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002745{
Guido van Rossum64933891994-10-20 21:56:42 +00002746#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002747 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002748#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002749 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002750#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002751 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002752 Py_INCREF(Py_None);
2753 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002754}
2755
Guido van Rossumb6775db1994-08-01 11:34:53 +00002756#endif /* HAVE_SETPGRP */
2757
Guido van Rossumad0ee831995-03-01 10:34:45 +00002758#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002759PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002760"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002761Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002762
Barry Warsaw53699e91996-12-10 23:23:01 +00002763static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002764posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002765{
Barry Warsaw53699e91996-12-10 23:23:01 +00002766 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002767}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002768#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002770
Fred Drake12c6e2d1999-12-14 21:25:03 +00002771#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002772PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002773"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002774Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002775
2776static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002777posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002778{
Neal Norwitze241ce82003-02-17 18:17:05 +00002779 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00002780 char *name;
2781 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002782
Fred Drakea30680b2000-12-06 21:24:28 +00002783 errno = 0;
2784 name = getlogin();
2785 if (name == NULL) {
2786 if (errno)
2787 posix_error();
2788 else
2789 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002790 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002791 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002792 else
2793 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002794 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00002795
Fred Drake12c6e2d1999-12-14 21:25:03 +00002796 return result;
2797}
2798#endif
2799
Guido van Rossumad0ee831995-03-01 10:34:45 +00002800#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002801PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002802"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002803Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002804
Barry Warsaw53699e91996-12-10 23:23:01 +00002805static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002806posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002807{
Barry Warsaw53699e91996-12-10 23:23:01 +00002808 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002809}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002810#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002812
Guido van Rossumad0ee831995-03-01 10:34:45 +00002813#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002814PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002815"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002816Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002817
Barry Warsaw53699e91996-12-10 23:23:01 +00002818static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002819posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002820{
2821 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002822 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002823 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002824#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002825 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2826 APIRET rc;
2827 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002828 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002829
2830 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2831 APIRET rc;
2832 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002833 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002834
2835 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002836 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002837#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002838 if (kill(pid, sig) == -1)
2839 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002840#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002841 Py_INCREF(Py_None);
2842 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002843}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002844#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002845
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002846#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002847PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002848"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002849Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002850
2851static PyObject *
2852posix_killpg(PyObject *self, PyObject *args)
2853{
2854 int pgid, sig;
2855 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2856 return NULL;
2857 if (killpg(pgid, sig) == -1)
2858 return posix_error();
2859 Py_INCREF(Py_None);
2860 return Py_None;
2861}
2862#endif
2863
Guido van Rossumc0125471996-06-28 18:55:32 +00002864#ifdef HAVE_PLOCK
2865
2866#ifdef HAVE_SYS_LOCK_H
2867#include <sys/lock.h>
2868#endif
2869
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002870PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002871"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002872Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002873
Barry Warsaw53699e91996-12-10 23:23:01 +00002874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002875posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002876{
2877 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002878 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002879 return NULL;
2880 if (plock(op) == -1)
2881 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002882 Py_INCREF(Py_None);
2883 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002884}
2885#endif
2886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002887
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002888#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002889PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002890"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002891Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002892
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002893#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002894#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002895static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002896async_system(const char *command)
2897{
2898 char *p, errormsg[256], args[1024];
2899 RESULTCODES rcodes;
2900 APIRET rc;
2901 char *shell = getenv("COMSPEC");
2902 if (!shell)
2903 shell = "cmd";
2904
2905 strcpy(args, shell);
2906 p = &args[ strlen(args)+1 ];
2907 strcpy(p, "/c ");
2908 strcat(p, command);
2909 p += strlen(p) + 1;
2910 *p = '\0';
2911
2912 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002913 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002914 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002915 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002916 &rcodes, shell);
2917 return rc;
2918}
2919
Guido van Rossumd48f2521997-12-05 22:19:34 +00002920static FILE *
2921popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002922{
2923 HFILE rhan, whan;
2924 FILE *retfd = NULL;
2925 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2926
Guido van Rossumd48f2521997-12-05 22:19:34 +00002927 if (rc != NO_ERROR) {
2928 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002929 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002930 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002931
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002932 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2933 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002934
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002935 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2936 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002937
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002938 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2939 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002940
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002941 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002942 }
2943
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002944 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2945 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002946
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002947 if (rc == NO_ERROR)
2948 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2949
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002950 close(oldfd); /* And Close Saved STDOUT Handle */
2951 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002952
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002953 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2954 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002955
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002956 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2957 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002958
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002959 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2960 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002961
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002962 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002963 }
2964
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002965 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2966 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002967
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002968 if (rc == NO_ERROR)
2969 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2970
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002971 close(oldfd); /* And Close Saved STDIN Handle */
2972 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002973
Guido van Rossumd48f2521997-12-05 22:19:34 +00002974 } else {
2975 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002976 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002977 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002978}
2979
2980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002981posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002982{
2983 char *name;
2984 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002985 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002986 FILE *fp;
2987 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002988 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002989 return NULL;
2990 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002991 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002992 Py_END_ALLOW_THREADS
2993 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002994 return os2_error(err);
2995
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002996 f = PyFile_FromFile(fp, name, mode, fclose);
2997 if (f != NULL)
2998 PyFile_SetBufSize(f, bufsize);
2999 return f;
3000}
3001
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003002#elif defined(PYCC_GCC)
3003
3004/* standard posix version of popen() support */
3005static PyObject *
3006posix_popen(PyObject *self, PyObject *args)
3007{
3008 char *name;
3009 char *mode = "r";
3010 int bufsize = -1;
3011 FILE *fp;
3012 PyObject *f;
3013 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3014 return NULL;
3015 Py_BEGIN_ALLOW_THREADS
3016 fp = popen(name, mode);
3017 Py_END_ALLOW_THREADS
3018 if (fp == NULL)
3019 return posix_error();
3020 f = PyFile_FromFile(fp, name, mode, pclose);
3021 if (f != NULL)
3022 PyFile_SetBufSize(f, bufsize);
3023 return f;
3024}
3025
3026/* fork() under OS/2 has lots'o'warts
3027 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3028 * most of this code is a ripoff of the win32 code, but using the
3029 * capabilities of EMX's C library routines
3030 */
3031
3032/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3033#define POPEN_1 1
3034#define POPEN_2 2
3035#define POPEN_3 3
3036#define POPEN_4 4
3037
3038static PyObject *_PyPopen(char *, int, int, int);
3039static int _PyPclose(FILE *file);
3040
3041/*
3042 * Internal dictionary mapping popen* file pointers to process handles,
3043 * for use when retrieving the process exit code. See _PyPclose() below
3044 * for more information on this dictionary's use.
3045 */
3046static PyObject *_PyPopenProcs = NULL;
3047
3048/* os2emx version of popen2()
3049 *
3050 * The result of this function is a pipe (file) connected to the
3051 * process's stdin, and a pipe connected to the process's stdout.
3052 */
3053
3054static PyObject *
3055os2emx_popen2(PyObject *self, PyObject *args)
3056{
3057 PyObject *f;
3058 int tm=0;
3059
3060 char *cmdstring;
3061 char *mode = "t";
3062 int bufsize = -1;
3063 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3064 return NULL;
3065
3066 if (*mode == 't')
3067 tm = O_TEXT;
3068 else if (*mode != 'b') {
3069 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3070 return NULL;
3071 } else
3072 tm = O_BINARY;
3073
3074 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3075
3076 return f;
3077}
3078
3079/*
3080 * Variation on os2emx.popen2
3081 *
3082 * The result of this function is 3 pipes - the process's stdin,
3083 * stdout and stderr
3084 */
3085
3086static PyObject *
3087os2emx_popen3(PyObject *self, PyObject *args)
3088{
3089 PyObject *f;
3090 int tm = 0;
3091
3092 char *cmdstring;
3093 char *mode = "t";
3094 int bufsize = -1;
3095 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3096 return NULL;
3097
3098 if (*mode == 't')
3099 tm = O_TEXT;
3100 else if (*mode != 'b') {
3101 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3102 return NULL;
3103 } else
3104 tm = O_BINARY;
3105
3106 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3107
3108 return f;
3109}
3110
3111/*
3112 * Variation on os2emx.popen2
3113 *
Tim Peters11b23062003-04-23 02:39:17 +00003114 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003115 * and stdout+stderr combined as a single pipe.
3116 */
3117
3118static PyObject *
3119os2emx_popen4(PyObject *self, PyObject *args)
3120{
3121 PyObject *f;
3122 int tm = 0;
3123
3124 char *cmdstring;
3125 char *mode = "t";
3126 int bufsize = -1;
3127 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3128 return NULL;
3129
3130 if (*mode == 't')
3131 tm = O_TEXT;
3132 else if (*mode != 'b') {
3133 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3134 return NULL;
3135 } else
3136 tm = O_BINARY;
3137
3138 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3139
3140 return f;
3141}
3142
3143/* a couple of structures for convenient handling of multiple
3144 * file handles and pipes
3145 */
3146struct file_ref
3147{
3148 int handle;
3149 int flags;
3150};
3151
3152struct pipe_ref
3153{
3154 int rd;
3155 int wr;
3156};
3157
3158/* The following code is derived from the win32 code */
3159
3160static PyObject *
3161_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3162{
3163 struct file_ref stdio[3];
3164 struct pipe_ref p_fd[3];
3165 FILE *p_s[3];
3166 int file_count, i, pipe_err, pipe_pid;
3167 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3168 PyObject *f, *p_f[3];
3169
3170 /* file modes for subsequent fdopen's on pipe handles */
3171 if (mode == O_TEXT)
3172 {
3173 rd_mode = "rt";
3174 wr_mode = "wt";
3175 }
3176 else
3177 {
3178 rd_mode = "rb";
3179 wr_mode = "wb";
3180 }
3181
3182 /* prepare shell references */
3183 if ((shell = getenv("EMXSHELL")) == NULL)
3184 if ((shell = getenv("COMSPEC")) == NULL)
3185 {
3186 errno = ENOENT;
3187 return posix_error();
3188 }
3189
3190 sh_name = _getname(shell);
3191 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3192 opt = "/c";
3193 else
3194 opt = "-c";
3195
3196 /* save current stdio fds + their flags, and set not inheritable */
3197 i = pipe_err = 0;
3198 while (pipe_err >= 0 && i < 3)
3199 {
3200 pipe_err = stdio[i].handle = dup(i);
3201 stdio[i].flags = fcntl(i, F_GETFD, 0);
3202 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3203 i++;
3204 }
3205 if (pipe_err < 0)
3206 {
3207 /* didn't get them all saved - clean up and bail out */
3208 int saved_err = errno;
3209 while (i-- > 0)
3210 {
3211 close(stdio[i].handle);
3212 }
3213 errno = saved_err;
3214 return posix_error();
3215 }
3216
3217 /* create pipe ends */
3218 file_count = 2;
3219 if (n == POPEN_3)
3220 file_count = 3;
3221 i = pipe_err = 0;
3222 while ((pipe_err == 0) && (i < file_count))
3223 pipe_err = pipe((int *)&p_fd[i++]);
3224 if (pipe_err < 0)
3225 {
3226 /* didn't get them all made - clean up and bail out */
3227 while (i-- > 0)
3228 {
3229 close(p_fd[i].wr);
3230 close(p_fd[i].rd);
3231 }
3232 errno = EPIPE;
3233 return posix_error();
3234 }
3235
3236 /* change the actual standard IO streams over temporarily,
3237 * making the retained pipe ends non-inheritable
3238 */
3239 pipe_err = 0;
3240
3241 /* - stdin */
3242 if (dup2(p_fd[0].rd, 0) == 0)
3243 {
3244 close(p_fd[0].rd);
3245 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3246 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3247 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3248 {
3249 close(p_fd[0].wr);
3250 pipe_err = -1;
3251 }
3252 }
3253 else
3254 {
3255 pipe_err = -1;
3256 }
3257
3258 /* - stdout */
3259 if (pipe_err == 0)
3260 {
3261 if (dup2(p_fd[1].wr, 1) == 1)
3262 {
3263 close(p_fd[1].wr);
3264 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3265 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3266 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3267 {
3268 close(p_fd[1].rd);
3269 pipe_err = -1;
3270 }
3271 }
3272 else
3273 {
3274 pipe_err = -1;
3275 }
3276 }
3277
3278 /* - stderr, as required */
3279 if (pipe_err == 0)
3280 switch (n)
3281 {
3282 case POPEN_3:
3283 {
3284 if (dup2(p_fd[2].wr, 2) == 2)
3285 {
3286 close(p_fd[2].wr);
3287 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3288 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3289 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3290 {
3291 close(p_fd[2].rd);
3292 pipe_err = -1;
3293 }
3294 }
3295 else
3296 {
3297 pipe_err = -1;
3298 }
3299 break;
3300 }
3301
3302 case POPEN_4:
3303 {
3304 if (dup2(1, 2) != 2)
3305 {
3306 pipe_err = -1;
3307 }
3308 break;
3309 }
3310 }
3311
3312 /* spawn the child process */
3313 if (pipe_err == 0)
3314 {
3315 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3316 if (pipe_pid == -1)
3317 {
3318 pipe_err = -1;
3319 }
3320 else
3321 {
3322 /* save the PID into the FILE structure
3323 * NOTE: this implementation doesn't actually
3324 * take advantage of this, but do it for
3325 * completeness - AIM Apr01
3326 */
3327 for (i = 0; i < file_count; i++)
3328 p_s[i]->_pid = pipe_pid;
3329 }
3330 }
3331
3332 /* reset standard IO to normal */
3333 for (i = 0; i < 3; i++)
3334 {
3335 dup2(stdio[i].handle, i);
3336 fcntl(i, F_SETFD, stdio[i].flags);
3337 close(stdio[i].handle);
3338 }
3339
3340 /* if any remnant problems, clean up and bail out */
3341 if (pipe_err < 0)
3342 {
3343 for (i = 0; i < 3; i++)
3344 {
3345 close(p_fd[i].rd);
3346 close(p_fd[i].wr);
3347 }
3348 errno = EPIPE;
3349 return posix_error_with_filename(cmdstring);
3350 }
3351
3352 /* build tuple of file objects to return */
3353 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3354 PyFile_SetBufSize(p_f[0], bufsize);
3355 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3356 PyFile_SetBufSize(p_f[1], bufsize);
3357 if (n == POPEN_3)
3358 {
3359 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3360 PyFile_SetBufSize(p_f[0], bufsize);
3361 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3362 }
3363 else
3364 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3365
3366 /*
3367 * Insert the files we've created into the process dictionary
3368 * all referencing the list with the process handle and the
3369 * initial number of files (see description below in _PyPclose).
3370 * Since if _PyPclose later tried to wait on a process when all
3371 * handles weren't closed, it could create a deadlock with the
3372 * child, we spend some energy here to try to ensure that we
3373 * either insert all file handles into the dictionary or none
3374 * at all. It's a little clumsy with the various popen modes
3375 * and variable number of files involved.
3376 */
3377 if (!_PyPopenProcs)
3378 {
3379 _PyPopenProcs = PyDict_New();
3380 }
3381
3382 if (_PyPopenProcs)
3383 {
3384 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3385 int ins_rc[3];
3386
3387 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3388 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3389
3390 procObj = PyList_New(2);
3391 pidObj = PyInt_FromLong((long) pipe_pid);
3392 intObj = PyInt_FromLong((long) file_count);
3393
3394 if (procObj && pidObj && intObj)
3395 {
3396 PyList_SetItem(procObj, 0, pidObj);
3397 PyList_SetItem(procObj, 1, intObj);
3398
3399 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3400 if (fileObj[0])
3401 {
3402 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3403 fileObj[0],
3404 procObj);
3405 }
3406 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3407 if (fileObj[1])
3408 {
3409 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3410 fileObj[1],
3411 procObj);
3412 }
3413 if (file_count >= 3)
3414 {
3415 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3416 if (fileObj[2])
3417 {
3418 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3419 fileObj[2],
3420 procObj);
3421 }
3422 }
3423
3424 if (ins_rc[0] < 0 || !fileObj[0] ||
3425 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3426 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3427 {
3428 /* Something failed - remove any dictionary
3429 * entries that did make it.
3430 */
3431 if (!ins_rc[0] && fileObj[0])
3432 {
3433 PyDict_DelItem(_PyPopenProcs,
3434 fileObj[0]);
3435 }
3436 if (!ins_rc[1] && fileObj[1])
3437 {
3438 PyDict_DelItem(_PyPopenProcs,
3439 fileObj[1]);
3440 }
3441 if (!ins_rc[2] && fileObj[2])
3442 {
3443 PyDict_DelItem(_PyPopenProcs,
3444 fileObj[2]);
3445 }
3446 }
3447 }
Tim Peters11b23062003-04-23 02:39:17 +00003448
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003449 /*
3450 * Clean up our localized references for the dictionary keys
3451 * and value since PyDict_SetItem will Py_INCREF any copies
3452 * that got placed in the dictionary.
3453 */
3454 Py_XDECREF(procObj);
3455 Py_XDECREF(fileObj[0]);
3456 Py_XDECREF(fileObj[1]);
3457 Py_XDECREF(fileObj[2]);
3458 }
3459
3460 /* Child is launched. */
3461 return f;
3462}
3463
3464/*
3465 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3466 * exit code for the child process and return as a result of the close.
3467 *
3468 * This function uses the _PyPopenProcs dictionary in order to map the
3469 * input file pointer to information about the process that was
3470 * originally created by the popen* call that created the file pointer.
3471 * The dictionary uses the file pointer as a key (with one entry
3472 * inserted for each file returned by the original popen* call) and a
3473 * single list object as the value for all files from a single call.
3474 * The list object contains the Win32 process handle at [0], and a file
3475 * count at [1], which is initialized to the total number of file
3476 * handles using that list.
3477 *
3478 * This function closes whichever handle it is passed, and decrements
3479 * the file count in the dictionary for the process handle pointed to
3480 * by this file. On the last close (when the file count reaches zero),
3481 * this function will wait for the child process and then return its
3482 * exit code as the result of the close() operation. This permits the
3483 * files to be closed in any order - it is always the close() of the
3484 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003485 *
3486 * NOTE: This function is currently called with the GIL released.
3487 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003488 */
3489
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003490static int _PyPclose(FILE *file)
3491{
3492 int result;
3493 int exit_code;
3494 int pipe_pid;
3495 PyObject *procObj, *pidObj, *intObj, *fileObj;
3496 int file_count;
3497#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003498 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003499#endif
3500
3501 /* Close the file handle first, to ensure it can't block the
3502 * child from exiting if it's the last handle.
3503 */
3504 result = fclose(file);
3505
3506#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003507 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003508#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003509 if (_PyPopenProcs)
3510 {
3511 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3512 (procObj = PyDict_GetItem(_PyPopenProcs,
3513 fileObj)) != NULL &&
3514 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3515 (intObj = PyList_GetItem(procObj,1)) != NULL)
3516 {
3517 pipe_pid = (int) PyInt_AsLong(pidObj);
3518 file_count = (int) PyInt_AsLong(intObj);
3519
3520 if (file_count > 1)
3521 {
3522 /* Still other files referencing process */
3523 file_count--;
3524 PyList_SetItem(procObj,1,
3525 PyInt_FromLong((long) file_count));
3526 }
3527 else
3528 {
3529 /* Last file for this process */
3530 if (result != EOF &&
3531 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3532 {
3533 /* extract exit status */
3534 if (WIFEXITED(exit_code))
3535 {
3536 result = WEXITSTATUS(exit_code);
3537 }
3538 else
3539 {
3540 errno = EPIPE;
3541 result = -1;
3542 }
3543 }
3544 else
3545 {
3546 /* Indicate failure - this will cause the file object
3547 * to raise an I/O error and translate the last
3548 * error code from errno. We do have a problem with
3549 * last errors that overlap the normal errno table,
3550 * but that's a consistent problem with the file object.
3551 */
3552 result = -1;
3553 }
3554 }
3555
3556 /* Remove this file pointer from dictionary */
3557 PyDict_DelItem(_PyPopenProcs, fileObj);
3558
3559 if (PyDict_Size(_PyPopenProcs) == 0)
3560 {
3561 Py_DECREF(_PyPopenProcs);
3562 _PyPopenProcs = NULL;
3563 }
3564
3565 } /* if object retrieval ok */
3566
3567 Py_XDECREF(fileObj);
3568 } /* if _PyPopenProcs */
3569
3570#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003571 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003572#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003573 return result;
3574}
3575
3576#endif /* PYCC_??? */
3577
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003578#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003579
3580/*
3581 * Portable 'popen' replacement for Win32.
3582 *
3583 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3584 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003585 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003586 */
3587
3588#include <malloc.h>
3589#include <io.h>
3590#include <fcntl.h>
3591
3592/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3593#define POPEN_1 1
3594#define POPEN_2 2
3595#define POPEN_3 3
3596#define POPEN_4 4
3597
3598static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003599static int _PyPclose(FILE *file);
3600
3601/*
3602 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003603 * for use when retrieving the process exit code. See _PyPclose() below
3604 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003605 */
3606static PyObject *_PyPopenProcs = NULL;
3607
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003608
3609/* popen that works from a GUI.
3610 *
3611 * The result of this function is a pipe (file) connected to the
3612 * processes stdin or stdout, depending on the requested mode.
3613 */
3614
3615static PyObject *
3616posix_popen(PyObject *self, PyObject *args)
3617{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00003618 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003619 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003620
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003621 char *cmdstring;
3622 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003623 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003624 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003625 return NULL;
3626
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003627 if (*mode == 'r')
3628 tm = _O_RDONLY;
3629 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003630 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003631 return NULL;
3632 } else
3633 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003634
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003635 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003636 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003637 return NULL;
3638 }
3639
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003640 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003641 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003642 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003643 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003644 else
3645 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3646
3647 return f;
3648}
3649
3650/* Variation on win32pipe.popen
3651 *
3652 * The result of this function is a pipe (file) connected to the
3653 * process's stdin, and a pipe connected to the process's stdout.
3654 */
3655
3656static PyObject *
3657win32_popen2(PyObject *self, PyObject *args)
3658{
3659 PyObject *f;
3660 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003661
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003662 char *cmdstring;
3663 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003664 int bufsize = -1;
3665 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003666 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003667
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003668 if (*mode == 't')
3669 tm = _O_TEXT;
3670 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003671 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003672 return NULL;
3673 } else
3674 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003675
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003676 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003677 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003678 return NULL;
3679 }
3680
3681 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003682
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003683 return f;
3684}
3685
3686/*
3687 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003688 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003689 * The result of this function is 3 pipes - the process's stdin,
3690 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003691 */
3692
3693static PyObject *
3694win32_popen3(PyObject *self, PyObject *args)
3695{
3696 PyObject *f;
3697 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003698
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003699 char *cmdstring;
3700 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003701 int bufsize = -1;
3702 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003703 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003704
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003705 if (*mode == 't')
3706 tm = _O_TEXT;
3707 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003708 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003709 return NULL;
3710 } else
3711 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003712
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003713 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003714 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003715 return NULL;
3716 }
3717
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003718 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003719
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003720 return f;
3721}
3722
3723/*
3724 * Variation on win32pipe.popen
3725 *
Tim Peters5aa91602002-01-30 05:46:57 +00003726 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003727 * and stdout+stderr combined as a single pipe.
3728 */
3729
3730static PyObject *
3731win32_popen4(PyObject *self, PyObject *args)
3732{
3733 PyObject *f;
3734 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003735
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003736 char *cmdstring;
3737 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003738 int bufsize = -1;
3739 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003740 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003741
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003742 if (*mode == 't')
3743 tm = _O_TEXT;
3744 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003745 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003746 return NULL;
3747 } else
3748 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003749
3750 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003751 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003752 return NULL;
3753 }
3754
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003755 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003756
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003757 return f;
3758}
3759
Mark Hammond08501372001-01-31 07:30:29 +00003760static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003761_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003762 HANDLE hStdin,
3763 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003764 HANDLE hStderr,
3765 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003766{
3767 PROCESS_INFORMATION piProcInfo;
3768 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003769 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003770 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003771 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003772 int i;
3773 int x;
3774
3775 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003776 char *comshell;
3777
Tim Peters92e4dd82002-10-05 01:47:34 +00003778 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003779 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3780 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003781
3782 /* Explicitly check if we are using COMMAND.COM. If we are
3783 * then use the w9xpopen hack.
3784 */
3785 comshell = s1 + x;
3786 while (comshell >= s1 && *comshell != '\\')
3787 --comshell;
3788 ++comshell;
3789
3790 if (GetVersion() < 0x80000000 &&
3791 _stricmp(comshell, "command.com") != 0) {
3792 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003793 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003794 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003795 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003796 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003797 }
3798 else {
3799 /*
Tim Peters402d5982001-08-27 06:37:48 +00003800 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3801 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003802 */
Mark Hammond08501372001-01-31 07:30:29 +00003803 char modulepath[_MAX_PATH];
3804 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003805 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3806 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003807 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003808 x = i+1;
3809 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003810 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003811 strncat(modulepath,
3812 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003813 (sizeof(modulepath)/sizeof(modulepath[0]))
3814 -strlen(modulepath));
3815 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003816 /* Eeek - file-not-found - possibly an embedding
3817 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003818 */
Tim Peters5aa91602002-01-30 05:46:57 +00003819 strncpy(modulepath,
3820 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003821 sizeof(modulepath)/sizeof(modulepath[0]));
3822 if (modulepath[strlen(modulepath)-1] != '\\')
3823 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003824 strncat(modulepath,
3825 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003826 (sizeof(modulepath)/sizeof(modulepath[0]))
3827 -strlen(modulepath));
3828 /* No where else to look - raise an easily identifiable
3829 error, rather than leaving Windows to report
3830 "file not found" - as the user is probably blissfully
3831 unaware this shim EXE is used, and it will confuse them.
3832 (well, it confused me for a while ;-)
3833 */
3834 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003835 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003836 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003837 "for popen to work with your shell "
3838 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003839 szConsoleSpawn);
3840 return FALSE;
3841 }
3842 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003843 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003844 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003845 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003846
Tim Peters92e4dd82002-10-05 01:47:34 +00003847 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003848 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003849 /* To maintain correct argument passing semantics,
3850 we pass the command-line as it stands, and allow
3851 quoting to be applied. w9xpopen.exe will then
3852 use its argv vector, and re-quote the necessary
3853 args for the ultimate child process.
3854 */
Tim Peters75cdad52001-11-28 22:07:30 +00003855 PyOS_snprintf(
3856 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003857 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003858 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003859 s1,
3860 s3,
3861 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003862 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00003863 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003864 dialog:
3865 "Your program accessed mem currently in use at xxx"
3866 and a hopeful warning about the stability of your
3867 system.
3868 Cost is Ctrl+C wont kill children, but anyone
3869 who cares can have a go!
3870 */
3871 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003872 }
3873 }
3874
3875 /* Could be an else here to try cmd.exe / command.com in the path
3876 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003877 else {
Tim Peters402d5982001-08-27 06:37:48 +00003878 PyErr_SetString(PyExc_RuntimeError,
3879 "Cannot locate a COMSPEC environment variable to "
3880 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003881 return FALSE;
3882 }
Tim Peters5aa91602002-01-30 05:46:57 +00003883
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003884 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3885 siStartInfo.cb = sizeof(STARTUPINFO);
3886 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3887 siStartInfo.hStdInput = hStdin;
3888 siStartInfo.hStdOutput = hStdout;
3889 siStartInfo.hStdError = hStderr;
3890 siStartInfo.wShowWindow = SW_HIDE;
3891
3892 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003893 s2,
3894 NULL,
3895 NULL,
3896 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003897 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003898 NULL,
3899 NULL,
3900 &siStartInfo,
3901 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003902 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003903 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003904
Mark Hammondb37a3732000-08-14 04:47:33 +00003905 /* Return process handle */
3906 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003907 return TRUE;
3908 }
Tim Peters402d5982001-08-27 06:37:48 +00003909 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003910 return FALSE;
3911}
3912
3913/* The following code is based off of KB: Q190351 */
3914
3915static PyObject *
3916_PyPopen(char *cmdstring, int mode, int n)
3917{
3918 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3919 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003920 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003921
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003922 SECURITY_ATTRIBUTES saAttr;
3923 BOOL fSuccess;
3924 int fd1, fd2, fd3;
3925 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003926 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003927 PyObject *f;
3928
3929 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3930 saAttr.bInheritHandle = TRUE;
3931 saAttr.lpSecurityDescriptor = NULL;
3932
3933 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3934 return win32_error("CreatePipe", NULL);
3935
3936 /* Create new output read handle and the input write handle. Set
3937 * the inheritance properties to FALSE. Otherwise, the child inherits
3938 * the these handles; resulting in non-closeable handles to the pipes
3939 * being created. */
3940 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003941 GetCurrentProcess(), &hChildStdinWrDup, 0,
3942 FALSE,
3943 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003944 if (!fSuccess)
3945 return win32_error("DuplicateHandle", NULL);
3946
3947 /* Close the inheritable version of ChildStdin
3948 that we're using. */
3949 CloseHandle(hChildStdinWr);
3950
3951 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3952 return win32_error("CreatePipe", NULL);
3953
3954 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003955 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3956 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003957 if (!fSuccess)
3958 return win32_error("DuplicateHandle", NULL);
3959
3960 /* Close the inheritable version of ChildStdout
3961 that we're using. */
3962 CloseHandle(hChildStdoutRd);
3963
3964 if (n != POPEN_4) {
3965 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3966 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003967 fSuccess = DuplicateHandle(GetCurrentProcess(),
3968 hChildStderrRd,
3969 GetCurrentProcess(),
3970 &hChildStderrRdDup, 0,
3971 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003972 if (!fSuccess)
3973 return win32_error("DuplicateHandle", NULL);
3974 /* Close the inheritable version of ChildStdErr that we're using. */
3975 CloseHandle(hChildStderrRd);
3976 }
Tim Peters5aa91602002-01-30 05:46:57 +00003977
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003978 switch (n) {
3979 case POPEN_1:
3980 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3981 case _O_WRONLY | _O_TEXT:
3982 /* Case for writing to child Stdin in text mode. */
3983 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3984 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003985 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003986 PyFile_SetBufSize(f, 0);
3987 /* We don't care about these pipes anymore, so close them. */
3988 CloseHandle(hChildStdoutRdDup);
3989 CloseHandle(hChildStderrRdDup);
3990 break;
3991
3992 case _O_RDONLY | _O_TEXT:
3993 /* Case for reading from child Stdout in text mode. */
3994 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3995 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003996 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003997 PyFile_SetBufSize(f, 0);
3998 /* We don't care about these pipes anymore, so close them. */
3999 CloseHandle(hChildStdinWrDup);
4000 CloseHandle(hChildStderrRdDup);
4001 break;
4002
4003 case _O_RDONLY | _O_BINARY:
4004 /* Case for readinig from child Stdout in binary mode. */
4005 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4006 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004007 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004008 PyFile_SetBufSize(f, 0);
4009 /* We don't care about these pipes anymore, so close them. */
4010 CloseHandle(hChildStdinWrDup);
4011 CloseHandle(hChildStderrRdDup);
4012 break;
4013
4014 case _O_WRONLY | _O_BINARY:
4015 /* Case for writing to child Stdin in binary mode. */
4016 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4017 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004018 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004019 PyFile_SetBufSize(f, 0);
4020 /* We don't care about these pipes anymore, so close them. */
4021 CloseHandle(hChildStdoutRdDup);
4022 CloseHandle(hChildStderrRdDup);
4023 break;
4024 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004025 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004026 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004027
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004028 case POPEN_2:
4029 case POPEN_4:
4030 {
4031 char *m1, *m2;
4032 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004033
Tim Peters7dca21e2002-08-19 00:42:29 +00004034 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004035 m1 = "r";
4036 m2 = "w";
4037 } else {
4038 m1 = "rb";
4039 m2 = "wb";
4040 }
4041
4042 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4043 f1 = _fdopen(fd1, m2);
4044 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4045 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004046 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004047 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004048 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004049 PyFile_SetBufSize(p2, 0);
4050
4051 if (n != 4)
4052 CloseHandle(hChildStderrRdDup);
4053
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004054 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004055 Py_XDECREF(p1);
4056 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004057 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004058 break;
4059 }
Tim Peters5aa91602002-01-30 05:46:57 +00004060
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004061 case POPEN_3:
4062 {
4063 char *m1, *m2;
4064 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004065
Tim Peters7dca21e2002-08-19 00:42:29 +00004066 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004067 m1 = "r";
4068 m2 = "w";
4069 } else {
4070 m1 = "rb";
4071 m2 = "wb";
4072 }
4073
4074 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4075 f1 = _fdopen(fd1, m2);
4076 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4077 f2 = _fdopen(fd2, m1);
4078 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4079 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004080 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004081 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4082 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004083 PyFile_SetBufSize(p1, 0);
4084 PyFile_SetBufSize(p2, 0);
4085 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004086 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004087 Py_XDECREF(p1);
4088 Py_XDECREF(p2);
4089 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004090 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004091 break;
4092 }
4093 }
4094
4095 if (n == POPEN_4) {
4096 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004097 hChildStdinRd,
4098 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004099 hChildStdoutWr,
4100 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004101 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004102 }
4103 else {
4104 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004105 hChildStdinRd,
4106 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004107 hChildStderrWr,
4108 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004109 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004110 }
4111
Mark Hammondb37a3732000-08-14 04:47:33 +00004112 /*
4113 * Insert the files we've created into the process dictionary
4114 * all referencing the list with the process handle and the
4115 * initial number of files (see description below in _PyPclose).
4116 * Since if _PyPclose later tried to wait on a process when all
4117 * handles weren't closed, it could create a deadlock with the
4118 * child, we spend some energy here to try to ensure that we
4119 * either insert all file handles into the dictionary or none
4120 * at all. It's a little clumsy with the various popen modes
4121 * and variable number of files involved.
4122 */
4123 if (!_PyPopenProcs) {
4124 _PyPopenProcs = PyDict_New();
4125 }
4126
4127 if (_PyPopenProcs) {
4128 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4129 int ins_rc[3];
4130
4131 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4132 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4133
4134 procObj = PyList_New(2);
4135 hProcessObj = PyLong_FromVoidPtr(hProcess);
4136 intObj = PyInt_FromLong(file_count);
4137
4138 if (procObj && hProcessObj && intObj) {
4139 PyList_SetItem(procObj,0,hProcessObj);
4140 PyList_SetItem(procObj,1,intObj);
4141
4142 fileObj[0] = PyLong_FromVoidPtr(f1);
4143 if (fileObj[0]) {
4144 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4145 fileObj[0],
4146 procObj);
4147 }
4148 if (file_count >= 2) {
4149 fileObj[1] = PyLong_FromVoidPtr(f2);
4150 if (fileObj[1]) {
4151 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4152 fileObj[1],
4153 procObj);
4154 }
4155 }
4156 if (file_count >= 3) {
4157 fileObj[2] = PyLong_FromVoidPtr(f3);
4158 if (fileObj[2]) {
4159 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4160 fileObj[2],
4161 procObj);
4162 }
4163 }
4164
4165 if (ins_rc[0] < 0 || !fileObj[0] ||
4166 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4167 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4168 /* Something failed - remove any dictionary
4169 * entries that did make it.
4170 */
4171 if (!ins_rc[0] && fileObj[0]) {
4172 PyDict_DelItem(_PyPopenProcs,
4173 fileObj[0]);
4174 }
4175 if (!ins_rc[1] && fileObj[1]) {
4176 PyDict_DelItem(_PyPopenProcs,
4177 fileObj[1]);
4178 }
4179 if (!ins_rc[2] && fileObj[2]) {
4180 PyDict_DelItem(_PyPopenProcs,
4181 fileObj[2]);
4182 }
4183 }
4184 }
Tim Peters5aa91602002-01-30 05:46:57 +00004185
Mark Hammondb37a3732000-08-14 04:47:33 +00004186 /*
4187 * Clean up our localized references for the dictionary keys
4188 * and value since PyDict_SetItem will Py_INCREF any copies
4189 * that got placed in the dictionary.
4190 */
4191 Py_XDECREF(procObj);
4192 Py_XDECREF(fileObj[0]);
4193 Py_XDECREF(fileObj[1]);
4194 Py_XDECREF(fileObj[2]);
4195 }
4196
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004197 /* Child is launched. Close the parents copy of those pipe
4198 * handles that only the child should have open. You need to
4199 * make sure that no handles to the write end of the output pipe
4200 * are maintained in this process or else the pipe will not close
4201 * when the child process exits and the ReadFile will hang. */
4202
4203 if (!CloseHandle(hChildStdinRd))
4204 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004205
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004206 if (!CloseHandle(hChildStdoutWr))
4207 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004208
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004209 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4210 return win32_error("CloseHandle", NULL);
4211
4212 return f;
4213}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004214
4215/*
4216 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4217 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004218 *
4219 * This function uses the _PyPopenProcs dictionary in order to map the
4220 * input file pointer to information about the process that was
4221 * originally created by the popen* call that created the file pointer.
4222 * The dictionary uses the file pointer as a key (with one entry
4223 * inserted for each file returned by the original popen* call) and a
4224 * single list object as the value for all files from a single call.
4225 * The list object contains the Win32 process handle at [0], and a file
4226 * count at [1], which is initialized to the total number of file
4227 * handles using that list.
4228 *
4229 * This function closes whichever handle it is passed, and decrements
4230 * the file count in the dictionary for the process handle pointed to
4231 * by this file. On the last close (when the file count reaches zero),
4232 * this function will wait for the child process and then return its
4233 * exit code as the result of the close() operation. This permits the
4234 * files to be closed in any order - it is always the close() of the
4235 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004236 *
4237 * NOTE: This function is currently called with the GIL released.
4238 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004239 */
Tim Peters736aa322000-09-01 06:51:24 +00004240
Fredrik Lundh56055a42000-07-23 19:47:12 +00004241static int _PyPclose(FILE *file)
4242{
Fredrik Lundh20318932000-07-26 17:29:12 +00004243 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004244 DWORD exit_code;
4245 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004246 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4247 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004248#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004249 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004250#endif
4251
Fredrik Lundh20318932000-07-26 17:29:12 +00004252 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004253 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004254 */
4255 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004256#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004257 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004258#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004259 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004260 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4261 (procObj = PyDict_GetItem(_PyPopenProcs,
4262 fileObj)) != NULL &&
4263 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4264 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4265
4266 hProcess = PyLong_AsVoidPtr(hProcessObj);
4267 file_count = PyInt_AsLong(intObj);
4268
4269 if (file_count > 1) {
4270 /* Still other files referencing process */
4271 file_count--;
4272 PyList_SetItem(procObj,1,
4273 PyInt_FromLong(file_count));
4274 } else {
4275 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004276 if (result != EOF &&
4277 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4278 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004279 /* Possible truncation here in 16-bit environments, but
4280 * real exit codes are just the lower byte in any event.
4281 */
4282 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004283 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004284 /* Indicate failure - this will cause the file object
4285 * to raise an I/O error and translate the last Win32
4286 * error code from errno. We do have a problem with
4287 * last errors that overlap the normal errno table,
4288 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004289 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004290 if (result != EOF) {
4291 /* If the error wasn't from the fclose(), then
4292 * set errno for the file object error handling.
4293 */
4294 errno = GetLastError();
4295 }
4296 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004297 }
4298
4299 /* Free up the native handle at this point */
4300 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004301 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004302
Mark Hammondb37a3732000-08-14 04:47:33 +00004303 /* Remove this file pointer from dictionary */
4304 PyDict_DelItem(_PyPopenProcs, fileObj);
4305
4306 if (PyDict_Size(_PyPopenProcs) == 0) {
4307 Py_DECREF(_PyPopenProcs);
4308 _PyPopenProcs = NULL;
4309 }
4310
4311 } /* if object retrieval ok */
4312
4313 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004314 } /* if _PyPopenProcs */
4315
Tim Peters736aa322000-09-01 06:51:24 +00004316#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004317 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004318#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004319 return result;
4320}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004321
4322#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004323static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004324posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004325{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004326 char *name;
4327 char *mode = "r";
4328 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004329 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004330 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004331 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004332 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004333 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004334 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004335 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004336 if (fp == NULL)
4337 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004338 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004339 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004340 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004341 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004342}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004343
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004344#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004345#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004346
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004347
Guido van Rossumb6775db1994-08-01 11:34:53 +00004348#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004349PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004350"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004351Set the current process's user id.");
4352
Barry Warsaw53699e91996-12-10 23:23:01 +00004353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004354posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004355{
4356 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004357 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004358 return NULL;
4359 if (setuid(uid) < 0)
4360 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004361 Py_INCREF(Py_None);
4362 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004363}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004364#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004366
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004367#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004368PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004369"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004370Set the current process's effective user id.");
4371
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004372static PyObject *
4373posix_seteuid (PyObject *self, PyObject *args)
4374{
4375 int euid;
4376 if (!PyArg_ParseTuple(args, "i", &euid)) {
4377 return NULL;
4378 } else if (seteuid(euid) < 0) {
4379 return posix_error();
4380 } else {
4381 Py_INCREF(Py_None);
4382 return Py_None;
4383 }
4384}
4385#endif /* HAVE_SETEUID */
4386
4387#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004388PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004389"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004390Set the current process's effective group id.");
4391
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004392static PyObject *
4393posix_setegid (PyObject *self, PyObject *args)
4394{
4395 int egid;
4396 if (!PyArg_ParseTuple(args, "i", &egid)) {
4397 return NULL;
4398 } else if (setegid(egid) < 0) {
4399 return posix_error();
4400 } else {
4401 Py_INCREF(Py_None);
4402 return Py_None;
4403 }
4404}
4405#endif /* HAVE_SETEGID */
4406
4407#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004408PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004409"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004410Set the current process's real and effective user ids.");
4411
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004412static PyObject *
4413posix_setreuid (PyObject *self, PyObject *args)
4414{
4415 int ruid, euid;
4416 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4417 return NULL;
4418 } else if (setreuid(ruid, euid) < 0) {
4419 return posix_error();
4420 } else {
4421 Py_INCREF(Py_None);
4422 return Py_None;
4423 }
4424}
4425#endif /* HAVE_SETREUID */
4426
4427#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004428PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004429"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004430Set the current process's real and effective group ids.");
4431
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004432static PyObject *
4433posix_setregid (PyObject *self, PyObject *args)
4434{
4435 int rgid, egid;
4436 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4437 return NULL;
4438 } else if (setregid(rgid, egid) < 0) {
4439 return posix_error();
4440 } else {
4441 Py_INCREF(Py_None);
4442 return Py_None;
4443 }
4444}
4445#endif /* HAVE_SETREGID */
4446
Guido van Rossumb6775db1994-08-01 11:34:53 +00004447#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004448PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004449"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004450Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004451
Barry Warsaw53699e91996-12-10 23:23:01 +00004452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004453posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004454{
4455 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004456 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004457 return NULL;
4458 if (setgid(gid) < 0)
4459 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004460 Py_INCREF(Py_None);
4461 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004462}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004463#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004464
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004465#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004466PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004467"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004468Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004469
4470static PyObject *
4471posix_setgroups(PyObject *self, PyObject *args)
4472{
4473 PyObject *groups;
4474 int i, len;
4475 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004476
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004477 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4478 return NULL;
4479 if (!PySequence_Check(groups)) {
4480 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4481 return NULL;
4482 }
4483 len = PySequence_Size(groups);
4484 if (len > MAX_GROUPS) {
4485 PyErr_SetString(PyExc_ValueError, "too many groups");
4486 return NULL;
4487 }
4488 for(i = 0; i < len; i++) {
4489 PyObject *elem;
4490 elem = PySequence_GetItem(groups, i);
4491 if (!elem)
4492 return NULL;
4493 if (!PyInt_Check(elem)) {
4494 PyErr_SetString(PyExc_TypeError,
4495 "groups must be integers");
4496 Py_DECREF(elem);
4497 return NULL;
4498 }
4499 /* XXX: check that value fits into gid_t. */
4500 grouplist[i] = PyInt_AsLong(elem);
4501 Py_DECREF(elem);
4502 }
4503
4504 if (setgroups(len, grouplist) < 0)
4505 return posix_error();
4506 Py_INCREF(Py_None);
4507 return Py_None;
4508}
4509#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004510
Guido van Rossumb6775db1994-08-01 11:34:53 +00004511#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004512PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004513"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004514Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004515
Barry Warsaw53699e91996-12-10 23:23:01 +00004516static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004517posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004518{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004519 int pid, options;
4520#ifdef UNION_WAIT
4521 union wait status;
4522#define status_i (status.w_status)
4523#else
4524 int status;
4525#define status_i status
4526#endif
4527 status_i = 0;
4528
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004529 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004530 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004531 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004532 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004533 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004534 if (pid == -1)
4535 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004536 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004537 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004538}
4539
Tim Petersab034fa2002-02-01 11:27:43 +00004540#elif defined(HAVE_CWAIT)
4541
4542/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004543PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004544"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004545"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004546
4547static PyObject *
4548posix_waitpid(PyObject *self, PyObject *args)
4549{
4550 int pid, options;
4551 int status;
4552
4553 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4554 return NULL;
4555 Py_BEGIN_ALLOW_THREADS
4556 pid = _cwait(&status, pid, options);
4557 Py_END_ALLOW_THREADS
4558 if (pid == -1)
4559 return posix_error();
4560 else
4561 /* shift the status left a byte so this is more like the
4562 POSIX waitpid */
4563 return Py_BuildValue("ii", pid, status << 8);
4564}
4565#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004566
Guido van Rossumad0ee831995-03-01 10:34:45 +00004567#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004568PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004569"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004570Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004571
Barry Warsaw53699e91996-12-10 23:23:01 +00004572static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004573posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004574{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004575 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004576#ifdef UNION_WAIT
4577 union wait status;
4578#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004579#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004580 int status;
4581#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004582#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004583
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004584 status_i = 0;
4585 Py_BEGIN_ALLOW_THREADS
4586 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004587 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004588 if (pid == -1)
4589 return posix_error();
4590 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004591 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004592#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004593}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004594#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004595
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004596
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004597PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004598"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004599Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004600
Barry Warsaw53699e91996-12-10 23:23:01 +00004601static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004602posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004603{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004604#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004605 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004606#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004607#ifdef MS_WINDOWS
Mark Hammond7edd0a92003-08-06 02:46:58 +00004608 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", _wstati64);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004609#else
4610 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4611#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004612#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004613}
4614
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004615
Guido van Rossumb6775db1994-08-01 11:34:53 +00004616#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004617PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004618"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004619Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004620
Barry Warsaw53699e91996-12-10 23:23:01 +00004621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004622posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004623{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004624 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004625 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004626 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004627 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004628 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004629 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004630 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004631 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004632 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004633 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004634 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004635}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004636#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004638
Guido van Rossumb6775db1994-08-01 11:34:53 +00004639#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004640PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004641"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004642Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004643
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004645posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004646{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004647 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004648}
4649#endif /* HAVE_SYMLINK */
4650
4651
4652#ifdef HAVE_TIMES
4653#ifndef HZ
4654#define HZ 60 /* Universal constant :-) */
4655#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004656
Guido van Rossumd48f2521997-12-05 22:19:34 +00004657#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4658static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004659system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004660{
4661 ULONG value = 0;
4662
4663 Py_BEGIN_ALLOW_THREADS
4664 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4665 Py_END_ALLOW_THREADS
4666
4667 return value;
4668}
4669
4670static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004671posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004672{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004673 /* Currently Only Uptime is Provided -- Others Later */
4674 return Py_BuildValue("ddddd",
4675 (double)0 /* t.tms_utime / HZ */,
4676 (double)0 /* t.tms_stime / HZ */,
4677 (double)0 /* t.tms_cutime / HZ */,
4678 (double)0 /* t.tms_cstime / HZ */,
4679 (double)system_uptime() / 1000);
4680}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004681#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004682static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004683posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004684{
4685 struct tms t;
4686 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004687 errno = 0;
4688 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004689 if (c == (clock_t) -1)
4690 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004691 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004692 (double)t.tms_utime / HZ,
4693 (double)t.tms_stime / HZ,
4694 (double)t.tms_cutime / HZ,
4695 (double)t.tms_cstime / HZ,
4696 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004697}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004698#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004699#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004700
4701
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004702#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004703#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004704static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004705posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004706{
4707 FILETIME create, exit, kernel, user;
4708 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004709 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004710 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4711 /* The fields of a FILETIME structure are the hi and lo part
4712 of a 64-bit value expressed in 100 nanosecond units.
4713 1e7 is one second in such units; 1e-7 the inverse.
4714 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4715 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004716 return Py_BuildValue(
4717 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004718 (double)(kernel.dwHighDateTime*429.4967296 +
4719 kernel.dwLowDateTime*1e-7),
4720 (double)(user.dwHighDateTime*429.4967296 +
4721 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004722 (double)0,
4723 (double)0,
4724 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004725}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004726#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004727
4728#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004729PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004730"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004731Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004732#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004733
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004734
Guido van Rossumb6775db1994-08-01 11:34:53 +00004735#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004736PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004737"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004738Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004739
Barry Warsaw53699e91996-12-10 23:23:01 +00004740static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004741posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004742{
Guido van Rossum687dd131993-05-17 08:34:16 +00004743 if (setsid() < 0)
4744 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004745 Py_INCREF(Py_None);
4746 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004747}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004748#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004749
Guido van Rossumb6775db1994-08-01 11:34:53 +00004750#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004751PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004752"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004753Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004754
Barry Warsaw53699e91996-12-10 23:23:01 +00004755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004756posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004757{
4758 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004759 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004760 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004761 if (setpgid(pid, pgrp) < 0)
4762 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004763 Py_INCREF(Py_None);
4764 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004765}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004766#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004767
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004768
Guido van Rossumb6775db1994-08-01 11:34:53 +00004769#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004770PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004771"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004772Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004773
Barry Warsaw53699e91996-12-10 23:23:01 +00004774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004775posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004776{
4777 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004778 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004779 return NULL;
4780 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004781 if (pgid < 0)
4782 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004783 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004784}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004785#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004786
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004787
Guido van Rossumb6775db1994-08-01 11:34:53 +00004788#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004789PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004790"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004791Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004792
Barry Warsaw53699e91996-12-10 23:23:01 +00004793static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004794posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004795{
4796 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004797 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004798 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004799 if (tcsetpgrp(fd, pgid) < 0)
4800 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004801 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004802 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004803}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004804#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004805
Guido van Rossum687dd131993-05-17 08:34:16 +00004806/* Functions acting on file descriptors */
4807
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004808PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004809"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004810Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004811
Barry Warsaw53699e91996-12-10 23:23:01 +00004812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004813posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004814{
Mark Hammondef8b6542001-05-13 08:04:26 +00004815 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004816 int flag;
4817 int mode = 0777;
4818 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004819
4820#ifdef MS_WINDOWS
4821 if (unicode_file_names()) {
4822 PyUnicodeObject *po;
4823 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4824 Py_BEGIN_ALLOW_THREADS
4825 /* PyUnicode_AS_UNICODE OK without thread
4826 lock as it is a simple dereference. */
4827 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4828 Py_END_ALLOW_THREADS
4829 if (fd < 0)
4830 return posix_error();
4831 return PyInt_FromLong((long)fd);
4832 }
4833 /* Drop the argument parsing error as narrow strings
4834 are also valid. */
4835 PyErr_Clear();
4836 }
4837#endif
4838
Tim Peters5aa91602002-01-30 05:46:57 +00004839 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004840 Py_FileSystemDefaultEncoding, &file,
4841 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004842 return NULL;
4843
Barry Warsaw53699e91996-12-10 23:23:01 +00004844 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004845 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004846 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004847 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004848 return posix_error_with_allocated_filename(file);
4849 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004850 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004851}
4852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004853
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004854PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004855"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004856Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004857
Barry Warsaw53699e91996-12-10 23:23:01 +00004858static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004859posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004860{
4861 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004862 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004863 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004864 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004865 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004866 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004867 if (res < 0)
4868 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004869 Py_INCREF(Py_None);
4870 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004871}
4872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004873
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004874PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004875"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004876Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004877
Barry Warsaw53699e91996-12-10 23:23:01 +00004878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004879posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004880{
4881 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004882 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004883 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004884 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004885 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004886 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004887 if (fd < 0)
4888 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004889 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004890}
4891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004892
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004893PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004894"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004895Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004896
Barry Warsaw53699e91996-12-10 23:23:01 +00004897static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004898posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004899{
4900 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004901 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004902 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004903 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004904 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004905 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004906 if (res < 0)
4907 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004908 Py_INCREF(Py_None);
4909 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004910}
4911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004912
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004913PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004914"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004915Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004916
Barry Warsaw53699e91996-12-10 23:23:01 +00004917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004918posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004919{
4920 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004921#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004922 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004923#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004924 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004925#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004926 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004927 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004928 return NULL;
4929#ifdef SEEK_SET
4930 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4931 switch (how) {
4932 case 0: how = SEEK_SET; break;
4933 case 1: how = SEEK_CUR; break;
4934 case 2: how = SEEK_END; break;
4935 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004936#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004937
4938#if !defined(HAVE_LARGEFILE_SUPPORT)
4939 pos = PyInt_AsLong(posobj);
4940#else
4941 pos = PyLong_Check(posobj) ?
4942 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4943#endif
4944 if (PyErr_Occurred())
4945 return NULL;
4946
Barry Warsaw53699e91996-12-10 23:23:01 +00004947 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004948#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004949 res = _lseeki64(fd, pos, how);
4950#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004951 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004952#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004953 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004954 if (res < 0)
4955 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004956
4957#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004958 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004959#else
4960 return PyLong_FromLongLong(res);
4961#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004962}
4963
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004964
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004965PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004966"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004967Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004968
Barry Warsaw53699e91996-12-10 23:23:01 +00004969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004970posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004971{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004972 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004973 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004974 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004975 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004976 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004977 if (buffer == NULL)
4978 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004979 Py_BEGIN_ALLOW_THREADS
4980 n = read(fd, PyString_AsString(buffer), size);
4981 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004982 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004983 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004984 return posix_error();
4985 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004986 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004987 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004988 return buffer;
4989}
4990
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004991
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004992PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004993"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004994Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004995
Barry Warsaw53699e91996-12-10 23:23:01 +00004996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004997posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004998{
4999 int fd, size;
5000 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005001 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005002 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005003 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005004 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005005 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005006 if (size < 0)
5007 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005008 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005009}
5010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005011
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005012PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005013"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005015
Barry Warsaw53699e91996-12-10 23:23:01 +00005016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005017posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005018{
5019 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005020 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005021 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005022 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005023 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005024#ifdef __VMS
5025 /* on OpenVMS we must ensure that all bytes are written to the file */
5026 fsync(fd);
5027#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005028 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005029 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005030 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005031 if (res != 0)
5032 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005033
Fred Drake699f3522000-06-29 21:12:41 +00005034 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005035}
5036
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005037
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005038PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005039"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005040Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005041
Barry Warsaw53699e91996-12-10 23:23:01 +00005042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005043posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005044{
Guido van Rossum687dd131993-05-17 08:34:16 +00005045 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005046 char *mode = "r";
5047 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005048 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005049 PyObject *f;
5050 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005051 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005052
Thomas Heller1f043e22002-11-07 16:00:59 +00005053 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5054 PyErr_Format(PyExc_ValueError,
5055 "invalid file mode '%s'", mode);
5056 return NULL;
5057 }
5058
Barry Warsaw53699e91996-12-10 23:23:01 +00005059 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005060 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005061 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005062 if (fp == NULL)
5063 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005064 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005065 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005066 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005067 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005068}
5069
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005070PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005071"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005072Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005073connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005074
5075static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005076posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005077{
5078 int fd;
5079 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5080 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005081 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005082}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005083
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005084#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005085PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005086"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005087Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005088
Barry Warsaw53699e91996-12-10 23:23:01 +00005089static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005090posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005091{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005092#if defined(PYOS_OS2)
5093 HFILE read, write;
5094 APIRET rc;
5095
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005096 Py_BEGIN_ALLOW_THREADS
5097 rc = DosCreatePipe( &read, &write, 4096);
5098 Py_END_ALLOW_THREADS
5099 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005100 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005101
5102 return Py_BuildValue("(ii)", read, write);
5103#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005104#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005105 int fds[2];
5106 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005107 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005108 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005109 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005110 if (res != 0)
5111 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005112 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005113#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005114 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005115 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005116 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005117 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005118 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005119 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005120 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005121 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005122 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5123 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005124 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005125#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005126#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005127}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005128#endif /* HAVE_PIPE */
5129
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005130
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005131#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005132PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005133"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005134Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005135
Barry Warsaw53699e91996-12-10 23:23:01 +00005136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005137posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005138{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005139 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005140 int mode = 0666;
5141 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005142 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005143 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005144 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005145 res = mkfifo(filename, mode);
5146 Py_END_ALLOW_THREADS
5147 if (res < 0)
5148 return posix_error();
5149 Py_INCREF(Py_None);
5150 return Py_None;
5151}
5152#endif
5153
5154
Neal Norwitz11690112002-07-30 01:08:28 +00005155#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005156PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005157"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005158Create a filesystem node (file, device special file or named pipe)\n\
5159named filename. mode specifies both the permissions to use and the\n\
5160type of node to be created, being combined (bitwise OR) with one of\n\
5161S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005162device defines the newly created device special file (probably using\n\
5163os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005164
5165
5166static PyObject *
5167posix_mknod(PyObject *self, PyObject *args)
5168{
5169 char *filename;
5170 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005171 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005172 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005173 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005174 return NULL;
5175 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005176 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005177 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005178 if (res < 0)
5179 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005180 Py_INCREF(Py_None);
5181 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005182}
5183#endif
5184
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005185#ifdef HAVE_DEVICE_MACROS
5186PyDoc_STRVAR(posix_major__doc__,
5187"major(device) -> major number\n\
5188Extracts a device major number from a raw device number.");
5189
5190static PyObject *
5191posix_major(PyObject *self, PyObject *args)
5192{
5193 int device;
5194 if (!PyArg_ParseTuple(args, "i:major", &device))
5195 return NULL;
5196 return PyInt_FromLong((long)major(device));
5197}
5198
5199PyDoc_STRVAR(posix_minor__doc__,
5200"minor(device) -> minor number\n\
5201Extracts a device minor number from a raw device number.");
5202
5203static PyObject *
5204posix_minor(PyObject *self, PyObject *args)
5205{
5206 int device;
5207 if (!PyArg_ParseTuple(args, "i:minor", &device))
5208 return NULL;
5209 return PyInt_FromLong((long)minor(device));
5210}
5211
5212PyDoc_STRVAR(posix_makedev__doc__,
5213"makedev(major, minor) -> device number\n\
5214Composes a raw device number from the major and minor device numbers.");
5215
5216static PyObject *
5217posix_makedev(PyObject *self, PyObject *args)
5218{
5219 int major, minor;
5220 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5221 return NULL;
5222 return PyInt_FromLong((long)makedev(major, minor));
5223}
5224#endif /* device macros */
5225
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005226
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005227#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005228PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005229"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005230Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005231
Barry Warsaw53699e91996-12-10 23:23:01 +00005232static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005233posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005234{
5235 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005236 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005237 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005238 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005239
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005240 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005241 return NULL;
5242
5243#if !defined(HAVE_LARGEFILE_SUPPORT)
5244 length = PyInt_AsLong(lenobj);
5245#else
5246 length = PyLong_Check(lenobj) ?
5247 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5248#endif
5249 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005250 return NULL;
5251
Barry Warsaw53699e91996-12-10 23:23:01 +00005252 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005253 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005254 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005255 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005256 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005257 return NULL;
5258 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005259 Py_INCREF(Py_None);
5260 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005261}
5262#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005263
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005264#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005265PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005266"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005267Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005268
Fred Drake762e2061999-08-26 17:23:54 +00005269/* Save putenv() parameters as values here, so we can collect them when they
5270 * get re-set with another call for the same key. */
5271static PyObject *posix_putenv_garbage;
5272
Tim Peters5aa91602002-01-30 05:46:57 +00005273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005274posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005275{
5276 char *s1, *s2;
5277 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005278 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005279 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005280
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005281 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005282 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005283
5284#if defined(PYOS_OS2)
5285 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5286 APIRET rc;
5287
Guido van Rossumd48f2521997-12-05 22:19:34 +00005288 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5289 if (rc != NO_ERROR)
5290 return os2_error(rc);
5291
5292 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5293 APIRET rc;
5294
Guido van Rossumd48f2521997-12-05 22:19:34 +00005295 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5296 if (rc != NO_ERROR)
5297 return os2_error(rc);
5298 } else {
5299#endif
5300
Fred Drake762e2061999-08-26 17:23:54 +00005301 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005302 len = strlen(s1) + strlen(s2) + 2;
5303 /* len includes space for a trailing \0; the size arg to
5304 PyString_FromStringAndSize does not count that */
5305 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005306 if (newstr == NULL)
5307 return PyErr_NoMemory();
5308 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005309 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005310 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005311 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005312 posix_error();
5313 return NULL;
5314 }
Fred Drake762e2061999-08-26 17:23:54 +00005315 /* Install the first arg and newstr in posix_putenv_garbage;
5316 * this will cause previous value to be collected. This has to
5317 * happen after the real putenv() call because the old value
5318 * was still accessible until then. */
5319 if (PyDict_SetItem(posix_putenv_garbage,
5320 PyTuple_GET_ITEM(args, 0), newstr)) {
5321 /* really not much we can do; just leak */
5322 PyErr_Clear();
5323 }
5324 else {
5325 Py_DECREF(newstr);
5326 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005327
5328#if defined(PYOS_OS2)
5329 }
5330#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005331 Py_INCREF(Py_None);
5332 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005333}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005334#endif /* putenv */
5335
Guido van Rossumc524d952001-10-19 01:31:59 +00005336#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005337PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005338"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005339Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005340
5341static PyObject *
5342posix_unsetenv(PyObject *self, PyObject *args)
5343{
5344 char *s1;
5345
5346 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5347 return NULL;
5348
5349 unsetenv(s1);
5350
5351 /* Remove the key from posix_putenv_garbage;
5352 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005353 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005354 * old value was still accessible until then.
5355 */
5356 if (PyDict_DelItem(posix_putenv_garbage,
5357 PyTuple_GET_ITEM(args, 0))) {
5358 /* really not much we can do; just leak */
5359 PyErr_Clear();
5360 }
5361
5362 Py_INCREF(Py_None);
5363 return Py_None;
5364}
5365#endif /* unsetenv */
5366
Guido van Rossumb6a47161997-09-15 22:54:34 +00005367#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005368PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005369"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005370Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005371
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005373posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005374{
5375 int code;
5376 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005377 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005378 return NULL;
5379 message = strerror(code);
5380 if (message == NULL) {
5381 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005382 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005383 return NULL;
5384 }
5385 return PyString_FromString(message);
5386}
5387#endif /* strerror */
5388
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005389
Guido van Rossumc9641791998-08-04 15:26:23 +00005390#ifdef HAVE_SYS_WAIT_H
5391
Fred Drake106c1a02002-04-23 15:58:02 +00005392#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005393PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005394"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005395Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005396
5397static PyObject *
5398posix_WCOREDUMP(PyObject *self, PyObject *args)
5399{
5400#ifdef UNION_WAIT
5401 union wait status;
5402#define status_i (status.w_status)
5403#else
5404 int status;
5405#define status_i status
5406#endif
5407 status_i = 0;
5408
5409 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5410 {
5411 return NULL;
5412 }
5413
5414 return PyBool_FromLong(WCOREDUMP(status));
5415#undef status_i
5416}
5417#endif /* WCOREDUMP */
5418
5419#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005420PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005421"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005422Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005423job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005424
5425static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005426posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005427{
5428#ifdef UNION_WAIT
5429 union wait status;
5430#define status_i (status.w_status)
5431#else
5432 int status;
5433#define status_i status
5434#endif
5435 status_i = 0;
5436
5437 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5438 {
5439 return NULL;
5440 }
5441
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005442 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005443#undef status_i
5444}
5445#endif /* WIFCONTINUED */
5446
Guido van Rossumc9641791998-08-04 15:26:23 +00005447#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005448PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005449"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005450Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005451
5452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005453posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005454{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005455#ifdef UNION_WAIT
5456 union wait status;
5457#define status_i (status.w_status)
5458#else
5459 int status;
5460#define status_i status
5461#endif
5462 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005463
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005464 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005465 {
5466 return NULL;
5467 }
Tim Peters5aa91602002-01-30 05:46:57 +00005468
Fred Drake106c1a02002-04-23 15:58:02 +00005469 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005470#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005471}
5472#endif /* WIFSTOPPED */
5473
5474#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005475PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005476"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005477Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005478
5479static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005480posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005481{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005482#ifdef UNION_WAIT
5483 union wait status;
5484#define status_i (status.w_status)
5485#else
5486 int status;
5487#define status_i status
5488#endif
5489 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005490
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005491 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005492 {
5493 return NULL;
5494 }
Tim Peters5aa91602002-01-30 05:46:57 +00005495
Fred Drake106c1a02002-04-23 15:58:02 +00005496 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005497#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005498}
5499#endif /* WIFSIGNALED */
5500
5501#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005502PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005503"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005504Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005505system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005506
5507static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005508posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005509{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005510#ifdef UNION_WAIT
5511 union wait status;
5512#define status_i (status.w_status)
5513#else
5514 int status;
5515#define status_i status
5516#endif
5517 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005518
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005519 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005520 {
5521 return NULL;
5522 }
Tim Peters5aa91602002-01-30 05:46:57 +00005523
Fred Drake106c1a02002-04-23 15:58:02 +00005524 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005525#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005526}
5527#endif /* WIFEXITED */
5528
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005529#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005530PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005531"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005532Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005533
5534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005535posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005536{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005537#ifdef UNION_WAIT
5538 union wait status;
5539#define status_i (status.w_status)
5540#else
5541 int status;
5542#define status_i status
5543#endif
5544 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005545
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005546 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005547 {
5548 return NULL;
5549 }
Tim Peters5aa91602002-01-30 05:46:57 +00005550
Guido van Rossumc9641791998-08-04 15:26:23 +00005551 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005552#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005553}
5554#endif /* WEXITSTATUS */
5555
5556#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005557PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005558"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005559Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005560value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005561
5562static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005563posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005564{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005565#ifdef UNION_WAIT
5566 union wait status;
5567#define status_i (status.w_status)
5568#else
5569 int status;
5570#define status_i status
5571#endif
5572 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005573
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005574 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005575 {
5576 return NULL;
5577 }
Tim Peters5aa91602002-01-30 05:46:57 +00005578
Guido van Rossumc9641791998-08-04 15:26:23 +00005579 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005580#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005581}
5582#endif /* WTERMSIG */
5583
5584#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005585PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005586"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005587Return the signal that stopped the process that provided\n\
5588the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005589
5590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005591posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005592{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005593#ifdef UNION_WAIT
5594 union wait status;
5595#define status_i (status.w_status)
5596#else
5597 int status;
5598#define status_i status
5599#endif
5600 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005601
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005602 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005603 {
5604 return NULL;
5605 }
Tim Peters5aa91602002-01-30 05:46:57 +00005606
Guido van Rossumc9641791998-08-04 15:26:23 +00005607 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005608#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005609}
5610#endif /* WSTOPSIG */
5611
5612#endif /* HAVE_SYS_WAIT_H */
5613
5614
Guido van Rossum94f6f721999-01-06 18:42:14 +00005615#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005616#ifdef _SCO_DS
5617/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5618 needed definitions in sys/statvfs.h */
5619#define _SVID3
5620#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005621#include <sys/statvfs.h>
5622
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005623static PyObject*
5624_pystatvfs_fromstructstatvfs(struct statvfs st) {
5625 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5626 if (v == NULL)
5627 return NULL;
5628
5629#if !defined(HAVE_LARGEFILE_SUPPORT)
5630 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5631 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5632 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5633 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5634 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5635 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5636 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5637 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5638 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5639 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5640#else
5641 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5642 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005643 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005644 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005645 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005646 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005647 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005648 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005649 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005650 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005651 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005652 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005653 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005654 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005655 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5656 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5657#endif
5658
5659 return v;
5660}
5661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005662PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005663"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005664Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005665
5666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005667posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005668{
5669 int fd, res;
5670 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005671
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005672 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005673 return NULL;
5674 Py_BEGIN_ALLOW_THREADS
5675 res = fstatvfs(fd, &st);
5676 Py_END_ALLOW_THREADS
5677 if (res != 0)
5678 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005679
5680 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005681}
5682#endif /* HAVE_FSTATVFS */
5683
5684
5685#if defined(HAVE_STATVFS)
5686#include <sys/statvfs.h>
5687
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005689"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005691
5692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005693posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005694{
5695 char *path;
5696 int res;
5697 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005698 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005699 return NULL;
5700 Py_BEGIN_ALLOW_THREADS
5701 res = statvfs(path, &st);
5702 Py_END_ALLOW_THREADS
5703 if (res != 0)
5704 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005705
5706 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005707}
5708#endif /* HAVE_STATVFS */
5709
5710
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005711#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005712PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005713"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005714Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005715The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005716or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005717
5718static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005719posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005720{
5721 PyObject *result = NULL;
5722 char *dir = NULL;
5723 char *pfx = NULL;
5724 char *name;
5725
5726 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5727 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005728
5729 if (PyErr_Warn(PyExc_RuntimeWarning,
5730 "tempnam is a potential security risk to your program") < 0)
5731 return NULL;
5732
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005733#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005734 name = _tempnam(dir, pfx);
5735#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005736 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005737#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005738 if (name == NULL)
5739 return PyErr_NoMemory();
5740 result = PyString_FromString(name);
5741 free(name);
5742 return result;
5743}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005744#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005745
5746
5747#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005748PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005749"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005750Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005751
5752static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005753posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005754{
5755 FILE *fp;
5756
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005757 fp = tmpfile();
5758 if (fp == NULL)
5759 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005760 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005761}
5762#endif
5763
5764
5765#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005766PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005767"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005768Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005769
5770static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005771posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005772{
5773 char buffer[L_tmpnam];
5774 char *name;
5775
Skip Montanaro95618b52001-08-18 18:52:10 +00005776 if (PyErr_Warn(PyExc_RuntimeWarning,
5777 "tmpnam is a potential security risk to your program") < 0)
5778 return NULL;
5779
Greg Wardb48bc172000-03-01 21:51:56 +00005780#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005781 name = tmpnam_r(buffer);
5782#else
5783 name = tmpnam(buffer);
5784#endif
5785 if (name == NULL) {
5786 PyErr_SetObject(PyExc_OSError,
5787 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005788#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005789 "unexpected NULL from tmpnam_r"
5790#else
5791 "unexpected NULL from tmpnam"
5792#endif
5793 ));
5794 return NULL;
5795 }
5796 return PyString_FromString(buffer);
5797}
5798#endif
5799
5800
Fred Drakec9680921999-12-13 16:37:25 +00005801/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5802 * It maps strings representing configuration variable names to
5803 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005804 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005805 * rarely-used constants. There are three separate tables that use
5806 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005807 *
5808 * This code is always included, even if none of the interfaces that
5809 * need it are included. The #if hackery needed to avoid it would be
5810 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005811 */
5812struct constdef {
5813 char *name;
5814 long value;
5815};
5816
Fred Drake12c6e2d1999-12-14 21:25:03 +00005817static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005818conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5819 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005820{
5821 if (PyInt_Check(arg)) {
5822 *valuep = PyInt_AS_LONG(arg);
5823 return 1;
5824 }
5825 if (PyString_Check(arg)) {
5826 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005827 size_t lo = 0;
5828 size_t mid;
5829 size_t hi = tablesize;
5830 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005831 char *confname = PyString_AS_STRING(arg);
5832 while (lo < hi) {
5833 mid = (lo + hi) / 2;
5834 cmp = strcmp(confname, table[mid].name);
5835 if (cmp < 0)
5836 hi = mid;
5837 else if (cmp > 0)
5838 lo = mid + 1;
5839 else {
5840 *valuep = table[mid].value;
5841 return 1;
5842 }
5843 }
5844 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5845 }
5846 else
5847 PyErr_SetString(PyExc_TypeError,
5848 "configuration names must be strings or integers");
5849 return 0;
5850}
5851
5852
5853#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5854static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005855#ifdef _PC_ABI_AIO_XFER_MAX
5856 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5857#endif
5858#ifdef _PC_ABI_ASYNC_IO
5859 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5860#endif
Fred Drakec9680921999-12-13 16:37:25 +00005861#ifdef _PC_ASYNC_IO
5862 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5863#endif
5864#ifdef _PC_CHOWN_RESTRICTED
5865 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5866#endif
5867#ifdef _PC_FILESIZEBITS
5868 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5869#endif
5870#ifdef _PC_LAST
5871 {"PC_LAST", _PC_LAST},
5872#endif
5873#ifdef _PC_LINK_MAX
5874 {"PC_LINK_MAX", _PC_LINK_MAX},
5875#endif
5876#ifdef _PC_MAX_CANON
5877 {"PC_MAX_CANON", _PC_MAX_CANON},
5878#endif
5879#ifdef _PC_MAX_INPUT
5880 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5881#endif
5882#ifdef _PC_NAME_MAX
5883 {"PC_NAME_MAX", _PC_NAME_MAX},
5884#endif
5885#ifdef _PC_NO_TRUNC
5886 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5887#endif
5888#ifdef _PC_PATH_MAX
5889 {"PC_PATH_MAX", _PC_PATH_MAX},
5890#endif
5891#ifdef _PC_PIPE_BUF
5892 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5893#endif
5894#ifdef _PC_PRIO_IO
5895 {"PC_PRIO_IO", _PC_PRIO_IO},
5896#endif
5897#ifdef _PC_SOCK_MAXBUF
5898 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5899#endif
5900#ifdef _PC_SYNC_IO
5901 {"PC_SYNC_IO", _PC_SYNC_IO},
5902#endif
5903#ifdef _PC_VDISABLE
5904 {"PC_VDISABLE", _PC_VDISABLE},
5905#endif
5906};
5907
Fred Drakec9680921999-12-13 16:37:25 +00005908static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005909conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005910{
5911 return conv_confname(arg, valuep, posix_constants_pathconf,
5912 sizeof(posix_constants_pathconf)
5913 / sizeof(struct constdef));
5914}
5915#endif
5916
5917#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005918PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005919"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005920Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005921If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005922
5923static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005924posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005925{
5926 PyObject *result = NULL;
5927 int name, fd;
5928
Fred Drake12c6e2d1999-12-14 21:25:03 +00005929 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5930 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005931 long limit;
5932
5933 errno = 0;
5934 limit = fpathconf(fd, name);
5935 if (limit == -1 && errno != 0)
5936 posix_error();
5937 else
5938 result = PyInt_FromLong(limit);
5939 }
5940 return result;
5941}
5942#endif
5943
5944
5945#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005946PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005947"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005948Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005949If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005950
5951static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005952posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005953{
5954 PyObject *result = NULL;
5955 int name;
5956 char *path;
5957
5958 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5959 conv_path_confname, &name)) {
5960 long limit;
5961
5962 errno = 0;
5963 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005964 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005965 if (errno == EINVAL)
5966 /* could be a path or name problem */
5967 posix_error();
5968 else
5969 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005970 }
Fred Drakec9680921999-12-13 16:37:25 +00005971 else
5972 result = PyInt_FromLong(limit);
5973 }
5974 return result;
5975}
5976#endif
5977
5978#ifdef HAVE_CONFSTR
5979static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005980#ifdef _CS_ARCHITECTURE
5981 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5982#endif
5983#ifdef _CS_HOSTNAME
5984 {"CS_HOSTNAME", _CS_HOSTNAME},
5985#endif
5986#ifdef _CS_HW_PROVIDER
5987 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5988#endif
5989#ifdef _CS_HW_SERIAL
5990 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5991#endif
5992#ifdef _CS_INITTAB_NAME
5993 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5994#endif
Fred Drakec9680921999-12-13 16:37:25 +00005995#ifdef _CS_LFS64_CFLAGS
5996 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5997#endif
5998#ifdef _CS_LFS64_LDFLAGS
5999 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6000#endif
6001#ifdef _CS_LFS64_LIBS
6002 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6003#endif
6004#ifdef _CS_LFS64_LINTFLAGS
6005 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6006#endif
6007#ifdef _CS_LFS_CFLAGS
6008 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6009#endif
6010#ifdef _CS_LFS_LDFLAGS
6011 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6012#endif
6013#ifdef _CS_LFS_LIBS
6014 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6015#endif
6016#ifdef _CS_LFS_LINTFLAGS
6017 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6018#endif
Fred Draked86ed291999-12-15 15:34:33 +00006019#ifdef _CS_MACHINE
6020 {"CS_MACHINE", _CS_MACHINE},
6021#endif
Fred Drakec9680921999-12-13 16:37:25 +00006022#ifdef _CS_PATH
6023 {"CS_PATH", _CS_PATH},
6024#endif
Fred Draked86ed291999-12-15 15:34:33 +00006025#ifdef _CS_RELEASE
6026 {"CS_RELEASE", _CS_RELEASE},
6027#endif
6028#ifdef _CS_SRPC_DOMAIN
6029 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6030#endif
6031#ifdef _CS_SYSNAME
6032 {"CS_SYSNAME", _CS_SYSNAME},
6033#endif
6034#ifdef _CS_VERSION
6035 {"CS_VERSION", _CS_VERSION},
6036#endif
Fred Drakec9680921999-12-13 16:37:25 +00006037#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6038 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6039#endif
6040#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6041 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6042#endif
6043#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6044 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6045#endif
6046#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6047 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6048#endif
6049#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6050 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6051#endif
6052#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6053 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6054#endif
6055#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6056 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6057#endif
6058#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6059 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6060#endif
6061#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6062 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6063#endif
6064#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6065 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6066#endif
6067#ifdef _CS_XBS5_LP64_OFF64_LIBS
6068 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6069#endif
6070#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6071 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6072#endif
6073#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6074 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6075#endif
6076#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6077 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6078#endif
6079#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6080 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6081#endif
6082#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6083 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6084#endif
Fred Draked86ed291999-12-15 15:34:33 +00006085#ifdef _MIPS_CS_AVAIL_PROCESSORS
6086 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6087#endif
6088#ifdef _MIPS_CS_BASE
6089 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6090#endif
6091#ifdef _MIPS_CS_HOSTID
6092 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6093#endif
6094#ifdef _MIPS_CS_HW_NAME
6095 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6096#endif
6097#ifdef _MIPS_CS_NUM_PROCESSORS
6098 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6099#endif
6100#ifdef _MIPS_CS_OSREL_MAJ
6101 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6102#endif
6103#ifdef _MIPS_CS_OSREL_MIN
6104 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6105#endif
6106#ifdef _MIPS_CS_OSREL_PATCH
6107 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6108#endif
6109#ifdef _MIPS_CS_OS_NAME
6110 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6111#endif
6112#ifdef _MIPS_CS_OS_PROVIDER
6113 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6114#endif
6115#ifdef _MIPS_CS_PROCESSORS
6116 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6117#endif
6118#ifdef _MIPS_CS_SERIAL
6119 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6120#endif
6121#ifdef _MIPS_CS_VENDOR
6122 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6123#endif
Fred Drakec9680921999-12-13 16:37:25 +00006124};
6125
6126static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006127conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006128{
6129 return conv_confname(arg, valuep, posix_constants_confstr,
6130 sizeof(posix_constants_confstr)
6131 / sizeof(struct constdef));
6132}
6133
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006134PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006135"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006137
6138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006139posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006140{
6141 PyObject *result = NULL;
6142 int name;
6143 char buffer[64];
6144
6145 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6146 int len = confstr(name, buffer, sizeof(buffer));
6147
Fred Drakec9680921999-12-13 16:37:25 +00006148 errno = 0;
6149 if (len == 0) {
6150 if (errno != 0)
6151 posix_error();
6152 else
6153 result = PyString_FromString("");
6154 }
6155 else {
6156 if (len >= sizeof(buffer)) {
6157 result = PyString_FromStringAndSize(NULL, len);
6158 if (result != NULL)
6159 confstr(name, PyString_AS_STRING(result), len+1);
6160 }
6161 else
6162 result = PyString_FromString(buffer);
6163 }
6164 }
6165 return result;
6166}
6167#endif
6168
6169
6170#ifdef HAVE_SYSCONF
6171static struct constdef posix_constants_sysconf[] = {
6172#ifdef _SC_2_CHAR_TERM
6173 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6174#endif
6175#ifdef _SC_2_C_BIND
6176 {"SC_2_C_BIND", _SC_2_C_BIND},
6177#endif
6178#ifdef _SC_2_C_DEV
6179 {"SC_2_C_DEV", _SC_2_C_DEV},
6180#endif
6181#ifdef _SC_2_C_VERSION
6182 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6183#endif
6184#ifdef _SC_2_FORT_DEV
6185 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6186#endif
6187#ifdef _SC_2_FORT_RUN
6188 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6189#endif
6190#ifdef _SC_2_LOCALEDEF
6191 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6192#endif
6193#ifdef _SC_2_SW_DEV
6194 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6195#endif
6196#ifdef _SC_2_UPE
6197 {"SC_2_UPE", _SC_2_UPE},
6198#endif
6199#ifdef _SC_2_VERSION
6200 {"SC_2_VERSION", _SC_2_VERSION},
6201#endif
Fred Draked86ed291999-12-15 15:34:33 +00006202#ifdef _SC_ABI_ASYNCHRONOUS_IO
6203 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6204#endif
6205#ifdef _SC_ACL
6206 {"SC_ACL", _SC_ACL},
6207#endif
Fred Drakec9680921999-12-13 16:37:25 +00006208#ifdef _SC_AIO_LISTIO_MAX
6209 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6210#endif
Fred Drakec9680921999-12-13 16:37:25 +00006211#ifdef _SC_AIO_MAX
6212 {"SC_AIO_MAX", _SC_AIO_MAX},
6213#endif
6214#ifdef _SC_AIO_PRIO_DELTA_MAX
6215 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6216#endif
6217#ifdef _SC_ARG_MAX
6218 {"SC_ARG_MAX", _SC_ARG_MAX},
6219#endif
6220#ifdef _SC_ASYNCHRONOUS_IO
6221 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6222#endif
6223#ifdef _SC_ATEXIT_MAX
6224 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6225#endif
Fred Draked86ed291999-12-15 15:34:33 +00006226#ifdef _SC_AUDIT
6227 {"SC_AUDIT", _SC_AUDIT},
6228#endif
Fred Drakec9680921999-12-13 16:37:25 +00006229#ifdef _SC_AVPHYS_PAGES
6230 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6231#endif
6232#ifdef _SC_BC_BASE_MAX
6233 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6234#endif
6235#ifdef _SC_BC_DIM_MAX
6236 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6237#endif
6238#ifdef _SC_BC_SCALE_MAX
6239 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6240#endif
6241#ifdef _SC_BC_STRING_MAX
6242 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6243#endif
Fred Draked86ed291999-12-15 15:34:33 +00006244#ifdef _SC_CAP
6245 {"SC_CAP", _SC_CAP},
6246#endif
Fred Drakec9680921999-12-13 16:37:25 +00006247#ifdef _SC_CHARCLASS_NAME_MAX
6248 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6249#endif
6250#ifdef _SC_CHAR_BIT
6251 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6252#endif
6253#ifdef _SC_CHAR_MAX
6254 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6255#endif
6256#ifdef _SC_CHAR_MIN
6257 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6258#endif
6259#ifdef _SC_CHILD_MAX
6260 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6261#endif
6262#ifdef _SC_CLK_TCK
6263 {"SC_CLK_TCK", _SC_CLK_TCK},
6264#endif
6265#ifdef _SC_COHER_BLKSZ
6266 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6267#endif
6268#ifdef _SC_COLL_WEIGHTS_MAX
6269 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6270#endif
6271#ifdef _SC_DCACHE_ASSOC
6272 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6273#endif
6274#ifdef _SC_DCACHE_BLKSZ
6275 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6276#endif
6277#ifdef _SC_DCACHE_LINESZ
6278 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6279#endif
6280#ifdef _SC_DCACHE_SZ
6281 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6282#endif
6283#ifdef _SC_DCACHE_TBLKSZ
6284 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6285#endif
6286#ifdef _SC_DELAYTIMER_MAX
6287 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6288#endif
6289#ifdef _SC_EQUIV_CLASS_MAX
6290 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6291#endif
6292#ifdef _SC_EXPR_NEST_MAX
6293 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6294#endif
6295#ifdef _SC_FSYNC
6296 {"SC_FSYNC", _SC_FSYNC},
6297#endif
6298#ifdef _SC_GETGR_R_SIZE_MAX
6299 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6300#endif
6301#ifdef _SC_GETPW_R_SIZE_MAX
6302 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6303#endif
6304#ifdef _SC_ICACHE_ASSOC
6305 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6306#endif
6307#ifdef _SC_ICACHE_BLKSZ
6308 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6309#endif
6310#ifdef _SC_ICACHE_LINESZ
6311 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6312#endif
6313#ifdef _SC_ICACHE_SZ
6314 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6315#endif
Fred Draked86ed291999-12-15 15:34:33 +00006316#ifdef _SC_INF
6317 {"SC_INF", _SC_INF},
6318#endif
Fred Drakec9680921999-12-13 16:37:25 +00006319#ifdef _SC_INT_MAX
6320 {"SC_INT_MAX", _SC_INT_MAX},
6321#endif
6322#ifdef _SC_INT_MIN
6323 {"SC_INT_MIN", _SC_INT_MIN},
6324#endif
6325#ifdef _SC_IOV_MAX
6326 {"SC_IOV_MAX", _SC_IOV_MAX},
6327#endif
Fred Draked86ed291999-12-15 15:34:33 +00006328#ifdef _SC_IP_SECOPTS
6329 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6330#endif
Fred Drakec9680921999-12-13 16:37:25 +00006331#ifdef _SC_JOB_CONTROL
6332 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6333#endif
Fred Draked86ed291999-12-15 15:34:33 +00006334#ifdef _SC_KERN_POINTERS
6335 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6336#endif
6337#ifdef _SC_KERN_SIM
6338 {"SC_KERN_SIM", _SC_KERN_SIM},
6339#endif
Fred Drakec9680921999-12-13 16:37:25 +00006340#ifdef _SC_LINE_MAX
6341 {"SC_LINE_MAX", _SC_LINE_MAX},
6342#endif
6343#ifdef _SC_LOGIN_NAME_MAX
6344 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6345#endif
6346#ifdef _SC_LOGNAME_MAX
6347 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6348#endif
6349#ifdef _SC_LONG_BIT
6350 {"SC_LONG_BIT", _SC_LONG_BIT},
6351#endif
Fred Draked86ed291999-12-15 15:34:33 +00006352#ifdef _SC_MAC
6353 {"SC_MAC", _SC_MAC},
6354#endif
Fred Drakec9680921999-12-13 16:37:25 +00006355#ifdef _SC_MAPPED_FILES
6356 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6357#endif
6358#ifdef _SC_MAXPID
6359 {"SC_MAXPID", _SC_MAXPID},
6360#endif
6361#ifdef _SC_MB_LEN_MAX
6362 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6363#endif
6364#ifdef _SC_MEMLOCK
6365 {"SC_MEMLOCK", _SC_MEMLOCK},
6366#endif
6367#ifdef _SC_MEMLOCK_RANGE
6368 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6369#endif
6370#ifdef _SC_MEMORY_PROTECTION
6371 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6372#endif
6373#ifdef _SC_MESSAGE_PASSING
6374 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6375#endif
Fred Draked86ed291999-12-15 15:34:33 +00006376#ifdef _SC_MMAP_FIXED_ALIGNMENT
6377 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6378#endif
Fred Drakec9680921999-12-13 16:37:25 +00006379#ifdef _SC_MQ_OPEN_MAX
6380 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6381#endif
6382#ifdef _SC_MQ_PRIO_MAX
6383 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6384#endif
Fred Draked86ed291999-12-15 15:34:33 +00006385#ifdef _SC_NACLS_MAX
6386 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6387#endif
Fred Drakec9680921999-12-13 16:37:25 +00006388#ifdef _SC_NGROUPS_MAX
6389 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6390#endif
6391#ifdef _SC_NL_ARGMAX
6392 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6393#endif
6394#ifdef _SC_NL_LANGMAX
6395 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6396#endif
6397#ifdef _SC_NL_MSGMAX
6398 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6399#endif
6400#ifdef _SC_NL_NMAX
6401 {"SC_NL_NMAX", _SC_NL_NMAX},
6402#endif
6403#ifdef _SC_NL_SETMAX
6404 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6405#endif
6406#ifdef _SC_NL_TEXTMAX
6407 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6408#endif
6409#ifdef _SC_NPROCESSORS_CONF
6410 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6411#endif
6412#ifdef _SC_NPROCESSORS_ONLN
6413 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6414#endif
Fred Draked86ed291999-12-15 15:34:33 +00006415#ifdef _SC_NPROC_CONF
6416 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6417#endif
6418#ifdef _SC_NPROC_ONLN
6419 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6420#endif
Fred Drakec9680921999-12-13 16:37:25 +00006421#ifdef _SC_NZERO
6422 {"SC_NZERO", _SC_NZERO},
6423#endif
6424#ifdef _SC_OPEN_MAX
6425 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6426#endif
6427#ifdef _SC_PAGESIZE
6428 {"SC_PAGESIZE", _SC_PAGESIZE},
6429#endif
6430#ifdef _SC_PAGE_SIZE
6431 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6432#endif
6433#ifdef _SC_PASS_MAX
6434 {"SC_PASS_MAX", _SC_PASS_MAX},
6435#endif
6436#ifdef _SC_PHYS_PAGES
6437 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6438#endif
6439#ifdef _SC_PII
6440 {"SC_PII", _SC_PII},
6441#endif
6442#ifdef _SC_PII_INTERNET
6443 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6444#endif
6445#ifdef _SC_PII_INTERNET_DGRAM
6446 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6447#endif
6448#ifdef _SC_PII_INTERNET_STREAM
6449 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6450#endif
6451#ifdef _SC_PII_OSI
6452 {"SC_PII_OSI", _SC_PII_OSI},
6453#endif
6454#ifdef _SC_PII_OSI_CLTS
6455 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6456#endif
6457#ifdef _SC_PII_OSI_COTS
6458 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6459#endif
6460#ifdef _SC_PII_OSI_M
6461 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6462#endif
6463#ifdef _SC_PII_SOCKET
6464 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6465#endif
6466#ifdef _SC_PII_XTI
6467 {"SC_PII_XTI", _SC_PII_XTI},
6468#endif
6469#ifdef _SC_POLL
6470 {"SC_POLL", _SC_POLL},
6471#endif
6472#ifdef _SC_PRIORITIZED_IO
6473 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6474#endif
6475#ifdef _SC_PRIORITY_SCHEDULING
6476 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6477#endif
6478#ifdef _SC_REALTIME_SIGNALS
6479 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6480#endif
6481#ifdef _SC_RE_DUP_MAX
6482 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6483#endif
6484#ifdef _SC_RTSIG_MAX
6485 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6486#endif
6487#ifdef _SC_SAVED_IDS
6488 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6489#endif
6490#ifdef _SC_SCHAR_MAX
6491 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6492#endif
6493#ifdef _SC_SCHAR_MIN
6494 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6495#endif
6496#ifdef _SC_SELECT
6497 {"SC_SELECT", _SC_SELECT},
6498#endif
6499#ifdef _SC_SEMAPHORES
6500 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6501#endif
6502#ifdef _SC_SEM_NSEMS_MAX
6503 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6504#endif
6505#ifdef _SC_SEM_VALUE_MAX
6506 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6507#endif
6508#ifdef _SC_SHARED_MEMORY_OBJECTS
6509 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6510#endif
6511#ifdef _SC_SHRT_MAX
6512 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6513#endif
6514#ifdef _SC_SHRT_MIN
6515 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6516#endif
6517#ifdef _SC_SIGQUEUE_MAX
6518 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6519#endif
6520#ifdef _SC_SIGRT_MAX
6521 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6522#endif
6523#ifdef _SC_SIGRT_MIN
6524 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6525#endif
Fred Draked86ed291999-12-15 15:34:33 +00006526#ifdef _SC_SOFTPOWER
6527 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6528#endif
Fred Drakec9680921999-12-13 16:37:25 +00006529#ifdef _SC_SPLIT_CACHE
6530 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6531#endif
6532#ifdef _SC_SSIZE_MAX
6533 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6534#endif
6535#ifdef _SC_STACK_PROT
6536 {"SC_STACK_PROT", _SC_STACK_PROT},
6537#endif
6538#ifdef _SC_STREAM_MAX
6539 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6540#endif
6541#ifdef _SC_SYNCHRONIZED_IO
6542 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6543#endif
6544#ifdef _SC_THREADS
6545 {"SC_THREADS", _SC_THREADS},
6546#endif
6547#ifdef _SC_THREAD_ATTR_STACKADDR
6548 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6549#endif
6550#ifdef _SC_THREAD_ATTR_STACKSIZE
6551 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6552#endif
6553#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6554 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6555#endif
6556#ifdef _SC_THREAD_KEYS_MAX
6557 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6558#endif
6559#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6560 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6561#endif
6562#ifdef _SC_THREAD_PRIO_INHERIT
6563 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6564#endif
6565#ifdef _SC_THREAD_PRIO_PROTECT
6566 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6567#endif
6568#ifdef _SC_THREAD_PROCESS_SHARED
6569 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6570#endif
6571#ifdef _SC_THREAD_SAFE_FUNCTIONS
6572 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6573#endif
6574#ifdef _SC_THREAD_STACK_MIN
6575 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6576#endif
6577#ifdef _SC_THREAD_THREADS_MAX
6578 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6579#endif
6580#ifdef _SC_TIMERS
6581 {"SC_TIMERS", _SC_TIMERS},
6582#endif
6583#ifdef _SC_TIMER_MAX
6584 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6585#endif
6586#ifdef _SC_TTY_NAME_MAX
6587 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6588#endif
6589#ifdef _SC_TZNAME_MAX
6590 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6591#endif
6592#ifdef _SC_T_IOV_MAX
6593 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6594#endif
6595#ifdef _SC_UCHAR_MAX
6596 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6597#endif
6598#ifdef _SC_UINT_MAX
6599 {"SC_UINT_MAX", _SC_UINT_MAX},
6600#endif
6601#ifdef _SC_UIO_MAXIOV
6602 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6603#endif
6604#ifdef _SC_ULONG_MAX
6605 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6606#endif
6607#ifdef _SC_USHRT_MAX
6608 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6609#endif
6610#ifdef _SC_VERSION
6611 {"SC_VERSION", _SC_VERSION},
6612#endif
6613#ifdef _SC_WORD_BIT
6614 {"SC_WORD_BIT", _SC_WORD_BIT},
6615#endif
6616#ifdef _SC_XBS5_ILP32_OFF32
6617 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6618#endif
6619#ifdef _SC_XBS5_ILP32_OFFBIG
6620 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6621#endif
6622#ifdef _SC_XBS5_LP64_OFF64
6623 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6624#endif
6625#ifdef _SC_XBS5_LPBIG_OFFBIG
6626 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6627#endif
6628#ifdef _SC_XOPEN_CRYPT
6629 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6630#endif
6631#ifdef _SC_XOPEN_ENH_I18N
6632 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6633#endif
6634#ifdef _SC_XOPEN_LEGACY
6635 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6636#endif
6637#ifdef _SC_XOPEN_REALTIME
6638 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6639#endif
6640#ifdef _SC_XOPEN_REALTIME_THREADS
6641 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6642#endif
6643#ifdef _SC_XOPEN_SHM
6644 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6645#endif
6646#ifdef _SC_XOPEN_UNIX
6647 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6648#endif
6649#ifdef _SC_XOPEN_VERSION
6650 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6651#endif
6652#ifdef _SC_XOPEN_XCU_VERSION
6653 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6654#endif
6655#ifdef _SC_XOPEN_XPG2
6656 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6657#endif
6658#ifdef _SC_XOPEN_XPG3
6659 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6660#endif
6661#ifdef _SC_XOPEN_XPG4
6662 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6663#endif
6664};
6665
6666static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006667conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006668{
6669 return conv_confname(arg, valuep, posix_constants_sysconf,
6670 sizeof(posix_constants_sysconf)
6671 / sizeof(struct constdef));
6672}
6673
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006674PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006675"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006676Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006677
6678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006679posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006680{
6681 PyObject *result = NULL;
6682 int name;
6683
6684 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6685 int value;
6686
6687 errno = 0;
6688 value = sysconf(name);
6689 if (value == -1 && errno != 0)
6690 posix_error();
6691 else
6692 result = PyInt_FromLong(value);
6693 }
6694 return result;
6695}
6696#endif
6697
6698
Fred Drakebec628d1999-12-15 18:31:10 +00006699/* This code is used to ensure that the tables of configuration value names
6700 * are in sorted order as required by conv_confname(), and also to build the
6701 * the exported dictionaries that are used to publish information about the
6702 * names available on the host platform.
6703 *
6704 * Sorting the table at runtime ensures that the table is properly ordered
6705 * when used, even for platforms we're not able to test on. It also makes
6706 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006707 */
Fred Drakebec628d1999-12-15 18:31:10 +00006708
6709static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006710cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006711{
6712 const struct constdef *c1 =
6713 (const struct constdef *) v1;
6714 const struct constdef *c2 =
6715 (const struct constdef *) v2;
6716
6717 return strcmp(c1->name, c2->name);
6718}
6719
6720static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006721setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006722 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006723{
Fred Drakebec628d1999-12-15 18:31:10 +00006724 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006725 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006726
6727 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6728 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006729 if (d == NULL)
6730 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006731
Barry Warsaw3155db32000-04-13 15:20:40 +00006732 for (i=0; i < tablesize; ++i) {
6733 PyObject *o = PyInt_FromLong(table[i].value);
6734 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6735 Py_XDECREF(o);
6736 Py_DECREF(d);
6737 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006738 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006739 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006740 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006741 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006742}
6743
Fred Drakebec628d1999-12-15 18:31:10 +00006744/* Return -1 on failure, 0 on success. */
6745static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006746setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006747{
6748#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006749 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006750 sizeof(posix_constants_pathconf)
6751 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006752 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006753 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006754#endif
6755#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006756 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006757 sizeof(posix_constants_confstr)
6758 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006759 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006760 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006761#endif
6762#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006763 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006764 sizeof(posix_constants_sysconf)
6765 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006766 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006767 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006768#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006769 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006770}
Fred Draked86ed291999-12-15 15:34:33 +00006771
6772
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006773PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006774"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006775Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006776in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006777
6778static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006779posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006780{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006781 abort();
6782 /*NOTREACHED*/
6783 Py_FatalError("abort() called from Python code didn't abort!");
6784 return NULL;
6785}
Fred Drakebec628d1999-12-15 18:31:10 +00006786
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006787#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006788PyDoc_STRVAR(win32_startfile__doc__,
6789"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006790\n\
6791This acts like double-clicking the file in Explorer, or giving the file\n\
6792name as an argument to the DOS \"start\" command: the file is opened\n\
6793with whatever application (if any) its extension is associated.\n\
6794\n\
6795startfile returns as soon as the associated application is launched.\n\
6796There is no option to wait for the application to close, and no way\n\
6797to retrieve the application's exit status.\n\
6798\n\
6799The filepath is relative to the current directory. If you want to use\n\
6800an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006801the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006802
6803static PyObject *
6804win32_startfile(PyObject *self, PyObject *args)
6805{
6806 char *filepath;
6807 HINSTANCE rc;
6808 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6809 return NULL;
6810 Py_BEGIN_ALLOW_THREADS
6811 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6812 Py_END_ALLOW_THREADS
6813 if (rc <= (HINSTANCE)32)
6814 return win32_error("startfile", filepath);
6815 Py_INCREF(Py_None);
6816 return Py_None;
6817}
6818#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006819
Martin v. Löwis438b5342002-12-27 10:16:42 +00006820#ifdef HAVE_GETLOADAVG
6821PyDoc_STRVAR(posix_getloadavg__doc__,
6822"getloadavg() -> (float, float, float)\n\n\
6823Return the number of processes in the system run queue averaged over\n\
6824the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6825was unobtainable");
6826
6827static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006828posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006829{
6830 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006831 if (getloadavg(loadavg, 3)!=3) {
6832 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6833 return NULL;
6834 } else
6835 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6836}
6837#endif
6838
6839
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006840static PyMethodDef posix_methods[] = {
6841 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6842#ifdef HAVE_TTYNAME
6843 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6844#endif
6845 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6846 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006847#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006848 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006849#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006850#ifdef HAVE_LCHOWN
6851 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6852#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006853#ifdef HAVE_CHROOT
6854 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6855#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006856#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006857 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006858#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006859#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006860 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00006861#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00006862 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006863#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00006864#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006865#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006866 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006867#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006868 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6869 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6870 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006871#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006872 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006873#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006874#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006875 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006876#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006877 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6878 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6879 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006880 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006881#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006882 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006883#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006884#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006885 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006886#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006887 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006888#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006889 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006890#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006891 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6892 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6893 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006894#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006895 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006896#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006897 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006898#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006899 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6900 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006901#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006902#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006903 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6904 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006905#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006906#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006907 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006908#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006909#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006910 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006911#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006912#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006913 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006914#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006915#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006916 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006917#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006918#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006919 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006920#endif /* HAVE_GETEGID */
6921#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006922 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006923#endif /* HAVE_GETEUID */
6924#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006925 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006926#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006927#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006928 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00006929#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006930 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006931#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006932 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006933#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006934#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00006935 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006936#endif /* HAVE_GETPPID */
6937#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006938 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006939#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006940#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00006941 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00006942#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006943#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006944 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006945#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006946#ifdef HAVE_KILLPG
6947 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6948#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006949#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006950 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006951#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006952#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006953 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006954#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006955 {"popen2", win32_popen2, METH_VARARGS},
6956 {"popen3", win32_popen3, METH_VARARGS},
6957 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006958 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006959#else
6960#if defined(PYOS_OS2) && defined(PYCC_GCC)
6961 {"popen2", os2emx_popen2, METH_VARARGS},
6962 {"popen3", os2emx_popen3, METH_VARARGS},
6963 {"popen4", os2emx_popen4, METH_VARARGS},
6964#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006965#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006966#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006967#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006968 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006969#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006970#ifdef HAVE_SETEUID
6971 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6972#endif /* HAVE_SETEUID */
6973#ifdef HAVE_SETEGID
6974 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6975#endif /* HAVE_SETEGID */
6976#ifdef HAVE_SETREUID
6977 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6978#endif /* HAVE_SETREUID */
6979#ifdef HAVE_SETREGID
6980 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6981#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006982#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006983 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006984#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006985#ifdef HAVE_SETGROUPS
6986 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6987#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006988#ifdef HAVE_GETPGID
6989 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6990#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006991#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006992 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006993#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006994#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00006995 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006996#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006997#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006998 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006999#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007000#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007001 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007002#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007003#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007004 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007005#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007006#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007007 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007008#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007009#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007010 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007011#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007012 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7013 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7014 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7015 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7016 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7017 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7018 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7019 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7020 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007021 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007022#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007023 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007024#endif
7025#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007026 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007027#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007028#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007029 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7030#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007031#ifdef HAVE_DEVICE_MACROS
7032 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7033 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7034 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7035#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007036#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007037 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007038#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007039#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007040 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007041#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007042#ifdef HAVE_UNSETENV
7043 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7044#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007045#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007046 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007047#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007048#ifdef HAVE_FCHDIR
7049 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7050#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007051#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007052 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007053#endif
7054#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007055 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007056#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007057#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007058#ifdef WCOREDUMP
7059 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7060#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007061#ifdef WIFCONTINUED
7062 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7063#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007064#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007065 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007066#endif /* WIFSTOPPED */
7067#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007068 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007069#endif /* WIFSIGNALED */
7070#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007071 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007072#endif /* WIFEXITED */
7073#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007074 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007075#endif /* WEXITSTATUS */
7076#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007077 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007078#endif /* WTERMSIG */
7079#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007080 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007081#endif /* WSTOPSIG */
7082#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007083#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007084 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007085#endif
7086#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007087 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007088#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007089#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007090 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007091#endif
7092#ifdef HAVE_TEMPNAM
7093 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7094#endif
7095#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007096 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007097#endif
Fred Drakec9680921999-12-13 16:37:25 +00007098#ifdef HAVE_CONFSTR
7099 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7100#endif
7101#ifdef HAVE_SYSCONF
7102 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7103#endif
7104#ifdef HAVE_FPATHCONF
7105 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7106#endif
7107#ifdef HAVE_PATHCONF
7108 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7109#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007110 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007111#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007112 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7113#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007114#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007115 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007116#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007117 {NULL, NULL} /* Sentinel */
7118};
7119
7120
Barry Warsaw4a342091996-12-19 23:50:02 +00007121static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007122ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007123{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007124 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007125}
7126
Guido van Rossumd48f2521997-12-05 22:19:34 +00007127#if defined(PYOS_OS2)
7128/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007129static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007130{
7131 APIRET rc;
7132 ULONG values[QSV_MAX+1];
7133 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007134 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007135
7136 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007137 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007138 Py_END_ALLOW_THREADS
7139
7140 if (rc != NO_ERROR) {
7141 os2_error(rc);
7142 return -1;
7143 }
7144
Fred Drake4d1e64b2002-04-15 19:40:07 +00007145 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7146 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7147 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7148 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7149 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7150 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7151 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007152
7153 switch (values[QSV_VERSION_MINOR]) {
7154 case 0: ver = "2.00"; break;
7155 case 10: ver = "2.10"; break;
7156 case 11: ver = "2.11"; break;
7157 case 30: ver = "3.00"; break;
7158 case 40: ver = "4.00"; break;
7159 case 50: ver = "5.00"; break;
7160 default:
Tim Peters885d4572001-11-28 20:27:42 +00007161 PyOS_snprintf(tmp, sizeof(tmp),
7162 "%d-%d", values[QSV_VERSION_MAJOR],
7163 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007164 ver = &tmp[0];
7165 }
7166
7167 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007168 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007169 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007170
7171 /* Add Indicator of Which Drive was Used to Boot the System */
7172 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7173 tmp[1] = ':';
7174 tmp[2] = '\0';
7175
Fred Drake4d1e64b2002-04-15 19:40:07 +00007176 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007177}
7178#endif
7179
Barry Warsaw4a342091996-12-19 23:50:02 +00007180static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007181all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007182{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007183#ifdef F_OK
7184 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007185#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007186#ifdef R_OK
7187 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007188#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007189#ifdef W_OK
7190 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007191#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007192#ifdef X_OK
7193 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007194#endif
Fred Drakec9680921999-12-13 16:37:25 +00007195#ifdef NGROUPS_MAX
7196 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7197#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007198#ifdef TMP_MAX
7199 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7200#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007201#ifdef WCONTINUED
7202 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7203#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007204#ifdef WNOHANG
7205 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007206#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007207#ifdef WUNTRACED
7208 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7209#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007210#ifdef O_RDONLY
7211 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7212#endif
7213#ifdef O_WRONLY
7214 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7215#endif
7216#ifdef O_RDWR
7217 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7218#endif
7219#ifdef O_NDELAY
7220 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7221#endif
7222#ifdef O_NONBLOCK
7223 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7224#endif
7225#ifdef O_APPEND
7226 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7227#endif
7228#ifdef O_DSYNC
7229 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7230#endif
7231#ifdef O_RSYNC
7232 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7233#endif
7234#ifdef O_SYNC
7235 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7236#endif
7237#ifdef O_NOCTTY
7238 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7239#endif
7240#ifdef O_CREAT
7241 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7242#endif
7243#ifdef O_EXCL
7244 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7245#endif
7246#ifdef O_TRUNC
7247 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7248#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007249#ifdef O_BINARY
7250 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7251#endif
7252#ifdef O_TEXT
7253 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7254#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007255#ifdef O_LARGEFILE
7256 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7257#endif
7258
Tim Peters5aa91602002-01-30 05:46:57 +00007259/* MS Windows */
7260#ifdef O_NOINHERIT
7261 /* Don't inherit in child processes. */
7262 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7263#endif
7264#ifdef _O_SHORT_LIVED
7265 /* Optimize for short life (keep in memory). */
7266 /* MS forgot to define this one with a non-underscore form too. */
7267 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7268#endif
7269#ifdef O_TEMPORARY
7270 /* Automatically delete when last handle is closed. */
7271 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7272#endif
7273#ifdef O_RANDOM
7274 /* Optimize for random access. */
7275 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7276#endif
7277#ifdef O_SEQUENTIAL
7278 /* Optimize for sequential access. */
7279 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7280#endif
7281
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007282/* GNU extensions. */
7283#ifdef O_DIRECT
7284 /* Direct disk access. */
7285 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7286#endif
7287#ifdef O_DIRECTORY
7288 /* Must be a directory. */
7289 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7290#endif
7291#ifdef O_NOFOLLOW
7292 /* Do not follow links. */
7293 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7294#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007295
Barry Warsaw5676bd12003-01-07 20:57:09 +00007296 /* These come from sysexits.h */
7297#ifdef EX_OK
7298 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007299#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007300#ifdef EX_USAGE
7301 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007302#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007303#ifdef EX_DATAERR
7304 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007305#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007306#ifdef EX_NOINPUT
7307 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007308#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007309#ifdef EX_NOUSER
7310 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007311#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007312#ifdef EX_NOHOST
7313 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007314#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007315#ifdef EX_UNAVAILABLE
7316 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007317#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007318#ifdef EX_SOFTWARE
7319 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007320#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007321#ifdef EX_OSERR
7322 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007323#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007324#ifdef EX_OSFILE
7325 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007326#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007327#ifdef EX_CANTCREAT
7328 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007329#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007330#ifdef EX_IOERR
7331 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007332#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007333#ifdef EX_TEMPFAIL
7334 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007335#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007336#ifdef EX_PROTOCOL
7337 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007338#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007339#ifdef EX_NOPERM
7340 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007341#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007342#ifdef EX_CONFIG
7343 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007344#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007345#ifdef EX_NOTFOUND
7346 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007347#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007348
Guido van Rossum246bc171999-02-01 23:54:31 +00007349#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007350#if defined(PYOS_OS2) && defined(PYCC_GCC)
7351 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7352 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7353 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7354 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7355 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7356 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7357 if (ins(d, "P_PM", (long)P_PM)) return -1;
7358 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7359 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7360 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7361 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7362 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7363 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7364 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7365 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7366 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7367 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7368 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7369 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7370 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7371#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007372 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7373 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7374 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7375 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7376 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007377#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007378#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007379
Guido van Rossumd48f2521997-12-05 22:19:34 +00007380#if defined(PYOS_OS2)
7381 if (insertvalues(d)) return -1;
7382#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007383 return 0;
7384}
7385
7386
Tim Peters5aa91602002-01-30 05:46:57 +00007387#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007388#define INITFUNC initnt
7389#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007390
7391#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007392#define INITFUNC initos2
7393#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007394
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007395#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007396#define INITFUNC initposix
7397#define MODNAME "posix"
7398#endif
7399
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007400PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007401INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007402{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007403 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007404
Fred Drake4d1e64b2002-04-15 19:40:07 +00007405 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007406 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007407 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007408
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007409 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007410 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007411 Py_XINCREF(v);
7412 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007413 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007414 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007415
Fred Drake4d1e64b2002-04-15 19:40:07 +00007416 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007417 return;
7418
Fred Drake4d1e64b2002-04-15 19:40:07 +00007419 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007420 return;
7421
Fred Drake4d1e64b2002-04-15 19:40:07 +00007422 Py_INCREF(PyExc_OSError);
7423 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007424
Guido van Rossumb3d39562000-01-31 18:41:26 +00007425#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007426 if (posix_putenv_garbage == NULL)
7427 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007428#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007429
Guido van Rossum14648392001-12-08 18:02:58 +00007430 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007431 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7432 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7433 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007434 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007435 structseq_new = StatResultType.tp_new;
7436 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007437 Py_INCREF((PyObject*) &StatResultType);
7438 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007439
Guido van Rossum14648392001-12-08 18:02:58 +00007440 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007441 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007442 Py_INCREF((PyObject*) &StatVFSResultType);
7443 PyModule_AddObject(m, "statvfs_result",
7444 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007445}