blob: 43af76647a682fab0059ab35ff210338c789cbe7 [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{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003618 PyObject *f, *s;
3619 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
3627 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003628
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003629 if (*mode == 'r')
3630 tm = _O_RDONLY;
3631 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003632 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003633 return NULL;
3634 } else
3635 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003636
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003637 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003638 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003639 return NULL;
3640 }
3641
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003642 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003643 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003644 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003645 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003646 else
3647 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3648
3649 return f;
3650}
3651
3652/* Variation on win32pipe.popen
3653 *
3654 * The result of this function is a pipe (file) connected to the
3655 * process's stdin, and a pipe connected to the process's stdout.
3656 */
3657
3658static PyObject *
3659win32_popen2(PyObject *self, PyObject *args)
3660{
3661 PyObject *f;
3662 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003663
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003664 char *cmdstring;
3665 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003666 int bufsize = -1;
3667 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003668 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003669
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003670 if (*mode == 't')
3671 tm = _O_TEXT;
3672 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003673 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003674 return NULL;
3675 } else
3676 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003677
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003678 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003679 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003680 return NULL;
3681 }
3682
3683 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003684
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003685 return f;
3686}
3687
3688/*
3689 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003690 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003691 * The result of this function is 3 pipes - the process's stdin,
3692 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003693 */
3694
3695static PyObject *
3696win32_popen3(PyObject *self, PyObject *args)
3697{
3698 PyObject *f;
3699 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003700
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003701 char *cmdstring;
3702 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003703 int bufsize = -1;
3704 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003705 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003706
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003707 if (*mode == 't')
3708 tm = _O_TEXT;
3709 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003710 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003711 return NULL;
3712 } else
3713 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003714
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003715 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003716 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003717 return NULL;
3718 }
3719
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003720 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003721
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003722 return f;
3723}
3724
3725/*
3726 * Variation on win32pipe.popen
3727 *
Tim Peters5aa91602002-01-30 05:46:57 +00003728 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003729 * and stdout+stderr combined as a single pipe.
3730 */
3731
3732static PyObject *
3733win32_popen4(PyObject *self, PyObject *args)
3734{
3735 PyObject *f;
3736 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003737
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003738 char *cmdstring;
3739 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003740 int bufsize = -1;
3741 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003742 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003743
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003744 if (*mode == 't')
3745 tm = _O_TEXT;
3746 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003747 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003748 return NULL;
3749 } else
3750 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003751
3752 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003753 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003754 return NULL;
3755 }
3756
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003757 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003758
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003759 return f;
3760}
3761
Mark Hammond08501372001-01-31 07:30:29 +00003762static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003763_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003764 HANDLE hStdin,
3765 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003766 HANDLE hStderr,
3767 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003768{
3769 PROCESS_INFORMATION piProcInfo;
3770 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003771 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003772 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003773 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003774 int i;
3775 int x;
3776
3777 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003778 char *comshell;
3779
Tim Peters92e4dd82002-10-05 01:47:34 +00003780 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003781 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3782 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003783
3784 /* Explicitly check if we are using COMMAND.COM. If we are
3785 * then use the w9xpopen hack.
3786 */
3787 comshell = s1 + x;
3788 while (comshell >= s1 && *comshell != '\\')
3789 --comshell;
3790 ++comshell;
3791
3792 if (GetVersion() < 0x80000000 &&
3793 _stricmp(comshell, "command.com") != 0) {
3794 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003795 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003796 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003797 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003798 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003799 }
3800 else {
3801 /*
Tim Peters402d5982001-08-27 06:37:48 +00003802 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3803 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003804 */
Mark Hammond08501372001-01-31 07:30:29 +00003805 char modulepath[_MAX_PATH];
3806 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003807 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3808 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003809 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003810 x = i+1;
3811 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003812 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003813 strncat(modulepath,
3814 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003815 (sizeof(modulepath)/sizeof(modulepath[0]))
3816 -strlen(modulepath));
3817 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003818 /* Eeek - file-not-found - possibly an embedding
3819 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003820 */
Tim Peters5aa91602002-01-30 05:46:57 +00003821 strncpy(modulepath,
3822 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003823 sizeof(modulepath)/sizeof(modulepath[0]));
3824 if (modulepath[strlen(modulepath)-1] != '\\')
3825 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003826 strncat(modulepath,
3827 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003828 (sizeof(modulepath)/sizeof(modulepath[0]))
3829 -strlen(modulepath));
3830 /* No where else to look - raise an easily identifiable
3831 error, rather than leaving Windows to report
3832 "file not found" - as the user is probably blissfully
3833 unaware this shim EXE is used, and it will confuse them.
3834 (well, it confused me for a while ;-)
3835 */
3836 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003837 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003838 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003839 "for popen to work with your shell "
3840 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003841 szConsoleSpawn);
3842 return FALSE;
3843 }
3844 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003845 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003846 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003847 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003848
Tim Peters92e4dd82002-10-05 01:47:34 +00003849 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003850 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003851 /* To maintain correct argument passing semantics,
3852 we pass the command-line as it stands, and allow
3853 quoting to be applied. w9xpopen.exe will then
3854 use its argv vector, and re-quote the necessary
3855 args for the ultimate child process.
3856 */
Tim Peters75cdad52001-11-28 22:07:30 +00003857 PyOS_snprintf(
3858 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003859 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003860 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003861 s1,
3862 s3,
3863 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003864 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00003865 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003866 dialog:
3867 "Your program accessed mem currently in use at xxx"
3868 and a hopeful warning about the stability of your
3869 system.
3870 Cost is Ctrl+C wont kill children, but anyone
3871 who cares can have a go!
3872 */
3873 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003874 }
3875 }
3876
3877 /* Could be an else here to try cmd.exe / command.com in the path
3878 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003879 else {
Tim Peters402d5982001-08-27 06:37:48 +00003880 PyErr_SetString(PyExc_RuntimeError,
3881 "Cannot locate a COMSPEC environment variable to "
3882 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003883 return FALSE;
3884 }
Tim Peters5aa91602002-01-30 05:46:57 +00003885
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003886 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3887 siStartInfo.cb = sizeof(STARTUPINFO);
3888 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3889 siStartInfo.hStdInput = hStdin;
3890 siStartInfo.hStdOutput = hStdout;
3891 siStartInfo.hStdError = hStderr;
3892 siStartInfo.wShowWindow = SW_HIDE;
3893
3894 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003895 s2,
3896 NULL,
3897 NULL,
3898 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003899 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003900 NULL,
3901 NULL,
3902 &siStartInfo,
3903 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003904 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003905 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003906
Mark Hammondb37a3732000-08-14 04:47:33 +00003907 /* Return process handle */
3908 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003909 return TRUE;
3910 }
Tim Peters402d5982001-08-27 06:37:48 +00003911 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003912 return FALSE;
3913}
3914
3915/* The following code is based off of KB: Q190351 */
3916
3917static PyObject *
3918_PyPopen(char *cmdstring, int mode, int n)
3919{
3920 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3921 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003922 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003923
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003924 SECURITY_ATTRIBUTES saAttr;
3925 BOOL fSuccess;
3926 int fd1, fd2, fd3;
3927 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003928 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003929 PyObject *f;
3930
3931 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3932 saAttr.bInheritHandle = TRUE;
3933 saAttr.lpSecurityDescriptor = NULL;
3934
3935 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3936 return win32_error("CreatePipe", NULL);
3937
3938 /* Create new output read handle and the input write handle. Set
3939 * the inheritance properties to FALSE. Otherwise, the child inherits
3940 * the these handles; resulting in non-closeable handles to the pipes
3941 * being created. */
3942 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003943 GetCurrentProcess(), &hChildStdinWrDup, 0,
3944 FALSE,
3945 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003946 if (!fSuccess)
3947 return win32_error("DuplicateHandle", NULL);
3948
3949 /* Close the inheritable version of ChildStdin
3950 that we're using. */
3951 CloseHandle(hChildStdinWr);
3952
3953 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3954 return win32_error("CreatePipe", NULL);
3955
3956 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003957 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3958 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003959 if (!fSuccess)
3960 return win32_error("DuplicateHandle", NULL);
3961
3962 /* Close the inheritable version of ChildStdout
3963 that we're using. */
3964 CloseHandle(hChildStdoutRd);
3965
3966 if (n != POPEN_4) {
3967 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3968 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003969 fSuccess = DuplicateHandle(GetCurrentProcess(),
3970 hChildStderrRd,
3971 GetCurrentProcess(),
3972 &hChildStderrRdDup, 0,
3973 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003974 if (!fSuccess)
3975 return win32_error("DuplicateHandle", NULL);
3976 /* Close the inheritable version of ChildStdErr that we're using. */
3977 CloseHandle(hChildStderrRd);
3978 }
Tim Peters5aa91602002-01-30 05:46:57 +00003979
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003980 switch (n) {
3981 case POPEN_1:
3982 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3983 case _O_WRONLY | _O_TEXT:
3984 /* Case for writing to child Stdin in text mode. */
3985 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3986 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003987 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003988 PyFile_SetBufSize(f, 0);
3989 /* We don't care about these pipes anymore, so close them. */
3990 CloseHandle(hChildStdoutRdDup);
3991 CloseHandle(hChildStderrRdDup);
3992 break;
3993
3994 case _O_RDONLY | _O_TEXT:
3995 /* Case for reading from child Stdout in text mode. */
3996 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3997 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003998 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003999 PyFile_SetBufSize(f, 0);
4000 /* We don't care about these pipes anymore, so close them. */
4001 CloseHandle(hChildStdinWrDup);
4002 CloseHandle(hChildStderrRdDup);
4003 break;
4004
4005 case _O_RDONLY | _O_BINARY:
4006 /* Case for readinig from child Stdout in binary mode. */
4007 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4008 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004009 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004010 PyFile_SetBufSize(f, 0);
4011 /* We don't care about these pipes anymore, so close them. */
4012 CloseHandle(hChildStdinWrDup);
4013 CloseHandle(hChildStderrRdDup);
4014 break;
4015
4016 case _O_WRONLY | _O_BINARY:
4017 /* Case for writing to child Stdin in binary mode. */
4018 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4019 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004020 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004021 PyFile_SetBufSize(f, 0);
4022 /* We don't care about these pipes anymore, so close them. */
4023 CloseHandle(hChildStdoutRdDup);
4024 CloseHandle(hChildStderrRdDup);
4025 break;
4026 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004027 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004028 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004029
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004030 case POPEN_2:
4031 case POPEN_4:
4032 {
4033 char *m1, *m2;
4034 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004035
Tim Peters7dca21e2002-08-19 00:42:29 +00004036 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004037 m1 = "r";
4038 m2 = "w";
4039 } else {
4040 m1 = "rb";
4041 m2 = "wb";
4042 }
4043
4044 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4045 f1 = _fdopen(fd1, m2);
4046 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4047 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004048 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004049 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004050 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004051 PyFile_SetBufSize(p2, 0);
4052
4053 if (n != 4)
4054 CloseHandle(hChildStderrRdDup);
4055
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004056 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004057 Py_XDECREF(p1);
4058 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004059 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004060 break;
4061 }
Tim Peters5aa91602002-01-30 05:46:57 +00004062
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004063 case POPEN_3:
4064 {
4065 char *m1, *m2;
4066 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004067
Tim Peters7dca21e2002-08-19 00:42:29 +00004068 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004069 m1 = "r";
4070 m2 = "w";
4071 } else {
4072 m1 = "rb";
4073 m2 = "wb";
4074 }
4075
4076 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4077 f1 = _fdopen(fd1, m2);
4078 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4079 f2 = _fdopen(fd2, m1);
4080 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4081 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004082 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004083 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4084 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004085 PyFile_SetBufSize(p1, 0);
4086 PyFile_SetBufSize(p2, 0);
4087 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004088 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004089 Py_XDECREF(p1);
4090 Py_XDECREF(p2);
4091 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004092 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004093 break;
4094 }
4095 }
4096
4097 if (n == POPEN_4) {
4098 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004099 hChildStdinRd,
4100 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004101 hChildStdoutWr,
4102 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004103 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004104 }
4105 else {
4106 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004107 hChildStdinRd,
4108 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004109 hChildStderrWr,
4110 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004111 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004112 }
4113
Mark Hammondb37a3732000-08-14 04:47:33 +00004114 /*
4115 * Insert the files we've created into the process dictionary
4116 * all referencing the list with the process handle and the
4117 * initial number of files (see description below in _PyPclose).
4118 * Since if _PyPclose later tried to wait on a process when all
4119 * handles weren't closed, it could create a deadlock with the
4120 * child, we spend some energy here to try to ensure that we
4121 * either insert all file handles into the dictionary or none
4122 * at all. It's a little clumsy with the various popen modes
4123 * and variable number of files involved.
4124 */
4125 if (!_PyPopenProcs) {
4126 _PyPopenProcs = PyDict_New();
4127 }
4128
4129 if (_PyPopenProcs) {
4130 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4131 int ins_rc[3];
4132
4133 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4134 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4135
4136 procObj = PyList_New(2);
4137 hProcessObj = PyLong_FromVoidPtr(hProcess);
4138 intObj = PyInt_FromLong(file_count);
4139
4140 if (procObj && hProcessObj && intObj) {
4141 PyList_SetItem(procObj,0,hProcessObj);
4142 PyList_SetItem(procObj,1,intObj);
4143
4144 fileObj[0] = PyLong_FromVoidPtr(f1);
4145 if (fileObj[0]) {
4146 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4147 fileObj[0],
4148 procObj);
4149 }
4150 if (file_count >= 2) {
4151 fileObj[1] = PyLong_FromVoidPtr(f2);
4152 if (fileObj[1]) {
4153 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4154 fileObj[1],
4155 procObj);
4156 }
4157 }
4158 if (file_count >= 3) {
4159 fileObj[2] = PyLong_FromVoidPtr(f3);
4160 if (fileObj[2]) {
4161 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4162 fileObj[2],
4163 procObj);
4164 }
4165 }
4166
4167 if (ins_rc[0] < 0 || !fileObj[0] ||
4168 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4169 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4170 /* Something failed - remove any dictionary
4171 * entries that did make it.
4172 */
4173 if (!ins_rc[0] && fileObj[0]) {
4174 PyDict_DelItem(_PyPopenProcs,
4175 fileObj[0]);
4176 }
4177 if (!ins_rc[1] && fileObj[1]) {
4178 PyDict_DelItem(_PyPopenProcs,
4179 fileObj[1]);
4180 }
4181 if (!ins_rc[2] && fileObj[2]) {
4182 PyDict_DelItem(_PyPopenProcs,
4183 fileObj[2]);
4184 }
4185 }
4186 }
Tim Peters5aa91602002-01-30 05:46:57 +00004187
Mark Hammondb37a3732000-08-14 04:47:33 +00004188 /*
4189 * Clean up our localized references for the dictionary keys
4190 * and value since PyDict_SetItem will Py_INCREF any copies
4191 * that got placed in the dictionary.
4192 */
4193 Py_XDECREF(procObj);
4194 Py_XDECREF(fileObj[0]);
4195 Py_XDECREF(fileObj[1]);
4196 Py_XDECREF(fileObj[2]);
4197 }
4198
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004199 /* Child is launched. Close the parents copy of those pipe
4200 * handles that only the child should have open. You need to
4201 * make sure that no handles to the write end of the output pipe
4202 * are maintained in this process or else the pipe will not close
4203 * when the child process exits and the ReadFile will hang. */
4204
4205 if (!CloseHandle(hChildStdinRd))
4206 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004207
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004208 if (!CloseHandle(hChildStdoutWr))
4209 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004210
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004211 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4212 return win32_error("CloseHandle", NULL);
4213
4214 return f;
4215}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004216
4217/*
4218 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4219 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004220 *
4221 * This function uses the _PyPopenProcs dictionary in order to map the
4222 * input file pointer to information about the process that was
4223 * originally created by the popen* call that created the file pointer.
4224 * The dictionary uses the file pointer as a key (with one entry
4225 * inserted for each file returned by the original popen* call) and a
4226 * single list object as the value for all files from a single call.
4227 * The list object contains the Win32 process handle at [0], and a file
4228 * count at [1], which is initialized to the total number of file
4229 * handles using that list.
4230 *
4231 * This function closes whichever handle it is passed, and decrements
4232 * the file count in the dictionary for the process handle pointed to
4233 * by this file. On the last close (when the file count reaches zero),
4234 * this function will wait for the child process and then return its
4235 * exit code as the result of the close() operation. This permits the
4236 * files to be closed in any order - it is always the close() of the
4237 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004238 *
4239 * NOTE: This function is currently called with the GIL released.
4240 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004241 */
Tim Peters736aa322000-09-01 06:51:24 +00004242
Fredrik Lundh56055a42000-07-23 19:47:12 +00004243static int _PyPclose(FILE *file)
4244{
Fredrik Lundh20318932000-07-26 17:29:12 +00004245 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004246 DWORD exit_code;
4247 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004248 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4249 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004250#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004251 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004252#endif
4253
Fredrik Lundh20318932000-07-26 17:29:12 +00004254 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004255 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004256 */
4257 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004258#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004259 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004260#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004261 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004262 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4263 (procObj = PyDict_GetItem(_PyPopenProcs,
4264 fileObj)) != NULL &&
4265 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4266 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4267
4268 hProcess = PyLong_AsVoidPtr(hProcessObj);
4269 file_count = PyInt_AsLong(intObj);
4270
4271 if (file_count > 1) {
4272 /* Still other files referencing process */
4273 file_count--;
4274 PyList_SetItem(procObj,1,
4275 PyInt_FromLong(file_count));
4276 } else {
4277 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004278 if (result != EOF &&
4279 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4280 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004281 /* Possible truncation here in 16-bit environments, but
4282 * real exit codes are just the lower byte in any event.
4283 */
4284 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004285 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004286 /* Indicate failure - this will cause the file object
4287 * to raise an I/O error and translate the last Win32
4288 * error code from errno. We do have a problem with
4289 * last errors that overlap the normal errno table,
4290 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004291 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004292 if (result != EOF) {
4293 /* If the error wasn't from the fclose(), then
4294 * set errno for the file object error handling.
4295 */
4296 errno = GetLastError();
4297 }
4298 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004299 }
4300
4301 /* Free up the native handle at this point */
4302 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004303 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004304
Mark Hammondb37a3732000-08-14 04:47:33 +00004305 /* Remove this file pointer from dictionary */
4306 PyDict_DelItem(_PyPopenProcs, fileObj);
4307
4308 if (PyDict_Size(_PyPopenProcs) == 0) {
4309 Py_DECREF(_PyPopenProcs);
4310 _PyPopenProcs = NULL;
4311 }
4312
4313 } /* if object retrieval ok */
4314
4315 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004316 } /* if _PyPopenProcs */
4317
Tim Peters736aa322000-09-01 06:51:24 +00004318#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004319 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004320#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004321 return result;
4322}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004323
4324#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004325static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004326posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004327{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004328 char *name;
4329 char *mode = "r";
4330 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004331 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004332 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004333 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004334 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004335 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004336 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004337 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004338 if (fp == NULL)
4339 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004340 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004341 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004342 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004343 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004344}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004345
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004346#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004347#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004348
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004349
Guido van Rossumb6775db1994-08-01 11:34:53 +00004350#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004351PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004352"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004353Set the current process's user id.");
4354
Barry Warsaw53699e91996-12-10 23:23:01 +00004355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004356posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004357{
4358 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004359 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004360 return NULL;
4361 if (setuid(uid) < 0)
4362 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004363 Py_INCREF(Py_None);
4364 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004365}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004366#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004367
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004368
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004369#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004370PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004371"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004372Set the current process's effective user id.");
4373
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004374static PyObject *
4375posix_seteuid (PyObject *self, PyObject *args)
4376{
4377 int euid;
4378 if (!PyArg_ParseTuple(args, "i", &euid)) {
4379 return NULL;
4380 } else if (seteuid(euid) < 0) {
4381 return posix_error();
4382 } else {
4383 Py_INCREF(Py_None);
4384 return Py_None;
4385 }
4386}
4387#endif /* HAVE_SETEUID */
4388
4389#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004390PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004391"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004392Set the current process's effective group id.");
4393
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004394static PyObject *
4395posix_setegid (PyObject *self, PyObject *args)
4396{
4397 int egid;
4398 if (!PyArg_ParseTuple(args, "i", &egid)) {
4399 return NULL;
4400 } else if (setegid(egid) < 0) {
4401 return posix_error();
4402 } else {
4403 Py_INCREF(Py_None);
4404 return Py_None;
4405 }
4406}
4407#endif /* HAVE_SETEGID */
4408
4409#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004410PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004411"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004412Set the current process's real and effective user ids.");
4413
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004414static PyObject *
4415posix_setreuid (PyObject *self, PyObject *args)
4416{
4417 int ruid, euid;
4418 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4419 return NULL;
4420 } else if (setreuid(ruid, euid) < 0) {
4421 return posix_error();
4422 } else {
4423 Py_INCREF(Py_None);
4424 return Py_None;
4425 }
4426}
4427#endif /* HAVE_SETREUID */
4428
4429#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004430PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004431"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004432Set the current process's real and effective group ids.");
4433
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004434static PyObject *
4435posix_setregid (PyObject *self, PyObject *args)
4436{
4437 int rgid, egid;
4438 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4439 return NULL;
4440 } else if (setregid(rgid, egid) < 0) {
4441 return posix_error();
4442 } else {
4443 Py_INCREF(Py_None);
4444 return Py_None;
4445 }
4446}
4447#endif /* HAVE_SETREGID */
4448
Guido van Rossumb6775db1994-08-01 11:34:53 +00004449#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004450PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004451"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004452Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004453
Barry Warsaw53699e91996-12-10 23:23:01 +00004454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004455posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004456{
4457 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004458 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004459 return NULL;
4460 if (setgid(gid) < 0)
4461 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004462 Py_INCREF(Py_None);
4463 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004464}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004465#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004466
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004467#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004468PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004469"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004470Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004471
4472static PyObject *
4473posix_setgroups(PyObject *self, PyObject *args)
4474{
4475 PyObject *groups;
4476 int i, len;
4477 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004478
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004479 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4480 return NULL;
4481 if (!PySequence_Check(groups)) {
4482 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4483 return NULL;
4484 }
4485 len = PySequence_Size(groups);
4486 if (len > MAX_GROUPS) {
4487 PyErr_SetString(PyExc_ValueError, "too many groups");
4488 return NULL;
4489 }
4490 for(i = 0; i < len; i++) {
4491 PyObject *elem;
4492 elem = PySequence_GetItem(groups, i);
4493 if (!elem)
4494 return NULL;
4495 if (!PyInt_Check(elem)) {
4496 PyErr_SetString(PyExc_TypeError,
4497 "groups must be integers");
4498 Py_DECREF(elem);
4499 return NULL;
4500 }
4501 /* XXX: check that value fits into gid_t. */
4502 grouplist[i] = PyInt_AsLong(elem);
4503 Py_DECREF(elem);
4504 }
4505
4506 if (setgroups(len, grouplist) < 0)
4507 return posix_error();
4508 Py_INCREF(Py_None);
4509 return Py_None;
4510}
4511#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004512
Guido van Rossumb6775db1994-08-01 11:34:53 +00004513#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004514PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004515"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004516Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004517
Barry Warsaw53699e91996-12-10 23:23:01 +00004518static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004519posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004520{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004521 int pid, options;
4522#ifdef UNION_WAIT
4523 union wait status;
4524#define status_i (status.w_status)
4525#else
4526 int status;
4527#define status_i status
4528#endif
4529 status_i = 0;
4530
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004531 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004532 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004533 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004534 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004535 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004536 if (pid == -1)
4537 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004538 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004539 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004540}
4541
Tim Petersab034fa2002-02-01 11:27:43 +00004542#elif defined(HAVE_CWAIT)
4543
4544/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004545PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004546"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004547"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004548
4549static PyObject *
4550posix_waitpid(PyObject *self, PyObject *args)
4551{
4552 int pid, options;
4553 int status;
4554
4555 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4556 return NULL;
4557 Py_BEGIN_ALLOW_THREADS
4558 pid = _cwait(&status, pid, options);
4559 Py_END_ALLOW_THREADS
4560 if (pid == -1)
4561 return posix_error();
4562 else
4563 /* shift the status left a byte so this is more like the
4564 POSIX waitpid */
4565 return Py_BuildValue("ii", pid, status << 8);
4566}
4567#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004568
Guido van Rossumad0ee831995-03-01 10:34:45 +00004569#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004570PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004571"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004572Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004573
Barry Warsaw53699e91996-12-10 23:23:01 +00004574static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004575posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004576{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004577 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004578#ifdef UNION_WAIT
4579 union wait status;
4580#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004581#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004582 int status;
4583#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004584#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004585
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004586 status_i = 0;
4587 Py_BEGIN_ALLOW_THREADS
4588 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004589 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004590 if (pid == -1)
4591 return posix_error();
4592 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004593 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004594#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004595}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004596#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004597
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004598
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004599PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004600"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004601Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004602
Barry Warsaw53699e91996-12-10 23:23:01 +00004603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004604posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004605{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004606#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004607 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004608#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004609#ifdef MS_WINDOWS
4610 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4611#else
4612 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4613#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004614#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004615}
4616
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004617
Guido van Rossumb6775db1994-08-01 11:34:53 +00004618#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004619PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004620"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004621Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004622
Barry Warsaw53699e91996-12-10 23:23:01 +00004623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004624posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004625{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004626 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004627 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004628 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004629 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004630 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004631 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004632 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004633 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004634 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004635 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004636 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004637}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004638#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004639
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004640
Guido van Rossumb6775db1994-08-01 11:34:53 +00004641#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004642PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004643"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00004644Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004645
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004647posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004648{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004649 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004650}
4651#endif /* HAVE_SYMLINK */
4652
4653
4654#ifdef HAVE_TIMES
4655#ifndef HZ
4656#define HZ 60 /* Universal constant :-) */
4657#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004658
Guido van Rossumd48f2521997-12-05 22:19:34 +00004659#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4660static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004661system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004662{
4663 ULONG value = 0;
4664
4665 Py_BEGIN_ALLOW_THREADS
4666 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4667 Py_END_ALLOW_THREADS
4668
4669 return value;
4670}
4671
4672static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004673posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004674{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004675 /* Currently Only Uptime is Provided -- Others Later */
4676 return Py_BuildValue("ddddd",
4677 (double)0 /* t.tms_utime / HZ */,
4678 (double)0 /* t.tms_stime / HZ */,
4679 (double)0 /* t.tms_cutime / HZ */,
4680 (double)0 /* t.tms_cstime / HZ */,
4681 (double)system_uptime() / 1000);
4682}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004683#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004684static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004685posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004686{
4687 struct tms t;
4688 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004689 errno = 0;
4690 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004691 if (c == (clock_t) -1)
4692 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004693 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004694 (double)t.tms_utime / HZ,
4695 (double)t.tms_stime / HZ,
4696 (double)t.tms_cutime / HZ,
4697 (double)t.tms_cstime / HZ,
4698 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004699}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004700#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004701#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004702
4703
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004704#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004705#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004706static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004707posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004708{
4709 FILETIME create, exit, kernel, user;
4710 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004711 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004712 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4713 /* The fields of a FILETIME structure are the hi and lo part
4714 of a 64-bit value expressed in 100 nanosecond units.
4715 1e7 is one second in such units; 1e-7 the inverse.
4716 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4717 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004718 return Py_BuildValue(
4719 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004720 (double)(kernel.dwHighDateTime*429.4967296 +
4721 kernel.dwLowDateTime*1e-7),
4722 (double)(user.dwHighDateTime*429.4967296 +
4723 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004724 (double)0,
4725 (double)0,
4726 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004727}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004728#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004729
4730#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004731PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004732"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004733Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004734#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004736
Guido van Rossumb6775db1994-08-01 11:34:53 +00004737#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004738PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004739"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004740Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004741
Barry Warsaw53699e91996-12-10 23:23:01 +00004742static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004743posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004744{
Guido van Rossum687dd131993-05-17 08:34:16 +00004745 if (setsid() < 0)
4746 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004747 Py_INCREF(Py_None);
4748 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004749}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004750#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004751
Guido van Rossumb6775db1994-08-01 11:34:53 +00004752#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004753PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004754"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004755Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004756
Barry Warsaw53699e91996-12-10 23:23:01 +00004757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004758posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004759{
4760 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004761 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004762 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004763 if (setpgid(pid, pgrp) < 0)
4764 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004765 Py_INCREF(Py_None);
4766 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004767}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004768#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004770
Guido van Rossumb6775db1994-08-01 11:34:53 +00004771#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004772PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004773"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004774Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004775
Barry Warsaw53699e91996-12-10 23:23:01 +00004776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004777posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004778{
4779 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004780 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004781 return NULL;
4782 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004783 if (pgid < 0)
4784 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004785 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004786}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004787#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004788
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004789
Guido van Rossumb6775db1994-08-01 11:34:53 +00004790#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004791PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004792"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004793Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004794
Barry Warsaw53699e91996-12-10 23:23:01 +00004795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004796posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004797{
4798 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004799 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004800 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004801 if (tcsetpgrp(fd, pgid) < 0)
4802 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004803 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004804 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004805}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004806#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004807
Guido van Rossum687dd131993-05-17 08:34:16 +00004808/* Functions acting on file descriptors */
4809
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004810PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004811"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004812Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004813
Barry Warsaw53699e91996-12-10 23:23:01 +00004814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004815posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004816{
Mark Hammondef8b6542001-05-13 08:04:26 +00004817 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004818 int flag;
4819 int mode = 0777;
4820 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004821
4822#ifdef MS_WINDOWS
4823 if (unicode_file_names()) {
4824 PyUnicodeObject *po;
4825 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4826 Py_BEGIN_ALLOW_THREADS
4827 /* PyUnicode_AS_UNICODE OK without thread
4828 lock as it is a simple dereference. */
4829 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4830 Py_END_ALLOW_THREADS
4831 if (fd < 0)
4832 return posix_error();
4833 return PyInt_FromLong((long)fd);
4834 }
4835 /* Drop the argument parsing error as narrow strings
4836 are also valid. */
4837 PyErr_Clear();
4838 }
4839#endif
4840
Tim Peters5aa91602002-01-30 05:46:57 +00004841 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004842 Py_FileSystemDefaultEncoding, &file,
4843 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004844 return NULL;
4845
Barry Warsaw53699e91996-12-10 23:23:01 +00004846 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004847 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004848 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004849 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004850 return posix_error_with_allocated_filename(file);
4851 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004852 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004853}
4854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004855
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004856PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004857"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004858Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004859
Barry Warsaw53699e91996-12-10 23:23:01 +00004860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004861posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004862{
4863 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004864 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004865 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004866 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004867 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004868 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004869 if (res < 0)
4870 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004871 Py_INCREF(Py_None);
4872 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004873}
4874
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004875
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004876PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004877"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004878Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004879
Barry Warsaw53699e91996-12-10 23:23:01 +00004880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004881posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004882{
4883 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004884 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004885 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004886 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004887 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004888 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004889 if (fd < 0)
4890 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004891 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004892}
4893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004894
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004895PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004896"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004897Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004898
Barry Warsaw53699e91996-12-10 23:23:01 +00004899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004900posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004901{
4902 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004903 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004904 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004905 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004906 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004907 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004908 if (res < 0)
4909 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004910 Py_INCREF(Py_None);
4911 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004912}
4913
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004914
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004915PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004916"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004917Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004918
Barry Warsaw53699e91996-12-10 23:23:01 +00004919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004920posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004921{
4922 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004923#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00004924 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004925#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004926 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004927#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004928 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004929 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004930 return NULL;
4931#ifdef SEEK_SET
4932 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4933 switch (how) {
4934 case 0: how = SEEK_SET; break;
4935 case 1: how = SEEK_CUR; break;
4936 case 2: how = SEEK_END; break;
4937 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004938#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004939
4940#if !defined(HAVE_LARGEFILE_SUPPORT)
4941 pos = PyInt_AsLong(posobj);
4942#else
4943 pos = PyLong_Check(posobj) ?
4944 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4945#endif
4946 if (PyErr_Occurred())
4947 return NULL;
4948
Barry Warsaw53699e91996-12-10 23:23:01 +00004949 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004950#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004951 res = _lseeki64(fd, pos, how);
4952#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004953 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004954#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004955 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004956 if (res < 0)
4957 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004958
4959#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004960 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004961#else
4962 return PyLong_FromLongLong(res);
4963#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004964}
4965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004966
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004967PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004968"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004969Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004970
Barry Warsaw53699e91996-12-10 23:23:01 +00004971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004972posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004973{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004974 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004975 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004976 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004977 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004978 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004979 if (buffer == NULL)
4980 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004981 Py_BEGIN_ALLOW_THREADS
4982 n = read(fd, PyString_AsString(buffer), size);
4983 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004984 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004985 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004986 return posix_error();
4987 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004988 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004989 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004990 return buffer;
4991}
4992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004993
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004994PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004995"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004996Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004997
Barry Warsaw53699e91996-12-10 23:23:01 +00004998static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004999posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005000{
5001 int fd, size;
5002 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005003 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005004 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005005 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005006 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005007 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005008 if (size < 0)
5009 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005010 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005011}
5012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005013
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005015"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005016Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005017
Barry Warsaw53699e91996-12-10 23:23:01 +00005018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005019posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005020{
5021 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005022 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005023 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005024 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005025 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005026#ifdef __VMS
5027 /* on OpenVMS we must ensure that all bytes are written to the file */
5028 fsync(fd);
5029#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005030 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005031 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005032 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005033 if (res != 0)
5034 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005035
Fred Drake699f3522000-06-29 21:12:41 +00005036 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005037}
5038
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005039
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005040PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005041"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005042Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005043
Barry Warsaw53699e91996-12-10 23:23:01 +00005044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005045posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005046{
Guido van Rossum687dd131993-05-17 08:34:16 +00005047 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005048 char *mode = "r";
5049 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005050 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005051 PyObject *f;
5052 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005053 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005054
Thomas Heller1f043e22002-11-07 16:00:59 +00005055 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5056 PyErr_Format(PyExc_ValueError,
5057 "invalid file mode '%s'", mode);
5058 return NULL;
5059 }
5060
Barry Warsaw53699e91996-12-10 23:23:01 +00005061 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005062 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005063 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005064 if (fp == NULL)
5065 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005066 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005067 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005068 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005069 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005070}
5071
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005072PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005073"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005074Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005075connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005076
5077static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005078posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005079{
5080 int fd;
5081 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5082 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005083 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005084}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005085
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005086#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005087PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005088"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005089Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005090
Barry Warsaw53699e91996-12-10 23:23:01 +00005091static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005092posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005093{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005094#if defined(PYOS_OS2)
5095 HFILE read, write;
5096 APIRET rc;
5097
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005098 Py_BEGIN_ALLOW_THREADS
5099 rc = DosCreatePipe( &read, &write, 4096);
5100 Py_END_ALLOW_THREADS
5101 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005102 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005103
5104 return Py_BuildValue("(ii)", read, write);
5105#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005106#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005107 int fds[2];
5108 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005109 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005110 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005111 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005112 if (res != 0)
5113 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005114 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005115#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005116 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005117 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005118 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005119 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005120 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005121 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005122 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005123 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005124 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5125 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005126 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005127#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005128#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005129}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005130#endif /* HAVE_PIPE */
5131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005132
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005133#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005134PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005135"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005136Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005137
Barry Warsaw53699e91996-12-10 23:23:01 +00005138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005139posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005140{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005141 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005142 int mode = 0666;
5143 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005144 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005145 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005146 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005147 res = mkfifo(filename, mode);
5148 Py_END_ALLOW_THREADS
5149 if (res < 0)
5150 return posix_error();
5151 Py_INCREF(Py_None);
5152 return Py_None;
5153}
5154#endif
5155
5156
Neal Norwitz11690112002-07-30 01:08:28 +00005157#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005158PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005159"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005160Create a filesystem node (file, device special file or named pipe)\n\
5161named filename. mode specifies both the permissions to use and the\n\
5162type of node to be created, being combined (bitwise OR) with one of\n\
5163S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005164device defines the newly created device special file (probably using\n\
5165os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005166
5167
5168static PyObject *
5169posix_mknod(PyObject *self, PyObject *args)
5170{
5171 char *filename;
5172 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005173 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005174 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005175 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005176 return NULL;
5177 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005178 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005179 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005180 if (res < 0)
5181 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005182 Py_INCREF(Py_None);
5183 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005184}
5185#endif
5186
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005187#ifdef HAVE_DEVICE_MACROS
5188PyDoc_STRVAR(posix_major__doc__,
5189"major(device) -> major number\n\
5190Extracts a device major number from a raw device number.");
5191
5192static PyObject *
5193posix_major(PyObject *self, PyObject *args)
5194{
5195 int device;
5196 if (!PyArg_ParseTuple(args, "i:major", &device))
5197 return NULL;
5198 return PyInt_FromLong((long)major(device));
5199}
5200
5201PyDoc_STRVAR(posix_minor__doc__,
5202"minor(device) -> minor number\n\
5203Extracts a device minor number from a raw device number.");
5204
5205static PyObject *
5206posix_minor(PyObject *self, PyObject *args)
5207{
5208 int device;
5209 if (!PyArg_ParseTuple(args, "i:minor", &device))
5210 return NULL;
5211 return PyInt_FromLong((long)minor(device));
5212}
5213
5214PyDoc_STRVAR(posix_makedev__doc__,
5215"makedev(major, minor) -> device number\n\
5216Composes a raw device number from the major and minor device numbers.");
5217
5218static PyObject *
5219posix_makedev(PyObject *self, PyObject *args)
5220{
5221 int major, minor;
5222 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5223 return NULL;
5224 return PyInt_FromLong((long)makedev(major, minor));
5225}
5226#endif /* device macros */
5227
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005228
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005229#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005230PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005231"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005232Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005233
Barry Warsaw53699e91996-12-10 23:23:01 +00005234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005235posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005236{
5237 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005238 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005239 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005240 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005241
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005242 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005243 return NULL;
5244
5245#if !defined(HAVE_LARGEFILE_SUPPORT)
5246 length = PyInt_AsLong(lenobj);
5247#else
5248 length = PyLong_Check(lenobj) ?
5249 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5250#endif
5251 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005252 return NULL;
5253
Barry Warsaw53699e91996-12-10 23:23:01 +00005254 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005255 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005256 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005257 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005258 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005259 return NULL;
5260 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005261 Py_INCREF(Py_None);
5262 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005263}
5264#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005265
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005266#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005267PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005268"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005269Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005270
Fred Drake762e2061999-08-26 17:23:54 +00005271/* Save putenv() parameters as values here, so we can collect them when they
5272 * get re-set with another call for the same key. */
5273static PyObject *posix_putenv_garbage;
5274
Tim Peters5aa91602002-01-30 05:46:57 +00005275static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005276posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005277{
5278 char *s1, *s2;
5279 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005280 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005281 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005282
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005283 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005284 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005285
5286#if defined(PYOS_OS2)
5287 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5288 APIRET rc;
5289
Guido van Rossumd48f2521997-12-05 22:19:34 +00005290 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5291 if (rc != NO_ERROR)
5292 return os2_error(rc);
5293
5294 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5295 APIRET rc;
5296
Guido van Rossumd48f2521997-12-05 22:19:34 +00005297 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5298 if (rc != NO_ERROR)
5299 return os2_error(rc);
5300 } else {
5301#endif
5302
Fred Drake762e2061999-08-26 17:23:54 +00005303 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005304 len = strlen(s1) + strlen(s2) + 2;
5305 /* len includes space for a trailing \0; the size arg to
5306 PyString_FromStringAndSize does not count that */
5307 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005308 if (newstr == NULL)
5309 return PyErr_NoMemory();
5310 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005311 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005312 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005313 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005314 posix_error();
5315 return NULL;
5316 }
Fred Drake762e2061999-08-26 17:23:54 +00005317 /* Install the first arg and newstr in posix_putenv_garbage;
5318 * this will cause previous value to be collected. This has to
5319 * happen after the real putenv() call because the old value
5320 * was still accessible until then. */
5321 if (PyDict_SetItem(posix_putenv_garbage,
5322 PyTuple_GET_ITEM(args, 0), newstr)) {
5323 /* really not much we can do; just leak */
5324 PyErr_Clear();
5325 }
5326 else {
5327 Py_DECREF(newstr);
5328 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005329
5330#if defined(PYOS_OS2)
5331 }
5332#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005333 Py_INCREF(Py_None);
5334 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005335}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005336#endif /* putenv */
5337
Guido van Rossumc524d952001-10-19 01:31:59 +00005338#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005339PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005340"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005341Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005342
5343static PyObject *
5344posix_unsetenv(PyObject *self, PyObject *args)
5345{
5346 char *s1;
5347
5348 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5349 return NULL;
5350
5351 unsetenv(s1);
5352
5353 /* Remove the key from posix_putenv_garbage;
5354 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005355 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005356 * old value was still accessible until then.
5357 */
5358 if (PyDict_DelItem(posix_putenv_garbage,
5359 PyTuple_GET_ITEM(args, 0))) {
5360 /* really not much we can do; just leak */
5361 PyErr_Clear();
5362 }
5363
5364 Py_INCREF(Py_None);
5365 return Py_None;
5366}
5367#endif /* unsetenv */
5368
Guido van Rossumb6a47161997-09-15 22:54:34 +00005369#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005370PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005371"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005372Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005373
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005375posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005376{
5377 int code;
5378 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005379 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005380 return NULL;
5381 message = strerror(code);
5382 if (message == NULL) {
5383 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005384 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005385 return NULL;
5386 }
5387 return PyString_FromString(message);
5388}
5389#endif /* strerror */
5390
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005391
Guido van Rossumc9641791998-08-04 15:26:23 +00005392#ifdef HAVE_SYS_WAIT_H
5393
Fred Drake106c1a02002-04-23 15:58:02 +00005394#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005395PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005396"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005397Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005398
5399static PyObject *
5400posix_WCOREDUMP(PyObject *self, PyObject *args)
5401{
5402#ifdef UNION_WAIT
5403 union wait status;
5404#define status_i (status.w_status)
5405#else
5406 int status;
5407#define status_i status
5408#endif
5409 status_i = 0;
5410
5411 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5412 {
5413 return NULL;
5414 }
5415
5416 return PyBool_FromLong(WCOREDUMP(status));
5417#undef status_i
5418}
5419#endif /* WCOREDUMP */
5420
5421#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005422PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005423"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005424Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005425job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005426
5427static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005428posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005429{
5430#ifdef UNION_WAIT
5431 union wait status;
5432#define status_i (status.w_status)
5433#else
5434 int status;
5435#define status_i status
5436#endif
5437 status_i = 0;
5438
5439 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5440 {
5441 return NULL;
5442 }
5443
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005444 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005445#undef status_i
5446}
5447#endif /* WIFCONTINUED */
5448
Guido van Rossumc9641791998-08-04 15:26:23 +00005449#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005450PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005451"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005452Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005453
5454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005455posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005456{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005457#ifdef UNION_WAIT
5458 union wait status;
5459#define status_i (status.w_status)
5460#else
5461 int status;
5462#define status_i status
5463#endif
5464 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005465
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005466 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005467 {
5468 return NULL;
5469 }
Tim Peters5aa91602002-01-30 05:46:57 +00005470
Fred Drake106c1a02002-04-23 15:58:02 +00005471 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005472#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005473}
5474#endif /* WIFSTOPPED */
5475
5476#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005477PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005478"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005479Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005480
5481static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005482posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005483{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005484#ifdef UNION_WAIT
5485 union wait status;
5486#define status_i (status.w_status)
5487#else
5488 int status;
5489#define status_i status
5490#endif
5491 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005492
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005493 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005494 {
5495 return NULL;
5496 }
Tim Peters5aa91602002-01-30 05:46:57 +00005497
Fred Drake106c1a02002-04-23 15:58:02 +00005498 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005499#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005500}
5501#endif /* WIFSIGNALED */
5502
5503#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005504PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005505"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005506Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005507system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005508
5509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005510posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005511{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005512#ifdef UNION_WAIT
5513 union wait status;
5514#define status_i (status.w_status)
5515#else
5516 int status;
5517#define status_i status
5518#endif
5519 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005520
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005521 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005522 {
5523 return NULL;
5524 }
Tim Peters5aa91602002-01-30 05:46:57 +00005525
Fred Drake106c1a02002-04-23 15:58:02 +00005526 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005527#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005528}
5529#endif /* WIFEXITED */
5530
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005531#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005532PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005533"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005534Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005535
5536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005537posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005538{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005539#ifdef UNION_WAIT
5540 union wait status;
5541#define status_i (status.w_status)
5542#else
5543 int status;
5544#define status_i status
5545#endif
5546 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005547
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005548 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005549 {
5550 return NULL;
5551 }
Tim Peters5aa91602002-01-30 05:46:57 +00005552
Guido van Rossumc9641791998-08-04 15:26:23 +00005553 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005554#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005555}
5556#endif /* WEXITSTATUS */
5557
5558#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005559PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005560"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005561Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005562value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005563
5564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005565posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005566{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005567#ifdef UNION_WAIT
5568 union wait status;
5569#define status_i (status.w_status)
5570#else
5571 int status;
5572#define status_i status
5573#endif
5574 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005575
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005576 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005577 {
5578 return NULL;
5579 }
Tim Peters5aa91602002-01-30 05:46:57 +00005580
Guido van Rossumc9641791998-08-04 15:26:23 +00005581 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005582#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005583}
5584#endif /* WTERMSIG */
5585
5586#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005587PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005588"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005589Return the signal that stopped the process that provided\n\
5590the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005591
5592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005593posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005594{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005595#ifdef UNION_WAIT
5596 union wait status;
5597#define status_i (status.w_status)
5598#else
5599 int status;
5600#define status_i status
5601#endif
5602 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005603
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005604 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005605 {
5606 return NULL;
5607 }
Tim Peters5aa91602002-01-30 05:46:57 +00005608
Guido van Rossumc9641791998-08-04 15:26:23 +00005609 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005610#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005611}
5612#endif /* WSTOPSIG */
5613
5614#endif /* HAVE_SYS_WAIT_H */
5615
5616
Guido van Rossum94f6f721999-01-06 18:42:14 +00005617#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005618#ifdef _SCO_DS
5619/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5620 needed definitions in sys/statvfs.h */
5621#define _SVID3
5622#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005623#include <sys/statvfs.h>
5624
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005625static PyObject*
5626_pystatvfs_fromstructstatvfs(struct statvfs st) {
5627 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5628 if (v == NULL)
5629 return NULL;
5630
5631#if !defined(HAVE_LARGEFILE_SUPPORT)
5632 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5633 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5634 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5635 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5636 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5637 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5638 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5639 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5640 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5641 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5642#else
5643 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5644 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005645 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005646 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005647 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005648 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005649 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005650 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005651 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005652 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005653 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005654 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005655 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005656 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005657 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5658 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5659#endif
5660
5661 return v;
5662}
5663
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005664PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005665"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005666Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005667
5668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005669posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005670{
5671 int fd, res;
5672 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005673
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005674 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005675 return NULL;
5676 Py_BEGIN_ALLOW_THREADS
5677 res = fstatvfs(fd, &st);
5678 Py_END_ALLOW_THREADS
5679 if (res != 0)
5680 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005681
5682 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005683}
5684#endif /* HAVE_FSTATVFS */
5685
5686
5687#if defined(HAVE_STATVFS)
5688#include <sys/statvfs.h>
5689
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005691"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005692Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005693
5694static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005695posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005696{
5697 char *path;
5698 int res;
5699 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005700 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005701 return NULL;
5702 Py_BEGIN_ALLOW_THREADS
5703 res = statvfs(path, &st);
5704 Py_END_ALLOW_THREADS
5705 if (res != 0)
5706 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005707
5708 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005709}
5710#endif /* HAVE_STATVFS */
5711
5712
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005713#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005714PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005715"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005716Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005717The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005718or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005719
5720static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005721posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005722{
5723 PyObject *result = NULL;
5724 char *dir = NULL;
5725 char *pfx = NULL;
5726 char *name;
5727
5728 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5729 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005730
5731 if (PyErr_Warn(PyExc_RuntimeWarning,
5732 "tempnam is a potential security risk to your program") < 0)
5733 return NULL;
5734
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005735#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005736 name = _tempnam(dir, pfx);
5737#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005738 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005739#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005740 if (name == NULL)
5741 return PyErr_NoMemory();
5742 result = PyString_FromString(name);
5743 free(name);
5744 return result;
5745}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005746#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005747
5748
5749#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005750PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005751"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005752Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005753
5754static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005755posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005756{
5757 FILE *fp;
5758
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005759 fp = tmpfile();
5760 if (fp == NULL)
5761 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005762 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005763}
5764#endif
5765
5766
5767#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005768PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005769"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005770Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005771
5772static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005773posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005774{
5775 char buffer[L_tmpnam];
5776 char *name;
5777
Skip Montanaro95618b52001-08-18 18:52:10 +00005778 if (PyErr_Warn(PyExc_RuntimeWarning,
5779 "tmpnam is a potential security risk to your program") < 0)
5780 return NULL;
5781
Greg Wardb48bc172000-03-01 21:51:56 +00005782#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005783 name = tmpnam_r(buffer);
5784#else
5785 name = tmpnam(buffer);
5786#endif
5787 if (name == NULL) {
5788 PyErr_SetObject(PyExc_OSError,
5789 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005790#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005791 "unexpected NULL from tmpnam_r"
5792#else
5793 "unexpected NULL from tmpnam"
5794#endif
5795 ));
5796 return NULL;
5797 }
5798 return PyString_FromString(buffer);
5799}
5800#endif
5801
5802
Fred Drakec9680921999-12-13 16:37:25 +00005803/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5804 * It maps strings representing configuration variable names to
5805 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005806 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005807 * rarely-used constants. There are three separate tables that use
5808 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005809 *
5810 * This code is always included, even if none of the interfaces that
5811 * need it are included. The #if hackery needed to avoid it would be
5812 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005813 */
5814struct constdef {
5815 char *name;
5816 long value;
5817};
5818
Fred Drake12c6e2d1999-12-14 21:25:03 +00005819static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005820conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5821 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005822{
5823 if (PyInt_Check(arg)) {
5824 *valuep = PyInt_AS_LONG(arg);
5825 return 1;
5826 }
5827 if (PyString_Check(arg)) {
5828 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005829 size_t lo = 0;
5830 size_t mid;
5831 size_t hi = tablesize;
5832 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005833 char *confname = PyString_AS_STRING(arg);
5834 while (lo < hi) {
5835 mid = (lo + hi) / 2;
5836 cmp = strcmp(confname, table[mid].name);
5837 if (cmp < 0)
5838 hi = mid;
5839 else if (cmp > 0)
5840 lo = mid + 1;
5841 else {
5842 *valuep = table[mid].value;
5843 return 1;
5844 }
5845 }
5846 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5847 }
5848 else
5849 PyErr_SetString(PyExc_TypeError,
5850 "configuration names must be strings or integers");
5851 return 0;
5852}
5853
5854
5855#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5856static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005857#ifdef _PC_ABI_AIO_XFER_MAX
5858 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5859#endif
5860#ifdef _PC_ABI_ASYNC_IO
5861 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5862#endif
Fred Drakec9680921999-12-13 16:37:25 +00005863#ifdef _PC_ASYNC_IO
5864 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5865#endif
5866#ifdef _PC_CHOWN_RESTRICTED
5867 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5868#endif
5869#ifdef _PC_FILESIZEBITS
5870 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5871#endif
5872#ifdef _PC_LAST
5873 {"PC_LAST", _PC_LAST},
5874#endif
5875#ifdef _PC_LINK_MAX
5876 {"PC_LINK_MAX", _PC_LINK_MAX},
5877#endif
5878#ifdef _PC_MAX_CANON
5879 {"PC_MAX_CANON", _PC_MAX_CANON},
5880#endif
5881#ifdef _PC_MAX_INPUT
5882 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5883#endif
5884#ifdef _PC_NAME_MAX
5885 {"PC_NAME_MAX", _PC_NAME_MAX},
5886#endif
5887#ifdef _PC_NO_TRUNC
5888 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5889#endif
5890#ifdef _PC_PATH_MAX
5891 {"PC_PATH_MAX", _PC_PATH_MAX},
5892#endif
5893#ifdef _PC_PIPE_BUF
5894 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5895#endif
5896#ifdef _PC_PRIO_IO
5897 {"PC_PRIO_IO", _PC_PRIO_IO},
5898#endif
5899#ifdef _PC_SOCK_MAXBUF
5900 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5901#endif
5902#ifdef _PC_SYNC_IO
5903 {"PC_SYNC_IO", _PC_SYNC_IO},
5904#endif
5905#ifdef _PC_VDISABLE
5906 {"PC_VDISABLE", _PC_VDISABLE},
5907#endif
5908};
5909
Fred Drakec9680921999-12-13 16:37:25 +00005910static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005911conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005912{
5913 return conv_confname(arg, valuep, posix_constants_pathconf,
5914 sizeof(posix_constants_pathconf)
5915 / sizeof(struct constdef));
5916}
5917#endif
5918
5919#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005920PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005921"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005922Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005923If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005924
5925static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005926posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005927{
5928 PyObject *result = NULL;
5929 int name, fd;
5930
Fred Drake12c6e2d1999-12-14 21:25:03 +00005931 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5932 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005933 long limit;
5934
5935 errno = 0;
5936 limit = fpathconf(fd, name);
5937 if (limit == -1 && errno != 0)
5938 posix_error();
5939 else
5940 result = PyInt_FromLong(limit);
5941 }
5942 return result;
5943}
5944#endif
5945
5946
5947#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005948PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005949"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005950Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005951If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005952
5953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005954posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005955{
5956 PyObject *result = NULL;
5957 int name;
5958 char *path;
5959
5960 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5961 conv_path_confname, &name)) {
5962 long limit;
5963
5964 errno = 0;
5965 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005966 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005967 if (errno == EINVAL)
5968 /* could be a path or name problem */
5969 posix_error();
5970 else
5971 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005972 }
Fred Drakec9680921999-12-13 16:37:25 +00005973 else
5974 result = PyInt_FromLong(limit);
5975 }
5976 return result;
5977}
5978#endif
5979
5980#ifdef HAVE_CONFSTR
5981static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005982#ifdef _CS_ARCHITECTURE
5983 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5984#endif
5985#ifdef _CS_HOSTNAME
5986 {"CS_HOSTNAME", _CS_HOSTNAME},
5987#endif
5988#ifdef _CS_HW_PROVIDER
5989 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5990#endif
5991#ifdef _CS_HW_SERIAL
5992 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5993#endif
5994#ifdef _CS_INITTAB_NAME
5995 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5996#endif
Fred Drakec9680921999-12-13 16:37:25 +00005997#ifdef _CS_LFS64_CFLAGS
5998 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5999#endif
6000#ifdef _CS_LFS64_LDFLAGS
6001 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6002#endif
6003#ifdef _CS_LFS64_LIBS
6004 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6005#endif
6006#ifdef _CS_LFS64_LINTFLAGS
6007 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6008#endif
6009#ifdef _CS_LFS_CFLAGS
6010 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6011#endif
6012#ifdef _CS_LFS_LDFLAGS
6013 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6014#endif
6015#ifdef _CS_LFS_LIBS
6016 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6017#endif
6018#ifdef _CS_LFS_LINTFLAGS
6019 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6020#endif
Fred Draked86ed291999-12-15 15:34:33 +00006021#ifdef _CS_MACHINE
6022 {"CS_MACHINE", _CS_MACHINE},
6023#endif
Fred Drakec9680921999-12-13 16:37:25 +00006024#ifdef _CS_PATH
6025 {"CS_PATH", _CS_PATH},
6026#endif
Fred Draked86ed291999-12-15 15:34:33 +00006027#ifdef _CS_RELEASE
6028 {"CS_RELEASE", _CS_RELEASE},
6029#endif
6030#ifdef _CS_SRPC_DOMAIN
6031 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6032#endif
6033#ifdef _CS_SYSNAME
6034 {"CS_SYSNAME", _CS_SYSNAME},
6035#endif
6036#ifdef _CS_VERSION
6037 {"CS_VERSION", _CS_VERSION},
6038#endif
Fred Drakec9680921999-12-13 16:37:25 +00006039#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6040 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6041#endif
6042#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6043 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6044#endif
6045#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6046 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6047#endif
6048#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6049 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6050#endif
6051#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6052 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6053#endif
6054#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6055 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6056#endif
6057#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6058 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6059#endif
6060#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6061 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6062#endif
6063#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6064 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6065#endif
6066#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6067 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6068#endif
6069#ifdef _CS_XBS5_LP64_OFF64_LIBS
6070 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6071#endif
6072#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6073 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6074#endif
6075#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6076 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6077#endif
6078#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6079 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6080#endif
6081#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6082 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6083#endif
6084#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6085 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6086#endif
Fred Draked86ed291999-12-15 15:34:33 +00006087#ifdef _MIPS_CS_AVAIL_PROCESSORS
6088 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6089#endif
6090#ifdef _MIPS_CS_BASE
6091 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6092#endif
6093#ifdef _MIPS_CS_HOSTID
6094 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6095#endif
6096#ifdef _MIPS_CS_HW_NAME
6097 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6098#endif
6099#ifdef _MIPS_CS_NUM_PROCESSORS
6100 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6101#endif
6102#ifdef _MIPS_CS_OSREL_MAJ
6103 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6104#endif
6105#ifdef _MIPS_CS_OSREL_MIN
6106 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6107#endif
6108#ifdef _MIPS_CS_OSREL_PATCH
6109 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6110#endif
6111#ifdef _MIPS_CS_OS_NAME
6112 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6113#endif
6114#ifdef _MIPS_CS_OS_PROVIDER
6115 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6116#endif
6117#ifdef _MIPS_CS_PROCESSORS
6118 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6119#endif
6120#ifdef _MIPS_CS_SERIAL
6121 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6122#endif
6123#ifdef _MIPS_CS_VENDOR
6124 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6125#endif
Fred Drakec9680921999-12-13 16:37:25 +00006126};
6127
6128static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006129conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006130{
6131 return conv_confname(arg, valuep, posix_constants_confstr,
6132 sizeof(posix_constants_confstr)
6133 / sizeof(struct constdef));
6134}
6135
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006137"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006138Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006139
6140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006141posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006142{
6143 PyObject *result = NULL;
6144 int name;
6145 char buffer[64];
6146
6147 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6148 int len = confstr(name, buffer, sizeof(buffer));
6149
Fred Drakec9680921999-12-13 16:37:25 +00006150 errno = 0;
6151 if (len == 0) {
6152 if (errno != 0)
6153 posix_error();
6154 else
6155 result = PyString_FromString("");
6156 }
6157 else {
6158 if (len >= sizeof(buffer)) {
6159 result = PyString_FromStringAndSize(NULL, len);
6160 if (result != NULL)
6161 confstr(name, PyString_AS_STRING(result), len+1);
6162 }
6163 else
6164 result = PyString_FromString(buffer);
6165 }
6166 }
6167 return result;
6168}
6169#endif
6170
6171
6172#ifdef HAVE_SYSCONF
6173static struct constdef posix_constants_sysconf[] = {
6174#ifdef _SC_2_CHAR_TERM
6175 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6176#endif
6177#ifdef _SC_2_C_BIND
6178 {"SC_2_C_BIND", _SC_2_C_BIND},
6179#endif
6180#ifdef _SC_2_C_DEV
6181 {"SC_2_C_DEV", _SC_2_C_DEV},
6182#endif
6183#ifdef _SC_2_C_VERSION
6184 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6185#endif
6186#ifdef _SC_2_FORT_DEV
6187 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6188#endif
6189#ifdef _SC_2_FORT_RUN
6190 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6191#endif
6192#ifdef _SC_2_LOCALEDEF
6193 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6194#endif
6195#ifdef _SC_2_SW_DEV
6196 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6197#endif
6198#ifdef _SC_2_UPE
6199 {"SC_2_UPE", _SC_2_UPE},
6200#endif
6201#ifdef _SC_2_VERSION
6202 {"SC_2_VERSION", _SC_2_VERSION},
6203#endif
Fred Draked86ed291999-12-15 15:34:33 +00006204#ifdef _SC_ABI_ASYNCHRONOUS_IO
6205 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6206#endif
6207#ifdef _SC_ACL
6208 {"SC_ACL", _SC_ACL},
6209#endif
Fred Drakec9680921999-12-13 16:37:25 +00006210#ifdef _SC_AIO_LISTIO_MAX
6211 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6212#endif
Fred Drakec9680921999-12-13 16:37:25 +00006213#ifdef _SC_AIO_MAX
6214 {"SC_AIO_MAX", _SC_AIO_MAX},
6215#endif
6216#ifdef _SC_AIO_PRIO_DELTA_MAX
6217 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6218#endif
6219#ifdef _SC_ARG_MAX
6220 {"SC_ARG_MAX", _SC_ARG_MAX},
6221#endif
6222#ifdef _SC_ASYNCHRONOUS_IO
6223 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6224#endif
6225#ifdef _SC_ATEXIT_MAX
6226 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6227#endif
Fred Draked86ed291999-12-15 15:34:33 +00006228#ifdef _SC_AUDIT
6229 {"SC_AUDIT", _SC_AUDIT},
6230#endif
Fred Drakec9680921999-12-13 16:37:25 +00006231#ifdef _SC_AVPHYS_PAGES
6232 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6233#endif
6234#ifdef _SC_BC_BASE_MAX
6235 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6236#endif
6237#ifdef _SC_BC_DIM_MAX
6238 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6239#endif
6240#ifdef _SC_BC_SCALE_MAX
6241 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6242#endif
6243#ifdef _SC_BC_STRING_MAX
6244 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6245#endif
Fred Draked86ed291999-12-15 15:34:33 +00006246#ifdef _SC_CAP
6247 {"SC_CAP", _SC_CAP},
6248#endif
Fred Drakec9680921999-12-13 16:37:25 +00006249#ifdef _SC_CHARCLASS_NAME_MAX
6250 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6251#endif
6252#ifdef _SC_CHAR_BIT
6253 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6254#endif
6255#ifdef _SC_CHAR_MAX
6256 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6257#endif
6258#ifdef _SC_CHAR_MIN
6259 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6260#endif
6261#ifdef _SC_CHILD_MAX
6262 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6263#endif
6264#ifdef _SC_CLK_TCK
6265 {"SC_CLK_TCK", _SC_CLK_TCK},
6266#endif
6267#ifdef _SC_COHER_BLKSZ
6268 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6269#endif
6270#ifdef _SC_COLL_WEIGHTS_MAX
6271 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6272#endif
6273#ifdef _SC_DCACHE_ASSOC
6274 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6275#endif
6276#ifdef _SC_DCACHE_BLKSZ
6277 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6278#endif
6279#ifdef _SC_DCACHE_LINESZ
6280 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6281#endif
6282#ifdef _SC_DCACHE_SZ
6283 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6284#endif
6285#ifdef _SC_DCACHE_TBLKSZ
6286 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6287#endif
6288#ifdef _SC_DELAYTIMER_MAX
6289 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6290#endif
6291#ifdef _SC_EQUIV_CLASS_MAX
6292 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6293#endif
6294#ifdef _SC_EXPR_NEST_MAX
6295 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6296#endif
6297#ifdef _SC_FSYNC
6298 {"SC_FSYNC", _SC_FSYNC},
6299#endif
6300#ifdef _SC_GETGR_R_SIZE_MAX
6301 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6302#endif
6303#ifdef _SC_GETPW_R_SIZE_MAX
6304 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6305#endif
6306#ifdef _SC_ICACHE_ASSOC
6307 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6308#endif
6309#ifdef _SC_ICACHE_BLKSZ
6310 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6311#endif
6312#ifdef _SC_ICACHE_LINESZ
6313 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6314#endif
6315#ifdef _SC_ICACHE_SZ
6316 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6317#endif
Fred Draked86ed291999-12-15 15:34:33 +00006318#ifdef _SC_INF
6319 {"SC_INF", _SC_INF},
6320#endif
Fred Drakec9680921999-12-13 16:37:25 +00006321#ifdef _SC_INT_MAX
6322 {"SC_INT_MAX", _SC_INT_MAX},
6323#endif
6324#ifdef _SC_INT_MIN
6325 {"SC_INT_MIN", _SC_INT_MIN},
6326#endif
6327#ifdef _SC_IOV_MAX
6328 {"SC_IOV_MAX", _SC_IOV_MAX},
6329#endif
Fred Draked86ed291999-12-15 15:34:33 +00006330#ifdef _SC_IP_SECOPTS
6331 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6332#endif
Fred Drakec9680921999-12-13 16:37:25 +00006333#ifdef _SC_JOB_CONTROL
6334 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6335#endif
Fred Draked86ed291999-12-15 15:34:33 +00006336#ifdef _SC_KERN_POINTERS
6337 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6338#endif
6339#ifdef _SC_KERN_SIM
6340 {"SC_KERN_SIM", _SC_KERN_SIM},
6341#endif
Fred Drakec9680921999-12-13 16:37:25 +00006342#ifdef _SC_LINE_MAX
6343 {"SC_LINE_MAX", _SC_LINE_MAX},
6344#endif
6345#ifdef _SC_LOGIN_NAME_MAX
6346 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6347#endif
6348#ifdef _SC_LOGNAME_MAX
6349 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6350#endif
6351#ifdef _SC_LONG_BIT
6352 {"SC_LONG_BIT", _SC_LONG_BIT},
6353#endif
Fred Draked86ed291999-12-15 15:34:33 +00006354#ifdef _SC_MAC
6355 {"SC_MAC", _SC_MAC},
6356#endif
Fred Drakec9680921999-12-13 16:37:25 +00006357#ifdef _SC_MAPPED_FILES
6358 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6359#endif
6360#ifdef _SC_MAXPID
6361 {"SC_MAXPID", _SC_MAXPID},
6362#endif
6363#ifdef _SC_MB_LEN_MAX
6364 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6365#endif
6366#ifdef _SC_MEMLOCK
6367 {"SC_MEMLOCK", _SC_MEMLOCK},
6368#endif
6369#ifdef _SC_MEMLOCK_RANGE
6370 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6371#endif
6372#ifdef _SC_MEMORY_PROTECTION
6373 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6374#endif
6375#ifdef _SC_MESSAGE_PASSING
6376 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6377#endif
Fred Draked86ed291999-12-15 15:34:33 +00006378#ifdef _SC_MMAP_FIXED_ALIGNMENT
6379 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6380#endif
Fred Drakec9680921999-12-13 16:37:25 +00006381#ifdef _SC_MQ_OPEN_MAX
6382 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6383#endif
6384#ifdef _SC_MQ_PRIO_MAX
6385 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6386#endif
Fred Draked86ed291999-12-15 15:34:33 +00006387#ifdef _SC_NACLS_MAX
6388 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6389#endif
Fred Drakec9680921999-12-13 16:37:25 +00006390#ifdef _SC_NGROUPS_MAX
6391 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6392#endif
6393#ifdef _SC_NL_ARGMAX
6394 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6395#endif
6396#ifdef _SC_NL_LANGMAX
6397 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6398#endif
6399#ifdef _SC_NL_MSGMAX
6400 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6401#endif
6402#ifdef _SC_NL_NMAX
6403 {"SC_NL_NMAX", _SC_NL_NMAX},
6404#endif
6405#ifdef _SC_NL_SETMAX
6406 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6407#endif
6408#ifdef _SC_NL_TEXTMAX
6409 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6410#endif
6411#ifdef _SC_NPROCESSORS_CONF
6412 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6413#endif
6414#ifdef _SC_NPROCESSORS_ONLN
6415 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6416#endif
Fred Draked86ed291999-12-15 15:34:33 +00006417#ifdef _SC_NPROC_CONF
6418 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6419#endif
6420#ifdef _SC_NPROC_ONLN
6421 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6422#endif
Fred Drakec9680921999-12-13 16:37:25 +00006423#ifdef _SC_NZERO
6424 {"SC_NZERO", _SC_NZERO},
6425#endif
6426#ifdef _SC_OPEN_MAX
6427 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6428#endif
6429#ifdef _SC_PAGESIZE
6430 {"SC_PAGESIZE", _SC_PAGESIZE},
6431#endif
6432#ifdef _SC_PAGE_SIZE
6433 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6434#endif
6435#ifdef _SC_PASS_MAX
6436 {"SC_PASS_MAX", _SC_PASS_MAX},
6437#endif
6438#ifdef _SC_PHYS_PAGES
6439 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6440#endif
6441#ifdef _SC_PII
6442 {"SC_PII", _SC_PII},
6443#endif
6444#ifdef _SC_PII_INTERNET
6445 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6446#endif
6447#ifdef _SC_PII_INTERNET_DGRAM
6448 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6449#endif
6450#ifdef _SC_PII_INTERNET_STREAM
6451 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6452#endif
6453#ifdef _SC_PII_OSI
6454 {"SC_PII_OSI", _SC_PII_OSI},
6455#endif
6456#ifdef _SC_PII_OSI_CLTS
6457 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6458#endif
6459#ifdef _SC_PII_OSI_COTS
6460 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6461#endif
6462#ifdef _SC_PII_OSI_M
6463 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6464#endif
6465#ifdef _SC_PII_SOCKET
6466 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6467#endif
6468#ifdef _SC_PII_XTI
6469 {"SC_PII_XTI", _SC_PII_XTI},
6470#endif
6471#ifdef _SC_POLL
6472 {"SC_POLL", _SC_POLL},
6473#endif
6474#ifdef _SC_PRIORITIZED_IO
6475 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6476#endif
6477#ifdef _SC_PRIORITY_SCHEDULING
6478 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6479#endif
6480#ifdef _SC_REALTIME_SIGNALS
6481 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6482#endif
6483#ifdef _SC_RE_DUP_MAX
6484 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6485#endif
6486#ifdef _SC_RTSIG_MAX
6487 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6488#endif
6489#ifdef _SC_SAVED_IDS
6490 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6491#endif
6492#ifdef _SC_SCHAR_MAX
6493 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6494#endif
6495#ifdef _SC_SCHAR_MIN
6496 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6497#endif
6498#ifdef _SC_SELECT
6499 {"SC_SELECT", _SC_SELECT},
6500#endif
6501#ifdef _SC_SEMAPHORES
6502 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6503#endif
6504#ifdef _SC_SEM_NSEMS_MAX
6505 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6506#endif
6507#ifdef _SC_SEM_VALUE_MAX
6508 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6509#endif
6510#ifdef _SC_SHARED_MEMORY_OBJECTS
6511 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6512#endif
6513#ifdef _SC_SHRT_MAX
6514 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6515#endif
6516#ifdef _SC_SHRT_MIN
6517 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6518#endif
6519#ifdef _SC_SIGQUEUE_MAX
6520 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6521#endif
6522#ifdef _SC_SIGRT_MAX
6523 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6524#endif
6525#ifdef _SC_SIGRT_MIN
6526 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6527#endif
Fred Draked86ed291999-12-15 15:34:33 +00006528#ifdef _SC_SOFTPOWER
6529 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6530#endif
Fred Drakec9680921999-12-13 16:37:25 +00006531#ifdef _SC_SPLIT_CACHE
6532 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6533#endif
6534#ifdef _SC_SSIZE_MAX
6535 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6536#endif
6537#ifdef _SC_STACK_PROT
6538 {"SC_STACK_PROT", _SC_STACK_PROT},
6539#endif
6540#ifdef _SC_STREAM_MAX
6541 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6542#endif
6543#ifdef _SC_SYNCHRONIZED_IO
6544 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6545#endif
6546#ifdef _SC_THREADS
6547 {"SC_THREADS", _SC_THREADS},
6548#endif
6549#ifdef _SC_THREAD_ATTR_STACKADDR
6550 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6551#endif
6552#ifdef _SC_THREAD_ATTR_STACKSIZE
6553 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6554#endif
6555#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6556 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6557#endif
6558#ifdef _SC_THREAD_KEYS_MAX
6559 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6560#endif
6561#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6562 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6563#endif
6564#ifdef _SC_THREAD_PRIO_INHERIT
6565 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6566#endif
6567#ifdef _SC_THREAD_PRIO_PROTECT
6568 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6569#endif
6570#ifdef _SC_THREAD_PROCESS_SHARED
6571 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6572#endif
6573#ifdef _SC_THREAD_SAFE_FUNCTIONS
6574 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6575#endif
6576#ifdef _SC_THREAD_STACK_MIN
6577 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6578#endif
6579#ifdef _SC_THREAD_THREADS_MAX
6580 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6581#endif
6582#ifdef _SC_TIMERS
6583 {"SC_TIMERS", _SC_TIMERS},
6584#endif
6585#ifdef _SC_TIMER_MAX
6586 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6587#endif
6588#ifdef _SC_TTY_NAME_MAX
6589 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6590#endif
6591#ifdef _SC_TZNAME_MAX
6592 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6593#endif
6594#ifdef _SC_T_IOV_MAX
6595 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6596#endif
6597#ifdef _SC_UCHAR_MAX
6598 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6599#endif
6600#ifdef _SC_UINT_MAX
6601 {"SC_UINT_MAX", _SC_UINT_MAX},
6602#endif
6603#ifdef _SC_UIO_MAXIOV
6604 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6605#endif
6606#ifdef _SC_ULONG_MAX
6607 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6608#endif
6609#ifdef _SC_USHRT_MAX
6610 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6611#endif
6612#ifdef _SC_VERSION
6613 {"SC_VERSION", _SC_VERSION},
6614#endif
6615#ifdef _SC_WORD_BIT
6616 {"SC_WORD_BIT", _SC_WORD_BIT},
6617#endif
6618#ifdef _SC_XBS5_ILP32_OFF32
6619 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6620#endif
6621#ifdef _SC_XBS5_ILP32_OFFBIG
6622 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6623#endif
6624#ifdef _SC_XBS5_LP64_OFF64
6625 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6626#endif
6627#ifdef _SC_XBS5_LPBIG_OFFBIG
6628 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6629#endif
6630#ifdef _SC_XOPEN_CRYPT
6631 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6632#endif
6633#ifdef _SC_XOPEN_ENH_I18N
6634 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6635#endif
6636#ifdef _SC_XOPEN_LEGACY
6637 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6638#endif
6639#ifdef _SC_XOPEN_REALTIME
6640 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6641#endif
6642#ifdef _SC_XOPEN_REALTIME_THREADS
6643 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6644#endif
6645#ifdef _SC_XOPEN_SHM
6646 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6647#endif
6648#ifdef _SC_XOPEN_UNIX
6649 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6650#endif
6651#ifdef _SC_XOPEN_VERSION
6652 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6653#endif
6654#ifdef _SC_XOPEN_XCU_VERSION
6655 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6656#endif
6657#ifdef _SC_XOPEN_XPG2
6658 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6659#endif
6660#ifdef _SC_XOPEN_XPG3
6661 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6662#endif
6663#ifdef _SC_XOPEN_XPG4
6664 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6665#endif
6666};
6667
6668static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006669conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006670{
6671 return conv_confname(arg, valuep, posix_constants_sysconf,
6672 sizeof(posix_constants_sysconf)
6673 / sizeof(struct constdef));
6674}
6675
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006676PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006677"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006678Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006679
6680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006681posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006682{
6683 PyObject *result = NULL;
6684 int name;
6685
6686 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6687 int value;
6688
6689 errno = 0;
6690 value = sysconf(name);
6691 if (value == -1 && errno != 0)
6692 posix_error();
6693 else
6694 result = PyInt_FromLong(value);
6695 }
6696 return result;
6697}
6698#endif
6699
6700
Fred Drakebec628d1999-12-15 18:31:10 +00006701/* This code is used to ensure that the tables of configuration value names
6702 * are in sorted order as required by conv_confname(), and also to build the
6703 * the exported dictionaries that are used to publish information about the
6704 * names available on the host platform.
6705 *
6706 * Sorting the table at runtime ensures that the table is properly ordered
6707 * when used, even for platforms we're not able to test on. It also makes
6708 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006709 */
Fred Drakebec628d1999-12-15 18:31:10 +00006710
6711static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006712cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006713{
6714 const struct constdef *c1 =
6715 (const struct constdef *) v1;
6716 const struct constdef *c2 =
6717 (const struct constdef *) v2;
6718
6719 return strcmp(c1->name, c2->name);
6720}
6721
6722static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006723setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006724 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006725{
Fred Drakebec628d1999-12-15 18:31:10 +00006726 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006727 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006728
6729 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6730 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006731 if (d == NULL)
6732 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006733
Barry Warsaw3155db32000-04-13 15:20:40 +00006734 for (i=0; i < tablesize; ++i) {
6735 PyObject *o = PyInt_FromLong(table[i].value);
6736 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6737 Py_XDECREF(o);
6738 Py_DECREF(d);
6739 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006740 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006741 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006742 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006743 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006744}
6745
Fred Drakebec628d1999-12-15 18:31:10 +00006746/* Return -1 on failure, 0 on success. */
6747static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006748setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006749{
6750#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006751 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006752 sizeof(posix_constants_pathconf)
6753 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006754 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006755 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006756#endif
6757#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006758 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006759 sizeof(posix_constants_confstr)
6760 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006761 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006762 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006763#endif
6764#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006765 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006766 sizeof(posix_constants_sysconf)
6767 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006768 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006769 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006770#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006771 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006772}
Fred Draked86ed291999-12-15 15:34:33 +00006773
6774
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006775PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006776"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006777Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006778in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006779
6780static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006781posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006782{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006783 abort();
6784 /*NOTREACHED*/
6785 Py_FatalError("abort() called from Python code didn't abort!");
6786 return NULL;
6787}
Fred Drakebec628d1999-12-15 18:31:10 +00006788
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006789#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006790PyDoc_STRVAR(win32_startfile__doc__,
6791"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006792\n\
6793This acts like double-clicking the file in Explorer, or giving the file\n\
6794name as an argument to the DOS \"start\" command: the file is opened\n\
6795with whatever application (if any) its extension is associated.\n\
6796\n\
6797startfile returns as soon as the associated application is launched.\n\
6798There is no option to wait for the application to close, and no way\n\
6799to retrieve the application's exit status.\n\
6800\n\
6801The filepath is relative to the current directory. If you want to use\n\
6802an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006803the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006804
6805static PyObject *
6806win32_startfile(PyObject *self, PyObject *args)
6807{
6808 char *filepath;
6809 HINSTANCE rc;
6810 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6811 return NULL;
6812 Py_BEGIN_ALLOW_THREADS
6813 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6814 Py_END_ALLOW_THREADS
6815 if (rc <= (HINSTANCE)32)
6816 return win32_error("startfile", filepath);
6817 Py_INCREF(Py_None);
6818 return Py_None;
6819}
6820#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006821
Martin v. Löwis438b5342002-12-27 10:16:42 +00006822#ifdef HAVE_GETLOADAVG
6823PyDoc_STRVAR(posix_getloadavg__doc__,
6824"getloadavg() -> (float, float, float)\n\n\
6825Return the number of processes in the system run queue averaged over\n\
6826the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6827was unobtainable");
6828
6829static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006830posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006831{
6832 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006833 if (getloadavg(loadavg, 3)!=3) {
6834 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6835 return NULL;
6836 } else
6837 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6838}
6839#endif
6840
6841
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006842static PyMethodDef posix_methods[] = {
6843 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6844#ifdef HAVE_TTYNAME
6845 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6846#endif
6847 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6848 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006849#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006850 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006851#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006852#ifdef HAVE_LCHOWN
6853 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6854#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006855#ifdef HAVE_CHROOT
6856 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6857#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006858#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006859 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006860#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006861#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006862 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00006863#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00006864 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006865#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00006866#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006867#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006868 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006869#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006870 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6871 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6872 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006873#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006874 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006875#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006876#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006877 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006878#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006879 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6880 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6881 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006882 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006883#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006884 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006885#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006886#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006887 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006888#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006889 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006890#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006891 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006892#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006893 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6894 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6895 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006896#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006897 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006898#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006899 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006900#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006901 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6902 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006903#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006904#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006905 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6906 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006907#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006908#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006909 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006910#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006911#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006912 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006913#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006914#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006915 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006916#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006917#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006918 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006919#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006920#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006921 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006922#endif /* HAVE_GETEGID */
6923#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006924 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006925#endif /* HAVE_GETEUID */
6926#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00006927 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006928#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006929#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00006930 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00006931#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00006932 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006933#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006934 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006935#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006936#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00006937 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006938#endif /* HAVE_GETPPID */
6939#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00006940 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006941#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006942#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00006943 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00006944#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006945#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006946 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006947#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006948#ifdef HAVE_KILLPG
6949 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6950#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006951#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006952 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006953#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006954#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006955 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006956#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006957 {"popen2", win32_popen2, METH_VARARGS},
6958 {"popen3", win32_popen3, METH_VARARGS},
6959 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006960 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006961#else
6962#if defined(PYOS_OS2) && defined(PYCC_GCC)
6963 {"popen2", os2emx_popen2, METH_VARARGS},
6964 {"popen3", os2emx_popen3, METH_VARARGS},
6965 {"popen4", os2emx_popen4, METH_VARARGS},
6966#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006967#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006968#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006969#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006970 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006971#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006972#ifdef HAVE_SETEUID
6973 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6974#endif /* HAVE_SETEUID */
6975#ifdef HAVE_SETEGID
6976 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6977#endif /* HAVE_SETEGID */
6978#ifdef HAVE_SETREUID
6979 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6980#endif /* HAVE_SETREUID */
6981#ifdef HAVE_SETREGID
6982 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6983#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006984#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006985 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006986#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006987#ifdef HAVE_SETGROUPS
6988 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6989#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006990#ifdef HAVE_GETPGID
6991 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6992#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006993#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00006994 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006995#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006996#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00006997 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006998#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006999#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007000 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007001#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007002#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007003 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007004#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007005#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007006 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007007#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007008#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007009 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007010#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007011#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007012 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007013#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007014 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7015 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7016 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7017 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7018 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7019 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7020 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7021 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7022 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007023 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007024#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007025 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007026#endif
7027#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007028 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007029#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007030#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007031 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7032#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007033#ifdef HAVE_DEVICE_MACROS
7034 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7035 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7036 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7037#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007038#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007039 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007040#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007041#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007042 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007043#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007044#ifdef HAVE_UNSETENV
7045 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7046#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007047#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007048 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007049#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007050#ifdef HAVE_FCHDIR
7051 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7052#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007053#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007054 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007055#endif
7056#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007057 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007058#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007059#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007060#ifdef WCOREDUMP
7061 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7062#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007063#ifdef WIFCONTINUED
7064 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7065#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007066#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007067 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007068#endif /* WIFSTOPPED */
7069#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007070 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007071#endif /* WIFSIGNALED */
7072#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007073 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007074#endif /* WIFEXITED */
7075#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007076 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007077#endif /* WEXITSTATUS */
7078#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007079 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007080#endif /* WTERMSIG */
7081#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007082 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007083#endif /* WSTOPSIG */
7084#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007085#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007086 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007087#endif
7088#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007089 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007090#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007091#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007092 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007093#endif
7094#ifdef HAVE_TEMPNAM
7095 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7096#endif
7097#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007098 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007099#endif
Fred Drakec9680921999-12-13 16:37:25 +00007100#ifdef HAVE_CONFSTR
7101 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7102#endif
7103#ifdef HAVE_SYSCONF
7104 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7105#endif
7106#ifdef HAVE_FPATHCONF
7107 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7108#endif
7109#ifdef HAVE_PATHCONF
7110 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7111#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007112 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007113#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007114 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7115#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007116#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007117 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007118#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007119 {NULL, NULL} /* Sentinel */
7120};
7121
7122
Barry Warsaw4a342091996-12-19 23:50:02 +00007123static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007124ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007125{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007126 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007127}
7128
Guido van Rossumd48f2521997-12-05 22:19:34 +00007129#if defined(PYOS_OS2)
7130/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007131static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007132{
7133 APIRET rc;
7134 ULONG values[QSV_MAX+1];
7135 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007136 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007137
7138 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007139 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007140 Py_END_ALLOW_THREADS
7141
7142 if (rc != NO_ERROR) {
7143 os2_error(rc);
7144 return -1;
7145 }
7146
Fred Drake4d1e64b2002-04-15 19:40:07 +00007147 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7148 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7149 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7150 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7151 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7152 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7153 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007154
7155 switch (values[QSV_VERSION_MINOR]) {
7156 case 0: ver = "2.00"; break;
7157 case 10: ver = "2.10"; break;
7158 case 11: ver = "2.11"; break;
7159 case 30: ver = "3.00"; break;
7160 case 40: ver = "4.00"; break;
7161 case 50: ver = "5.00"; break;
7162 default:
Tim Peters885d4572001-11-28 20:27:42 +00007163 PyOS_snprintf(tmp, sizeof(tmp),
7164 "%d-%d", values[QSV_VERSION_MAJOR],
7165 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007166 ver = &tmp[0];
7167 }
7168
7169 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007170 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007171 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007172
7173 /* Add Indicator of Which Drive was Used to Boot the System */
7174 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7175 tmp[1] = ':';
7176 tmp[2] = '\0';
7177
Fred Drake4d1e64b2002-04-15 19:40:07 +00007178 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007179}
7180#endif
7181
Barry Warsaw4a342091996-12-19 23:50:02 +00007182static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007183all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007184{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007185#ifdef F_OK
7186 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007187#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007188#ifdef R_OK
7189 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007190#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007191#ifdef W_OK
7192 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007193#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007194#ifdef X_OK
7195 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007196#endif
Fred Drakec9680921999-12-13 16:37:25 +00007197#ifdef NGROUPS_MAX
7198 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7199#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007200#ifdef TMP_MAX
7201 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7202#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007203#ifdef WCONTINUED
7204 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7205#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007206#ifdef WNOHANG
7207 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007208#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007209#ifdef WUNTRACED
7210 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7211#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007212#ifdef O_RDONLY
7213 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7214#endif
7215#ifdef O_WRONLY
7216 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7217#endif
7218#ifdef O_RDWR
7219 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7220#endif
7221#ifdef O_NDELAY
7222 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7223#endif
7224#ifdef O_NONBLOCK
7225 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7226#endif
7227#ifdef O_APPEND
7228 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7229#endif
7230#ifdef O_DSYNC
7231 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7232#endif
7233#ifdef O_RSYNC
7234 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7235#endif
7236#ifdef O_SYNC
7237 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7238#endif
7239#ifdef O_NOCTTY
7240 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7241#endif
7242#ifdef O_CREAT
7243 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7244#endif
7245#ifdef O_EXCL
7246 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7247#endif
7248#ifdef O_TRUNC
7249 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7250#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007251#ifdef O_BINARY
7252 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7253#endif
7254#ifdef O_TEXT
7255 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7256#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007257#ifdef O_LARGEFILE
7258 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7259#endif
7260
Tim Peters5aa91602002-01-30 05:46:57 +00007261/* MS Windows */
7262#ifdef O_NOINHERIT
7263 /* Don't inherit in child processes. */
7264 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7265#endif
7266#ifdef _O_SHORT_LIVED
7267 /* Optimize for short life (keep in memory). */
7268 /* MS forgot to define this one with a non-underscore form too. */
7269 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7270#endif
7271#ifdef O_TEMPORARY
7272 /* Automatically delete when last handle is closed. */
7273 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7274#endif
7275#ifdef O_RANDOM
7276 /* Optimize for random access. */
7277 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7278#endif
7279#ifdef O_SEQUENTIAL
7280 /* Optimize for sequential access. */
7281 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7282#endif
7283
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007284/* GNU extensions. */
7285#ifdef O_DIRECT
7286 /* Direct disk access. */
7287 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7288#endif
7289#ifdef O_DIRECTORY
7290 /* Must be a directory. */
7291 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7292#endif
7293#ifdef O_NOFOLLOW
7294 /* Do not follow links. */
7295 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7296#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007297
Barry Warsaw5676bd12003-01-07 20:57:09 +00007298 /* These come from sysexits.h */
7299#ifdef EX_OK
7300 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007301#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007302#ifdef EX_USAGE
7303 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007304#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007305#ifdef EX_DATAERR
7306 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007307#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007308#ifdef EX_NOINPUT
7309 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007310#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007311#ifdef EX_NOUSER
7312 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007313#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007314#ifdef EX_NOHOST
7315 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007316#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007317#ifdef EX_UNAVAILABLE
7318 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007319#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007320#ifdef EX_SOFTWARE
7321 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007322#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007323#ifdef EX_OSERR
7324 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007325#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007326#ifdef EX_OSFILE
7327 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007328#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007329#ifdef EX_CANTCREAT
7330 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007331#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007332#ifdef EX_IOERR
7333 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007334#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007335#ifdef EX_TEMPFAIL
7336 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007337#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007338#ifdef EX_PROTOCOL
7339 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007340#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007341#ifdef EX_NOPERM
7342 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007343#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007344#ifdef EX_CONFIG
7345 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007346#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007347#ifdef EX_NOTFOUND
7348 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007349#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007350
Guido van Rossum246bc171999-02-01 23:54:31 +00007351#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007352#if defined(PYOS_OS2) && defined(PYCC_GCC)
7353 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7354 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7355 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7356 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7357 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7358 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7359 if (ins(d, "P_PM", (long)P_PM)) return -1;
7360 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7361 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7362 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7363 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7364 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7365 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7366 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7367 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7368 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7369 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7370 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7371 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7372 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7373#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007374 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7375 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7376 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7377 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7378 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007379#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007380#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007381
Guido van Rossumd48f2521997-12-05 22:19:34 +00007382#if defined(PYOS_OS2)
7383 if (insertvalues(d)) return -1;
7384#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007385 return 0;
7386}
7387
7388
Tim Peters5aa91602002-01-30 05:46:57 +00007389#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007390#define INITFUNC initnt
7391#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007392
7393#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007394#define INITFUNC initos2
7395#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007396
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007397#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007398#define INITFUNC initposix
7399#define MODNAME "posix"
7400#endif
7401
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007402PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007403INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007404{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007405 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007406
Fred Drake4d1e64b2002-04-15 19:40:07 +00007407 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007408 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007409 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007410
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007411 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007412 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007413 Py_XINCREF(v);
7414 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007415 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007416 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007417
Fred Drake4d1e64b2002-04-15 19:40:07 +00007418 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007419 return;
7420
Fred Drake4d1e64b2002-04-15 19:40:07 +00007421 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007422 return;
7423
Fred Drake4d1e64b2002-04-15 19:40:07 +00007424 Py_INCREF(PyExc_OSError);
7425 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007426
Guido van Rossumb3d39562000-01-31 18:41:26 +00007427#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007428 if (posix_putenv_garbage == NULL)
7429 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007430#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007431
Guido van Rossum14648392001-12-08 18:02:58 +00007432 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007433 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7434 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7435 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007436 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007437 structseq_new = StatResultType.tp_new;
7438 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007439 Py_INCREF((PyObject*) &StatResultType);
7440 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007441
Guido van Rossum14648392001-12-08 18:02:58 +00007442 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007443 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007444 Py_INCREF((PyObject*) &StatVFSResultType);
7445 PyModule_AddObject(m, "statvfs_result",
7446 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007447}