blob: ce77673a143fdf83ec1c5cc3869ec7b23a81716b [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004/* This file is also used for Windows NT and MS-Win. In that case the module
Guido van Rossumad0ee831995-03-01 10:34:45 +00005 actually calls itself 'nt', not 'posix', and a few functions are
6 either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +00007 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000013static char posix__doc__ [] =
14"This module provides access to operating system functionality that is\n\
15standardized by the C Standard and the POSIX standard (a thinly\n\
16disguised Unix interface). Refer to the library manual and\n\
17corresponding Unix manual entries for more information on calls.";
18
Barry Warsaw53699e91996-12-10 23:23:01 +000019#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000020
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000021#if defined(PYOS_OS2)
22#define INCL_DOS
23#define INCL_DOSERRORS
24#define INCL_DOSPROCESS
25#define INCL_NOPMAPI
26#include <os2.h>
27#endif
28
Guido van Rossumb6775db1994-08-01 11:34:53 +000029#include <sys/types.h>
30#include <sys/stat.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +000031#ifdef HAVE_SYS_WAIT_H
32#include <sys/wait.h> /* For WNOHANG */
33#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000034
Guido van Rossuma376cc51996-12-05 23:43:35 +000035#ifdef HAVE_SIGNAL_H
36#include <signal.h>
37#endif
38
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#ifdef HAVE_FCNTL_H
40#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000041#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000042
Skip Montanaro8216c182001-02-27 17:04:34 +000043/* pick up declaration of confstr on some systems? */
44#ifdef HAVE_UNISTD_H
45#include <unistd.h>
46#endif /* HAVE_UNISTD_H */
47
Guido van Rossuma4916fa1996-05-23 22:58:55 +000048/* Various compilers have only certain posix functions */
Guido van Rossum6d8841c1997-08-14 19:57:39 +000049/* XXX Gosh I wish these were all moved into config.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000050#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#include <process.h>
52#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000053#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000054#define HAVE_GETCWD 1
55#define HAVE_OPENDIR 1
56#define HAVE_SYSTEM 1
57#if defined(__OS2__)
58#define HAVE_EXECV 1
59#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000060#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000061#include <process.h>
62#else
63#ifdef __BORLANDC__ /* Borland compiler */
64#define HAVE_EXECV 1
65#define HAVE_GETCWD 1
66#define HAVE_GETEGID 1
67#define HAVE_GETEUID 1
68#define HAVE_GETGID 1
69#define HAVE_GETPPID 1
70#define HAVE_GETUID 1
71#define HAVE_KILL 1
72#define HAVE_OPENDIR 1
73#define HAVE_PIPE 1
74#define HAVE_POPEN 1
75#define HAVE_SYSTEM 1
76#define HAVE_WAIT 1
77#else
78#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000079#define HAVE_GETCWD 1
80#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000081#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#define HAVE_EXECV 1
83#define HAVE_PIPE 1
84#define HAVE_POPEN 1
85#define HAVE_SYSTEM 1
86#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000087#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000088#else /* all other compilers */
89/* Unix functions that the configure script doesn't check for */
90#define HAVE_EXECV 1
91#define HAVE_FORK 1
92#define HAVE_GETCWD 1
93#define HAVE_GETEGID 1
94#define HAVE_GETEUID 1
95#define HAVE_GETGID 1
96#define HAVE_GETPPID 1
97#define HAVE_GETUID 1
98#define HAVE_KILL 1
99#define HAVE_OPENDIR 1
100#define HAVE_PIPE 1
101#define HAVE_POPEN 1
102#define HAVE_SYSTEM 1
103#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000104#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#endif /* _MSC_VER */
106#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000107#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000108#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000109
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000110#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000111
Guido van Rossumb6775db1994-08-01 11:34:53 +0000112#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000113#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000114#endif
115
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000116#if defined(sun) && !defined(__SVR4)
117/* SunOS 4.1.4 doesn't have prototypes for these: */
118extern int rename(const char *, const char *);
119extern int pclose(FILE *);
120extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000121extern int fsync(int);
122extern int lstat(const char *, struct stat *);
123extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000124#endif
125
Guido van Rossum36bc6801995-06-14 22:54:23 +0000126#ifdef NeXT
127/* NeXT's <unistd.h> and <utime.h> aren't worth much */
128#undef HAVE_UNISTD_H
129#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000130#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000131/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000132#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000133#endif
134
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000135#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000136#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000138#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000139#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000142extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000144#endif
145#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chdir(char *);
147extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(const char *);
150extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chmod(const char *, mode_t);
153extern int chown(const char *, uid_t, gid_t);
154extern char *getcwd(char *, int);
155extern char *strerror(int);
156extern int link(const char *, const char *);
157extern int rename(const char *, const char *);
158extern int stat(const char *, struct stat *);
159extern int unlink(const char *);
160extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000161#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000162extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000163#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000164#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000165extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000166#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000167#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000168
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000169#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000170
Guido van Rossumb6775db1994-08-01 11:34:53 +0000171#ifdef HAVE_UTIME_H
172#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000173#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000175#ifdef HAVE_SYS_UTIME_H
176#include <sys/utime.h>
177#define HAVE_UTIME_H /* pretend we do for the rest of this file */
178#endif /* HAVE_SYS_UTIME_H */
179
Guido van Rossumb6775db1994-08-01 11:34:53 +0000180#ifdef HAVE_SYS_TIMES_H
181#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000182#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183
184#ifdef HAVE_SYS_PARAM_H
185#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000186#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187
188#ifdef HAVE_SYS_UTSNAME_H
189#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000190#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000191
192#ifndef MAXPATHLEN
193#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000194#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000196#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000197#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000198#define NAMLEN(dirent) strlen((dirent)->d_name)
199#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000200#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#include <direct.h>
202#define NAMLEN(dirent) strlen((dirent)->d_name)
203#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000205#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000206#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000207#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#include <direct.h>
220#include <io.h>
221#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000222#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000224#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000226#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000227#else /* 16-bit Windows */
228#include <dos.h>
229#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000230#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000231#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossumd48f2521997-12-05 22:19:34 +0000233#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000235#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000237#ifdef UNION_WAIT
238/* Emulate some macros on systems that have a union instead of macros */
239
240#ifndef WIFEXITED
241#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
242#endif
243
244#ifndef WEXITSTATUS
245#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
246#endif
247
248#ifndef WTERMSIG
249#define WTERMSIG(u_wait) ((u_wait).w_termsig)
250#endif
251
252#endif /* UNION_WAIT */
253
Greg Wardb48bc172000-03-01 21:51:56 +0000254/* Don't use the "_r" form if we don't need it (also, won't have a
255 prototype for it, at least on Solaris -- maybe others as well?). */
256#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
257#define USE_CTERMID_R
258#endif
259
260#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
261#define USE_TMPNAM_R
262#endif
263
Fred Drake699f3522000-06-29 21:12:41 +0000264/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000265#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000266#ifdef MS_WIN64
267# define STAT _stati64
268# define FSTAT _fstati64
269# define STRUCT_STAT struct _stati64
270#else
271# define STAT stat
272# define FSTAT fstat
273# define STRUCT_STAT struct stat
274#endif
275
276
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277/* Return a dictionary corresponding to the POSIX environment table */
278
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000279#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000281#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282
Barry Warsaw53699e91996-12-10 23:23:01 +0000283static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000284convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285{
Barry Warsaw53699e91996-12-10 23:23:01 +0000286 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000288 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289 if (d == NULL)
290 return NULL;
291 if (environ == NULL)
292 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000293 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000295 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000296 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 char *p = strchr(*e, '=');
298 if (p == NULL)
299 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000300 k = PyString_FromStringAndSize(*e, (int)(p-*e));
301 if (k == NULL) {
302 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000303 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000304 }
305 v = PyString_FromString(p+1);
306 if (v == NULL) {
307 PyErr_Clear();
308 Py_DECREF(k);
309 continue;
310 }
311 if (PyDict_GetItem(d, k) == NULL) {
312 if (PyDict_SetItem(d, k, v) != 0)
313 PyErr_Clear();
314 }
315 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000316 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000318#if defined(PYOS_OS2)
319 {
320 APIRET rc;
321 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
322
323 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000324 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000325 PyObject *v = PyString_FromString(buffer);
326 PyDict_SetItemString(d, "BEGINLIBPATH", v);
327 Py_DECREF(v);
328 }
329 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
330 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
331 PyObject *v = PyString_FromString(buffer);
332 PyDict_SetItemString(d, "ENDLIBPATH", v);
333 Py_DECREF(v);
334 }
335 }
336#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337 return d;
338}
339
340
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341/* Set a POSIX-specific error from errno, and return NULL */
342
Barry Warsawd58d7641998-07-23 16:14:40 +0000343static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000344posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000345{
Barry Warsawca74da41999-02-09 19:31:45 +0000346 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347}
Barry Warsawd58d7641998-07-23 16:14:40 +0000348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000349posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000350{
Barry Warsawca74da41999-02-09 19:31:45 +0000351 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000352}
353
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000354#ifdef MS_WIN32
355static PyObject *
356win32_error(char* function, char* filename)
357{
Mark Hammond33a6da92000-08-15 00:46:38 +0000358 /* XXX We should pass the function name along in the future.
359 (_winreg.c also wants to pass the function name.)
360 This would however require an additional param to the
361 Windows error object, which is non-trivial.
362 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000363 errno = GetLastError();
364 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000365 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000366 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000367 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000368}
369#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000370
Guido van Rossumd48f2521997-12-05 22:19:34 +0000371#if defined(PYOS_OS2)
372/**********************************************************************
373 * Helper Function to Trim and Format OS/2 Messages
374 **********************************************************************/
375 static void
376os2_formatmsg(char *msgbuf, int msglen, char *reason)
377{
378 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
379
380 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
381 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
382
383 while (lastc > msgbuf && isspace(*lastc))
384 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
385 }
386
387 /* Add Optional Reason Text */
388 if (reason) {
389 strcat(msgbuf, " : ");
390 strcat(msgbuf, reason);
391 }
392}
393
394/**********************************************************************
395 * Decode an OS/2 Operating System Error Code
396 *
397 * A convenience function to lookup an OS/2 error code and return a
398 * text message we can use to raise a Python exception.
399 *
400 * Notes:
401 * The messages for errors returned from the OS/2 kernel reside in
402 * the file OSO001.MSG in the \OS2 directory hierarchy.
403 *
404 **********************************************************************/
405 static char *
406os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
407{
408 APIRET rc;
409 ULONG msglen;
410
411 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
412 Py_BEGIN_ALLOW_THREADS
413 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
414 errorcode, "oso001.msg", &msglen);
415 Py_END_ALLOW_THREADS
416
417 if (rc == NO_ERROR)
418 os2_formatmsg(msgbuf, msglen, reason);
419 else
420 sprintf(msgbuf, "unknown OS error #%d", errorcode);
421
422 return msgbuf;
423}
424
425/* Set an OS/2-specific error and return NULL. OS/2 kernel
426 errors are not in a global variable e.g. 'errno' nor are
427 they congruent with posix error numbers. */
428
429static PyObject * os2_error(int code)
430{
431 char text[1024];
432 PyObject *v;
433
434 os2_strerror(text, sizeof(text), code, "");
435
436 v = Py_BuildValue("(is)", code, text);
437 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000438 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000439 Py_DECREF(v);
440 }
441 return NULL; /* Signal to Python that an Exception is Pending */
442}
443
444#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000445
446/* POSIX generic methods */
447
Barry Warsaw53699e91996-12-10 23:23:01 +0000448static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000449posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000450{
451 int fd;
452 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000453 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000454 return NULL;
455 Py_BEGIN_ALLOW_THREADS
456 res = (*func)(fd);
457 Py_END_ALLOW_THREADS
458 if (res < 0)
459 return posix_error();
460 Py_INCREF(Py_None);
461 return Py_None;
462}
463
464
465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000466posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000467{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000468 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000469 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000470 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000471 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000472 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000473 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000474 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000475 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000476 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000477 Py_INCREF(Py_None);
478 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479}
480
Barry Warsaw53699e91996-12-10 23:23:01 +0000481static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000482posix_2str(PyObject *args, char *format,
483 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000484{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000485 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000486 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000487 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000489 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000490 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000491 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000492 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000493 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000494 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000495 Py_INCREF(Py_None);
496 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000497}
498
Fred Drake699f3522000-06-29 21:12:41 +0000499/* pack a system stat C structure into the Python stat tuple
500 (used by posix_stat() and posix_fstat()) */
501static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000502_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000503{
504 PyObject *v = PyTuple_New(10);
505 if (v == NULL)
506 return NULL;
507
508 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
509#ifdef HAVE_LARGEFILE_SUPPORT
510 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
511#else
512 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
513#endif
514#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
515 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
516#else
517 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
518#endif
519 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
520 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
521 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
522#ifdef HAVE_LARGEFILE_SUPPORT
523 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
524#else
525 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
526#endif
527#if SIZEOF_TIME_T > SIZEOF_LONG
528 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
529 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
530 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
531#else
532 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
533 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
534 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
535#endif
536
537 if (PyErr_Occurred()) {
538 Py_DECREF(v);
539 return NULL;
540 }
541
542 return v;
543}
544
545
Barry Warsaw53699e91996-12-10 23:23:01 +0000546static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000547posix_do_stat(PyObject *self, PyObject *args, char *format,
548 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000549{
Fred Drake699f3522000-06-29 21:12:41 +0000550 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000551 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000552 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000553
554#ifdef MS_WIN32
555 int pathlen;
556 char pathcopy[MAX_PATH];
557#endif /* MS_WIN32 */
558
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000559 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000560 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000561
562#ifdef MS_WIN32
563 pathlen = strlen(path);
564 /* the library call can blow up if the file name is too long! */
565 if (pathlen > MAX_PATH) {
566 errno = ENAMETOOLONG;
567 return posix_error();
568 }
569
570 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000571 /* exception for specific or current drive root */
572 if (!((pathlen == 1) ||
573 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000574 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000575 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000576 {
577 strncpy(pathcopy, path, pathlen);
578 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
579 path = pathcopy;
580 }
581 }
582#endif /* MS_WIN32 */
583
Barry Warsaw53699e91996-12-10 23:23:01 +0000584 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000585 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000586 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000587 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000588 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000589
590 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000591}
592
593
594/* POSIX methods */
595
Guido van Rossum94f6f721999-01-06 18:42:14 +0000596static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000597"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000598Test for access to a file.";
599
600static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000601posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000602{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000603 char *path;
604 int mode;
605 int res;
606
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000607 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000608 return NULL;
609 Py_BEGIN_ALLOW_THREADS
610 res = access(path, mode);
611 Py_END_ALLOW_THREADS
612 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000613}
614
Guido van Rossumd371ff11999-01-25 16:12:23 +0000615#ifndef F_OK
616#define F_OK 0
617#endif
618#ifndef R_OK
619#define R_OK 4
620#endif
621#ifndef W_OK
622#define W_OK 2
623#endif
624#ifndef X_OK
625#define X_OK 1
626#endif
627
628#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000629static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000630"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000631Return the name of the terminal device connected to 'fd'.";
632
633static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000634posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000635{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000636 int id;
637 char *ret;
638
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000639 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000640 return NULL;
641
Guido van Rossum94f6f721999-01-06 18:42:14 +0000642 ret = ttyname(id);
643 if (ret == NULL)
644 return(posix_error());
645 return(PyString_FromString(ret));
646}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000647#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000648
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000649#ifdef HAVE_CTERMID
650static char posix_ctermid__doc__[] =
651"ctermid() -> String\n\
652Return the name of the controlling terminal for this process.";
653
654static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000655posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000656{
657 char *ret;
658 char buffer[L_ctermid];
659
660 if (!PyArg_ParseTuple(args, ":ctermid"))
661 return NULL;
662
Greg Wardb48bc172000-03-01 21:51:56 +0000663#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000664 ret = ctermid_r(buffer);
665#else
666 ret = ctermid(buffer);
667#endif
668 if (ret == NULL)
669 return(posix_error());
670 return(PyString_FromString(buffer));
671}
672#endif
673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000674static char posix_chdir__doc__[] =
675"chdir(path) -> None\n\
676Change the current working directory to the specified path.";
677
Barry Warsaw53699e91996-12-10 23:23:01 +0000678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000679posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000680{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000681 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000682}
683
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000684
685static char posix_chmod__doc__[] =
686"chmod(path, mode) -> None\n\
687Change the access permissions of a file.";
688
Barry Warsaw53699e91996-12-10 23:23:01 +0000689static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000690posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000692 char *path;
693 int i;
694 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000695 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000696 return NULL;
697 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000698 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000699 Py_END_ALLOW_THREADS
700 if (res < 0)
701 return posix_error_with_filename(path);
702 Py_INCREF(Py_None);
703 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000704}
705
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000706
Guido van Rossum21142a01999-01-08 21:05:37 +0000707#ifdef HAVE_FSYNC
708static char posix_fsync__doc__[] =
709"fsync(fildes) -> None\n\
710force write of file with filedescriptor to disk.";
711
712static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000713posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000714{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000715 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000716}
717#endif /* HAVE_FSYNC */
718
719#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000720
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000721#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000722extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
723#endif
724
Guido van Rossum21142a01999-01-08 21:05:37 +0000725static char posix_fdatasync__doc__[] =
726"fdatasync(fildes) -> None\n\
727force write of file with filedescriptor to disk.\n\
728 does not force update of metadata.";
729
730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000731posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000732{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000733 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000734}
735#endif /* HAVE_FDATASYNC */
736
737
Fredrik Lundh10723342000-07-10 16:38:09 +0000738#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000739static char posix_chown__doc__[] =
740"chown(path, uid, gid) -> None\n\
741Change the owner and group id of path to the numeric uid and gid.";
742
Barry Warsaw53699e91996-12-10 23:23:01 +0000743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000744posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000745{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000746 char *path;
747 int uid, gid;
748 int res;
749 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
750 return NULL;
751 Py_BEGIN_ALLOW_THREADS
752 res = chown(path, (uid_t) uid, (gid_t) gid);
753 Py_END_ALLOW_THREADS
754 if (res < 0)
755 return posix_error_with_filename(path);
756 Py_INCREF(Py_None);
757 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000758}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000759#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000760
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000761
Guido van Rossum36bc6801995-06-14 22:54:23 +0000762#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000763static char posix_getcwd__doc__[] =
764"getcwd() -> path\n\
765Return a string representing the current working directory.";
766
Barry Warsaw53699e91996-12-10 23:23:01 +0000767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000768posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000769{
770 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000771 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000772 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000773 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000774 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000775 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000776 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000777 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000778 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000779 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000780}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000781#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000783
Guido van Rossumb6775db1994-08-01 11:34:53 +0000784#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000785static char posix_link__doc__[] =
786"link(src, dst) -> None\n\
787Create a hard link to a file.";
788
Barry Warsaw53699e91996-12-10 23:23:01 +0000789static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000790posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000791{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000792 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000793}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000794#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000796
797static char posix_listdir__doc__[] =
798"listdir(path) -> list_of_strings\n\
799Return a list containing the names of the entries in the directory.\n\
800\n\
801 path: path of directory to list\n\
802\n\
803The list is in arbitrary order. It does not include the special\n\
804entries '.' and '..' even if they are present in the directory.";
805
Barry Warsaw53699e91996-12-10 23:23:01 +0000806static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000807posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000808{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000809 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000810 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000811#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000812
Guido van Rossumb6775db1994-08-01 11:34:53 +0000813 char *name;
814 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000815 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000816 HANDLE hFindFile;
817 WIN32_FIND_DATA FileData;
818 char namebuf[MAX_PATH+5];
Tim Peters0bb44a42000-09-15 07:44:49 +0000819 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000820
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000821 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000822 return NULL;
823 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000824 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000825 return NULL;
826 }
827 strcpy(namebuf, name);
Tim Peters0bb44a42000-09-15 07:44:49 +0000828 ch = namebuf[len-1];
829 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000830 namebuf[len++] = '/';
831 strcpy(namebuf + len, "*.*");
832
Barry Warsaw53699e91996-12-10 23:23:01 +0000833 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000834 return NULL;
835
836 hFindFile = FindFirstFile(namebuf, &FileData);
837 if (hFindFile == INVALID_HANDLE_VALUE) {
838 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000839 if (errno == ERROR_FILE_NOT_FOUND)
840 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000841 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000842 }
843 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000844 if (FileData.cFileName[0] == '.' &&
845 (FileData.cFileName[1] == '\0' ||
846 FileData.cFileName[1] == '.' &&
847 FileData.cFileName[2] == '\0'))
848 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000849 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000850 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000851 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000852 d = NULL;
853 break;
854 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000855 if (PyList_Append(d, v) != 0) {
856 Py_DECREF(v);
857 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000858 d = NULL;
859 break;
860 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000861 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000862 } while (FindNextFile(hFindFile, &FileData) == TRUE);
863
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000864 if (FindClose(hFindFile) == FALSE)
865 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000866
867 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000868
Tim Peters0bb44a42000-09-15 07:44:49 +0000869#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000870
871#ifndef MAX_PATH
872#define MAX_PATH 250
873#endif
874 char *name, *pt;
875 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000876 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000877 char namebuf[MAX_PATH+5];
878 struct _find_t ep;
879
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000880 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000881 return NULL;
882 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000883 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000884 return NULL;
885 }
886 strcpy(namebuf, name);
887 for (pt = namebuf; *pt; pt++)
888 if (*pt == '/')
889 *pt = '\\';
890 if (namebuf[len-1] != '\\')
891 namebuf[len++] = '\\';
892 strcpy(namebuf + len, "*.*");
893
Barry Warsaw53699e91996-12-10 23:23:01 +0000894 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000895 return NULL;
896
897 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000898 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
899 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000900 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000901 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000902 }
903 do {
904 if (ep.name[0] == '.' &&
905 (ep.name[1] == '\0' ||
906 ep.name[1] == '.' &&
907 ep.name[2] == '\0'))
908 continue;
909 strcpy(namebuf, ep.name);
910 for (pt = namebuf; *pt; pt++)
911 if (isupper(*pt))
912 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000913 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000914 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000915 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000916 d = NULL;
917 break;
918 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000919 if (PyList_Append(d, v) != 0) {
920 Py_DECREF(v);
921 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000922 d = NULL;
923 break;
924 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000925 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000926 } while (_dos_findnext(&ep) == 0);
927
928 return d;
929
Tim Peters0bb44a42000-09-15 07:44:49 +0000930#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000931
932#ifndef MAX_PATH
933#define MAX_PATH CCHMAXPATH
934#endif
935 char *name, *pt;
936 int len;
937 PyObject *d, *v;
938 char namebuf[MAX_PATH+5];
939 HDIR hdir = 1;
940 ULONG srchcnt = 1;
941 FILEFINDBUF3 ep;
942 APIRET rc;
943
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000944 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000945 return NULL;
946 if (len >= MAX_PATH) {
947 PyErr_SetString(PyExc_ValueError, "path too long");
948 return NULL;
949 }
950 strcpy(namebuf, name);
951 for (pt = namebuf; *pt; pt++)
952 if (*pt == '/')
953 *pt = '\\';
954 if (namebuf[len-1] != '\\')
955 namebuf[len++] = '\\';
956 strcpy(namebuf + len, "*.*");
957
958 if ((d = PyList_New(0)) == NULL)
959 return NULL;
960
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000961 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
962 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000964 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
965 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
966 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000967
968 if (rc != NO_ERROR) {
969 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000970 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000971 }
972
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000973 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000974 do {
975 if (ep.achName[0] == '.'
976 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000977 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000978
979 strcpy(namebuf, ep.achName);
980
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000981 /* Leave Case of Name Alone -- In Native Form */
982 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000983
984 v = PyString_FromString(namebuf);
985 if (v == NULL) {
986 Py_DECREF(d);
987 d = NULL;
988 break;
989 }
990 if (PyList_Append(d, v) != 0) {
991 Py_DECREF(v);
992 Py_DECREF(d);
993 d = NULL;
994 break;
995 }
996 Py_DECREF(v);
997 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
998 }
999
1000 return d;
1001#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001002
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001003 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001004 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001005 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001006 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001007 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001008 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001009 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001010 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001011 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001012 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001013 closedir(dirp);
1014 return NULL;
1015 }
1016 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001017 if (ep->d_name[0] == '.' &&
1018 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001019 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001020 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001021 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001022 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001023 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001024 d = NULL;
1025 break;
1026 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001027 if (PyList_Append(d, v) != 0) {
1028 Py_DECREF(v);
1029 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001030 d = NULL;
1031 break;
1032 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001033 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001034 }
1035 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001036
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001037 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001038
Tim Peters0bb44a42000-09-15 07:44:49 +00001039#endif /* which OS */
1040} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001042static char posix_mkdir__doc__[] =
1043"mkdir(path [, mode=0777]) -> None\n\
1044Create a directory.";
1045
Barry Warsaw53699e91996-12-10 23:23:01 +00001046static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001047posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001048{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001049 int res;
1050 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001051 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001052 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001053 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001054 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001055#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001056 res = mkdir(path);
1057#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001058 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001059#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001060 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001061 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001062 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001063 Py_INCREF(Py_None);
1064 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001065}
1066
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001067
Guido van Rossumb6775db1994-08-01 11:34:53 +00001068#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001069static char posix_nice__doc__[] =
1070"nice(inc) -> new_priority\n\
1071Decrease the priority of process and return new priority.";
1072
Barry Warsaw53699e91996-12-10 23:23:01 +00001073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001074posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001075{
1076 int increment, value;
1077
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001078 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001079 return NULL;
1080 value = nice(increment);
1081 if (value == -1)
1082 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001083 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001084}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001085#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001087
1088static char posix_rename__doc__[] =
1089"rename(old, new) -> None\n\
1090Rename a file or directory.";
1091
Barry Warsaw53699e91996-12-10 23:23:01 +00001092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001093posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001094{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001095 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001096}
1097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001098
1099static char posix_rmdir__doc__[] =
1100"rmdir(path) -> None\n\
1101Remove a directory.";
1102
Barry Warsaw53699e91996-12-10 23:23:01 +00001103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001104posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001105{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001106 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001107}
1108
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001109
1110static char posix_stat__doc__[] =
1111"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1112Perform a stat system call on the given path.";
1113
Barry Warsaw53699e91996-12-10 23:23:01 +00001114static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001115posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001116{
Fred Drake699f3522000-06-29 21:12:41 +00001117 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001118}
1119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001120
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001121#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001122static char posix_system__doc__[] =
1123"system(command) -> exit_status\n\
1124Execute the command (a string) in a subshell.";
1125
Barry Warsaw53699e91996-12-10 23:23:01 +00001126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001127posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001128{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001129 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001130 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001131 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001133 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001134 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001135 Py_END_ALLOW_THREADS
1136 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001138#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001139
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001140
1141static char posix_umask__doc__[] =
1142"umask(new_mask) -> old_mask\n\
1143Set the current numeric umask and return the previous umask.";
1144
Barry Warsaw53699e91996-12-10 23:23:01 +00001145static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001146posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001147{
1148 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001149 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001150 return NULL;
1151 i = umask(i);
1152 if (i < 0)
1153 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001154 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001155}
1156
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001157
1158static char posix_unlink__doc__[] =
1159"unlink(path) -> None\n\
1160Remove a file (same as remove(path)).";
1161
1162static char posix_remove__doc__[] =
1163"remove(path) -> None\n\
1164Remove a file (same as unlink(path)).";
1165
Barry Warsaw53699e91996-12-10 23:23:01 +00001166static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001167posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001168{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001169 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001170}
1171
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001172
Guido van Rossumb6775db1994-08-01 11:34:53 +00001173#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001174static char posix_uname__doc__[] =
1175"uname() -> (sysname, nodename, release, version, machine)\n\
1176Return a tuple identifying the current operating system.";
1177
Barry Warsaw53699e91996-12-10 23:23:01 +00001178static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001179posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001180{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001181 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001182 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001183 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001184 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001185 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001186 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001187 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001188 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001189 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001190 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001191 u.sysname,
1192 u.nodename,
1193 u.release,
1194 u.version,
1195 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001196}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001197#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001199
1200static char posix_utime__doc__[] =
1201"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001202utime(path, None) -> None\n\
1203Set the access and modified time of the file to the given values. If the\n\
1204second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001205
Barry Warsaw53699e91996-12-10 23:23:01 +00001206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001207posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001208{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001209 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001210 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001211 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001212 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001213
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001214/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001215#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001216 struct utimbuf buf;
1217#define ATIME buf.actime
1218#define MTIME buf.modtime
1219#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001220#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001221 time_t buf[2];
1222#define ATIME buf[0]
1223#define MTIME buf[1]
1224#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001225#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001226
Barry Warsaw3cef8562000-05-01 16:17:24 +00001227 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001228 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001229 if (arg == Py_None) {
1230 /* optional time values not given */
1231 Py_BEGIN_ALLOW_THREADS
1232 res = utime(path, NULL);
1233 Py_END_ALLOW_THREADS
1234 }
1235 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1236 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001237 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001238 return NULL;
1239 }
1240 else {
1241 ATIME = atime;
1242 MTIME = mtime;
1243 Py_BEGIN_ALLOW_THREADS
1244 res = utime(path, UTIME_ARG);
1245 Py_END_ALLOW_THREADS
1246 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001247 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001248 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001249 Py_INCREF(Py_None);
1250 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001251#undef UTIME_ARG
1252#undef ATIME
1253#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254}
1255
Guido van Rossum85e3b011991-06-03 12:42:10 +00001256
Guido van Rossum3b066191991-06-04 19:40:25 +00001257/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001258
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001259static char posix__exit__doc__[] =
1260"_exit(status)\n\
1261Exit to the system with specified status, without normal exit processing.";
1262
Barry Warsaw53699e91996-12-10 23:23:01 +00001263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001264posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001265{
1266 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001267 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001268 return NULL;
1269 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001270 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001271}
1272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001273
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001274#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001275static char posix_execv__doc__[] =
1276"execv(path, args)\n\
1277Execute an executable path with arguments, replacing current process.\n\
1278\n\
1279 path: path of executable file\n\
1280 args: tuple or list of strings";
1281
Barry Warsaw53699e91996-12-10 23:23:01 +00001282static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001283posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001284{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001285 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001286 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001287 char **argvlist;
1288 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001289 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001290
Guido van Rossum89b33251993-10-22 14:26:06 +00001291 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001292 argv is a list or tuple of strings. */
1293
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001294 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001295 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001296 if (PyList_Check(argv)) {
1297 argc = PyList_Size(argv);
1298 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001299 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001300 else if (PyTuple_Check(argv)) {
1301 argc = PyTuple_Size(argv);
1302 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001303 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001304 else {
Fred Drake661ea262000-10-24 19:57:45 +00001305 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001306 return NULL;
1307 }
1308
1309 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001310 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001311 return NULL;
1312 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001313
Barry Warsaw53699e91996-12-10 23:23:01 +00001314 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001315 if (argvlist == NULL)
1316 return NULL;
1317 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001318 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1319 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001320 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001321 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001322 return NULL;
1323
Guido van Rossum85e3b011991-06-03 12:42:10 +00001324 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001325 }
1326 argvlist[argc] = NULL;
1327
Guido van Rossumb6775db1994-08-01 11:34:53 +00001328#ifdef BAD_EXEC_PROTOTYPES
1329 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001330#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001331 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001332#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001333
Guido van Rossum85e3b011991-06-03 12:42:10 +00001334 /* If we get here it's definitely an error */
1335
Barry Warsaw53699e91996-12-10 23:23:01 +00001336 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001337 return posix_error();
1338}
1339
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001340
1341static char posix_execve__doc__[] =
1342"execve(path, args, env)\n\
1343Execute a path with arguments and environment, replacing current process.\n\
1344\n\
1345 path: path of executable file\n\
1346 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001347 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001348
Barry Warsaw53699e91996-12-10 23:23:01 +00001349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001350posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001351{
1352 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001353 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001354 char **argvlist;
1355 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001356 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001357 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001358 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001359
1360 /* execve has three arguments: (path, argv, env), where
1361 argv is a list or tuple of strings and env is a dictionary
1362 like posix.environ. */
1363
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001364 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001365 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001366 if (PyList_Check(argv)) {
1367 argc = PyList_Size(argv);
1368 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001369 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001370 else if (PyTuple_Check(argv)) {
1371 argc = PyTuple_Size(argv);
1372 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001373 }
1374 else {
Fred Drake661ea262000-10-24 19:57:45 +00001375 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001376 return NULL;
1377 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001378 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001379 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001380 return NULL;
1381 }
1382
Guido van Rossum50422b42000-04-26 20:34:28 +00001383 if (argc == 0) {
1384 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001385 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001386 return NULL;
1387 }
1388
Barry Warsaw53699e91996-12-10 23:23:01 +00001389 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001390 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001391 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001392 return NULL;
1393 }
1394 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001395 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001396 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001397 &argvlist[i]))
1398 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001399 goto fail_1;
1400 }
1401 }
1402 argvlist[argc] = NULL;
1403
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001404 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001405 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001406 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001407 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001408 goto fail_1;
1409 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001410 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001411 keys = PyMapping_Keys(env);
1412 vals = PyMapping_Values(env);
1413 if (!keys || !vals)
1414 goto fail_2;
1415
1416 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001417 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001418
1419 key = PyList_GetItem(keys, pos);
1420 val = PyList_GetItem(vals, pos);
1421 if (!key || !val)
1422 goto fail_2;
1423
Fred Drake661ea262000-10-24 19:57:45 +00001424 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1425 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001426 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001427 goto fail_2;
1428 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001429
1430#if defined(PYOS_OS2)
1431 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1432 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1433#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001434 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001435 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001436 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001437 goto fail_2;
1438 }
1439 sprintf(p, "%s=%s", k, v);
1440 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001441#if defined(PYOS_OS2)
1442 }
1443#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001444 }
1445 envlist[envc] = 0;
1446
Guido van Rossumb6775db1994-08-01 11:34:53 +00001447
1448#ifdef BAD_EXEC_PROTOTYPES
1449 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001450#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001451 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001452#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001453
1454 /* If we get here it's definitely an error */
1455
1456 (void) posix_error();
1457
1458 fail_2:
1459 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001460 PyMem_DEL(envlist[envc]);
1461 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001462 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001463 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001464 Py_XDECREF(vals);
1465 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001466 return NULL;
1467}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001468#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001469
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001470
Guido van Rossuma1065681999-01-25 23:20:23 +00001471#ifdef HAVE_SPAWNV
1472static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001473"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001474Execute an executable path with arguments, replacing current process.\n\
1475\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001476 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001477 path: path of executable file\n\
1478 args: tuple or list of strings";
1479
1480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001481posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001482{
1483 char *path;
1484 PyObject *argv;
1485 char **argvlist;
1486 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001487 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001488 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001489
1490 /* spawnv has three arguments: (mode, path, argv), where
1491 argv is a list or tuple of strings. */
1492
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001493 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001494 return NULL;
1495 if (PyList_Check(argv)) {
1496 argc = PyList_Size(argv);
1497 getitem = PyList_GetItem;
1498 }
1499 else if (PyTuple_Check(argv)) {
1500 argc = PyTuple_Size(argv);
1501 getitem = PyTuple_GetItem;
1502 }
1503 else {
Fred Drake661ea262000-10-24 19:57:45 +00001504 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001505 return NULL;
1506 }
1507
1508 argvlist = PyMem_NEW(char *, argc+1);
1509 if (argvlist == NULL)
1510 return NULL;
1511 for (i = 0; i < argc; i++) {
1512 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1513 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001514 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001515 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001516 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001517 }
1518 }
1519 argvlist[argc] = NULL;
1520
Guido van Rossum246bc171999-02-01 23:54:31 +00001521 if (mode == _OLD_P_OVERLAY)
1522 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001523 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001524
1525 PyMem_DEL(argvlist);
1526
Fred Drake699f3522000-06-29 21:12:41 +00001527 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001528 return posix_error();
1529 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001530#if SIZEOF_LONG == SIZEOF_VOID_P
1531 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001532#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001533 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001534#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001535}
1536
1537
1538static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001539"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001540Execute a path with arguments and environment, replacing current process.\n\
1541\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001542 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001543 path: path of executable file\n\
1544 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001545 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001546
1547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001548posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001549{
1550 char *path;
1551 PyObject *argv, *env;
1552 char **argvlist;
1553 char **envlist;
1554 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1555 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001556 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001557 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001558
1559 /* spawnve has four arguments: (mode, path, argv, env), where
1560 argv is a list or tuple of strings and env is a dictionary
1561 like posix.environ. */
1562
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001563 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001564 return NULL;
1565 if (PyList_Check(argv)) {
1566 argc = PyList_Size(argv);
1567 getitem = PyList_GetItem;
1568 }
1569 else if (PyTuple_Check(argv)) {
1570 argc = PyTuple_Size(argv);
1571 getitem = PyTuple_GetItem;
1572 }
1573 else {
Fred Drake661ea262000-10-24 19:57:45 +00001574 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001575 return NULL;
1576 }
1577 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001578 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001579 return NULL;
1580 }
1581
1582 argvlist = PyMem_NEW(char *, argc+1);
1583 if (argvlist == NULL) {
1584 PyErr_NoMemory();
1585 return NULL;
1586 }
1587 for (i = 0; i < argc; i++) {
1588 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001589 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001590 &argvlist[i]))
1591 {
1592 goto fail_1;
1593 }
1594 }
1595 argvlist[argc] = NULL;
1596
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001597 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001598 envlist = PyMem_NEW(char *, i + 1);
1599 if (envlist == NULL) {
1600 PyErr_NoMemory();
1601 goto fail_1;
1602 }
1603 envc = 0;
1604 keys = PyMapping_Keys(env);
1605 vals = PyMapping_Values(env);
1606 if (!keys || !vals)
1607 goto fail_2;
1608
1609 for (pos = 0; pos < i; pos++) {
1610 char *p, *k, *v;
1611
1612 key = PyList_GetItem(keys, pos);
1613 val = PyList_GetItem(vals, pos);
1614 if (!key || !val)
1615 goto fail_2;
1616
Fred Drake661ea262000-10-24 19:57:45 +00001617 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1618 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001619 {
1620 goto fail_2;
1621 }
1622 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1623 if (p == NULL) {
1624 PyErr_NoMemory();
1625 goto fail_2;
1626 }
1627 sprintf(p, "%s=%s", k, v);
1628 envlist[envc++] = p;
1629 }
1630 envlist[envc] = 0;
1631
Guido van Rossum246bc171999-02-01 23:54:31 +00001632 if (mode == _OLD_P_OVERLAY)
1633 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001634 spawnval = _spawnve(mode, path, argvlist, envlist);
1635 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001636 (void) posix_error();
1637 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001638#if SIZEOF_LONG == SIZEOF_VOID_P
1639 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001640#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001641 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001642#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001643
1644 fail_2:
1645 while (--envc >= 0)
1646 PyMem_DEL(envlist[envc]);
1647 PyMem_DEL(envlist);
1648 fail_1:
1649 PyMem_DEL(argvlist);
1650 Py_XDECREF(vals);
1651 Py_XDECREF(keys);
1652 return res;
1653}
1654#endif /* HAVE_SPAWNV */
1655
1656
Guido van Rossumad0ee831995-03-01 10:34:45 +00001657#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001658static char posix_fork__doc__[] =
1659"fork() -> pid\n\
1660Fork a child process.\n\
1661\n\
1662Return 0 to child process and PID of child to parent process.";
1663
Barry Warsaw53699e91996-12-10 23:23:01 +00001664static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001665posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001666{
1667 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001668 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001669 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001670 pid = fork();
1671 if (pid == -1)
1672 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001673 if (pid == 0)
1674 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001675 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001676}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001677#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001678
Fred Drake8cef4cf2000-06-28 16:40:38 +00001679#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1680#ifdef HAVE_PTY_H
1681#include <pty.h>
1682#else
1683#ifdef HAVE_LIBUTIL_H
1684#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001685#endif /* HAVE_LIBUTIL_H */
1686#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001687#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001688
Thomas Wouters70c21a12000-07-14 14:28:33 +00001689#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001690static char posix_openpty__doc__[] =
1691"openpty() -> (master_fd, slave_fd)\n\
1692Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1693
1694static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001695posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001696{
1697 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001698#ifndef HAVE_OPENPTY
1699 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001700#endif
1701
Fred Drake8cef4cf2000-06-28 16:40:38 +00001702 if (!PyArg_ParseTuple(args, ":openpty"))
1703 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001704
1705#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001706 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1707 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001708#else
1709 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1710 if (slave_name == NULL)
1711 return posix_error();
1712
1713 slave_fd = open(slave_name, O_RDWR);
1714 if (slave_fd < 0)
1715 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001716#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001717
Fred Drake8cef4cf2000-06-28 16:40:38 +00001718 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001719
Fred Drake8cef4cf2000-06-28 16:40:38 +00001720}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001721#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001722
1723#ifdef HAVE_FORKPTY
1724static char posix_forkpty__doc__[] =
1725"forkpty() -> (pid, master_fd)\n\
1726Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1727Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1728To both, return fd of newly opened pseudo-terminal.\n";
1729
1730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001731posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001732{
1733 int master_fd, pid;
1734
1735 if (!PyArg_ParseTuple(args, ":forkpty"))
1736 return NULL;
1737 pid = forkpty(&master_fd, NULL, NULL, NULL);
1738 if (pid == -1)
1739 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001740 if (pid == 0)
1741 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001742 return Py_BuildValue("(ii)", pid, master_fd);
1743}
1744#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001745
Guido van Rossumad0ee831995-03-01 10:34:45 +00001746#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001747static char posix_getegid__doc__[] =
1748"getegid() -> egid\n\
1749Return the current process's effective group id.";
1750
Barry Warsaw53699e91996-12-10 23:23:01 +00001751static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001752posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001753{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001754 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001755 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001756 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001757}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001758#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001760
Guido van Rossumad0ee831995-03-01 10:34:45 +00001761#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001762static char posix_geteuid__doc__[] =
1763"geteuid() -> euid\n\
1764Return the current process's effective user id.";
1765
Barry Warsaw53699e91996-12-10 23:23:01 +00001766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001767posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001768{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001769 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001770 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001771 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001772}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001773#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001775
Guido van Rossumad0ee831995-03-01 10:34:45 +00001776#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001777static char posix_getgid__doc__[] =
1778"getgid() -> gid\n\
1779Return the current process's group id.";
1780
Barry Warsaw53699e91996-12-10 23:23:01 +00001781static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001782posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001783{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001784 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001785 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001786 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001787}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001788#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001789
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001790
1791static char posix_getpid__doc__[] =
1792"getpid() -> pid\n\
1793Return the current process id";
1794
Barry Warsaw53699e91996-12-10 23:23:01 +00001795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001796posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001797{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001798 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001799 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001800 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001801}
1802
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001803
Fred Drakec9680921999-12-13 16:37:25 +00001804#ifdef HAVE_GETGROUPS
1805static char posix_getgroups__doc__[] = "\
1806getgroups() -> list of group IDs\n\
1807Return list of supplemental group IDs for the process.";
1808
1809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001810posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001811{
1812 PyObject *result = NULL;
1813
1814 if (PyArg_ParseTuple(args, ":getgroups")) {
1815#ifdef NGROUPS_MAX
1816#define MAX_GROUPS NGROUPS_MAX
1817#else
1818 /* defined to be 16 on Solaris7, so this should be a small number */
1819#define MAX_GROUPS 64
1820#endif
1821 gid_t grouplist[MAX_GROUPS];
1822 int n;
1823
1824 n = getgroups(MAX_GROUPS, grouplist);
1825 if (n < 0)
1826 posix_error();
1827 else {
1828 result = PyList_New(n);
1829 if (result != NULL) {
1830 PyObject *o;
1831 int i;
1832 for (i = 0; i < n; ++i) {
1833 o = PyInt_FromLong((long)grouplist[i]);
1834 if (o == NULL) {
1835 Py_DECREF(result);
1836 result = NULL;
1837 break;
1838 }
1839 PyList_SET_ITEM(result, i, o);
1840 }
1841 }
1842 }
1843 }
1844 return result;
1845}
1846#endif
1847
Guido van Rossumb6775db1994-08-01 11:34:53 +00001848#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001849static char posix_getpgrp__doc__[] =
1850"getpgrp() -> pgrp\n\
1851Return the current process group id.";
1852
Barry Warsaw53699e91996-12-10 23:23:01 +00001853static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001854posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001855{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001856 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001857 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001858#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001859 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001860#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001861 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001862#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001863}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001864#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001865
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001866
Guido van Rossumb6775db1994-08-01 11:34:53 +00001867#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001868static char posix_setpgrp__doc__[] =
1869"setpgrp() -> None\n\
1870Make this process a session leader.";
1871
Barry Warsaw53699e91996-12-10 23:23:01 +00001872static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001873posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001874{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001875 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001876 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001877#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001878 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001879#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001880 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001881#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001882 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001883 Py_INCREF(Py_None);
1884 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001885}
1886
Guido van Rossumb6775db1994-08-01 11:34:53 +00001887#endif /* HAVE_SETPGRP */
1888
Guido van Rossumad0ee831995-03-01 10:34:45 +00001889#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001890static char posix_getppid__doc__[] =
1891"getppid() -> ppid\n\
1892Return the parent's process id.";
1893
Barry Warsaw53699e91996-12-10 23:23:01 +00001894static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001895posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001896{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001897 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001898 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001899 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001900}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001901#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001902
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001903
Fred Drake12c6e2d1999-12-14 21:25:03 +00001904#ifdef HAVE_GETLOGIN
1905static char posix_getlogin__doc__[] = "\
1906getlogin() -> string\n\
1907Return the actual login name.";
1908
1909static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001910posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001911{
1912 PyObject *result = NULL;
1913
1914 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00001915 char *name;
1916 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001917
Fred Drakea30680b2000-12-06 21:24:28 +00001918 errno = 0;
1919 name = getlogin();
1920 if (name == NULL) {
1921 if (errno)
1922 posix_error();
1923 else
1924 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00001925 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00001926 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00001927 else
1928 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00001929 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001930 }
1931 return result;
1932}
1933#endif
1934
Guido van Rossumad0ee831995-03-01 10:34:45 +00001935#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001936static char posix_getuid__doc__[] =
1937"getuid() -> uid\n\
1938Return the current process's user id.";
1939
Barry Warsaw53699e91996-12-10 23:23:01 +00001940static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001941posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001942{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001943 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001944 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001945 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001946}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001947#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001949
Guido van Rossumad0ee831995-03-01 10:34:45 +00001950#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001951static char posix_kill__doc__[] =
1952"kill(pid, sig) -> None\n\
1953Kill a process with a signal.";
1954
Barry Warsaw53699e91996-12-10 23:23:01 +00001955static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001956posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001957{
1958 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001959 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001960 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001961#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001962 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1963 APIRET rc;
1964 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001965 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001966
1967 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1968 APIRET rc;
1969 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001970 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001971
1972 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001973 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001974#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001975 if (kill(pid, sig) == -1)
1976 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001977#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001978 Py_INCREF(Py_None);
1979 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001980}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001981#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001982
Guido van Rossumc0125471996-06-28 18:55:32 +00001983#ifdef HAVE_PLOCK
1984
1985#ifdef HAVE_SYS_LOCK_H
1986#include <sys/lock.h>
1987#endif
1988
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001989static char posix_plock__doc__[] =
1990"plock(op) -> None\n\
1991Lock program segments into memory.";
1992
Barry Warsaw53699e91996-12-10 23:23:01 +00001993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001994posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001995{
1996 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001997 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001998 return NULL;
1999 if (plock(op) == -1)
2000 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002001 Py_INCREF(Py_None);
2002 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002003}
2004#endif
2005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002006
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002007#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002008static char posix_popen__doc__[] =
2009"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2010Open a pipe to/from a command returning a file object.";
2011
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002012#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002013static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002014async_system(const char *command)
2015{
2016 char *p, errormsg[256], args[1024];
2017 RESULTCODES rcodes;
2018 APIRET rc;
2019 char *shell = getenv("COMSPEC");
2020 if (!shell)
2021 shell = "cmd";
2022
2023 strcpy(args, shell);
2024 p = &args[ strlen(args)+1 ];
2025 strcpy(p, "/c ");
2026 strcat(p, command);
2027 p += strlen(p) + 1;
2028 *p = '\0';
2029
2030 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002031 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002032 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002033 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002034 &rcodes, shell);
2035 return rc;
2036}
2037
Guido van Rossumd48f2521997-12-05 22:19:34 +00002038static FILE *
2039popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002040{
2041 HFILE rhan, whan;
2042 FILE *retfd = NULL;
2043 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2044
Guido van Rossumd48f2521997-12-05 22:19:34 +00002045 if (rc != NO_ERROR) {
2046 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002047 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002048 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002049
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002050 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2051 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002052
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002053 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2054 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002055
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002056 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2057 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002058
2059 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002060 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002061 }
2062
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002063 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2064 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002065
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002066 close(oldfd); /* And Close Saved STDOUT Handle */
2067 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002068
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002069 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2070 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002071
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002072 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2073 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002075 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2076 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002077
2078 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002079 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002080 }
2081
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002082 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2083 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002084
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002085 close(oldfd); /* And Close Saved STDIN Handle */
2086 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002087
Guido van Rossumd48f2521997-12-05 22:19:34 +00002088 } else {
2089 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002090 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002091 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002092}
2093
2094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002095posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002096{
2097 char *name;
2098 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002099 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002100 FILE *fp;
2101 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002102 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002103 return NULL;
2104 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002105 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002106 Py_END_ALLOW_THREADS
2107 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002108 return os2_error(err);
2109
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002110 f = PyFile_FromFile(fp, name, mode, fclose);
2111 if (f != NULL)
2112 PyFile_SetBufSize(f, bufsize);
2113 return f;
2114}
2115
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002116#elif defined(MS_WIN32)
2117
2118/*
2119 * Portable 'popen' replacement for Win32.
2120 *
2121 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2122 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002123 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002124 */
2125
2126#include <malloc.h>
2127#include <io.h>
2128#include <fcntl.h>
2129
2130/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2131#define POPEN_1 1
2132#define POPEN_2 2
2133#define POPEN_3 3
2134#define POPEN_4 4
2135
2136static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002137static int _PyPclose(FILE *file);
2138
2139/*
2140 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002141 * for use when retrieving the process exit code. See _PyPclose() below
2142 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002143 */
2144static PyObject *_PyPopenProcs = NULL;
2145
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002146
2147/* popen that works from a GUI.
2148 *
2149 * The result of this function is a pipe (file) connected to the
2150 * processes stdin or stdout, depending on the requested mode.
2151 */
2152
2153static PyObject *
2154posix_popen(PyObject *self, PyObject *args)
2155{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002156 PyObject *f, *s;
2157 int tm = 0;
2158
2159 char *cmdstring;
2160 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002161 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002162 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002163 return NULL;
2164
2165 s = PyTuple_New(0);
2166
2167 if (*mode == 'r')
2168 tm = _O_RDONLY;
2169 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002170 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002171 return NULL;
2172 } else
2173 tm = _O_WRONLY;
2174
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002175 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002176 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002177 return NULL;
2178 }
2179
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002180 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002181 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002182 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002183 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002184 else
2185 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2186
2187 return f;
2188}
2189
2190/* Variation on win32pipe.popen
2191 *
2192 * The result of this function is a pipe (file) connected to the
2193 * process's stdin, and a pipe connected to the process's stdout.
2194 */
2195
2196static PyObject *
2197win32_popen2(PyObject *self, PyObject *args)
2198{
2199 PyObject *f;
2200 int tm=0;
2201
2202 char *cmdstring;
2203 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002204 int bufsize = -1;
2205 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002206 return NULL;
2207
2208 if (*mode == 't')
2209 tm = _O_TEXT;
2210 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002211 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002212 return NULL;
2213 } else
2214 tm = _O_BINARY;
2215
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002216 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002217 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002218 return NULL;
2219 }
2220
2221 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002222
2223 return f;
2224}
2225
2226/*
2227 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002228 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002229 * The result of this function is 3 pipes - the process's stdin,
2230 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002231 */
2232
2233static PyObject *
2234win32_popen3(PyObject *self, PyObject *args)
2235{
2236 PyObject *f;
2237 int tm = 0;
2238
2239 char *cmdstring;
2240 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002241 int bufsize = -1;
2242 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002243 return NULL;
2244
2245 if (*mode == 't')
2246 tm = _O_TEXT;
2247 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002248 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002249 return NULL;
2250 } else
2251 tm = _O_BINARY;
2252
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002253 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002254 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002255 return NULL;
2256 }
2257
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002258 f = _PyPopen(cmdstring, tm, POPEN_3);
2259
2260 return f;
2261}
2262
2263/*
2264 * Variation on win32pipe.popen
2265 *
2266 * The result of this function is 2 pipes - the processes stdin,
2267 * and stdout+stderr combined as a single pipe.
2268 */
2269
2270static PyObject *
2271win32_popen4(PyObject *self, PyObject *args)
2272{
2273 PyObject *f;
2274 int tm = 0;
2275
2276 char *cmdstring;
2277 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002278 int bufsize = -1;
2279 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002280 return NULL;
2281
2282 if (*mode == 't')
2283 tm = _O_TEXT;
2284 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002285 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002286 return NULL;
2287 } else
2288 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002289
2290 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002291 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002292 return NULL;
2293 }
2294
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002295 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002296
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002297 return f;
2298}
2299
Mark Hammond08501372001-01-31 07:30:29 +00002300static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002301_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002302 HANDLE hStdin,
2303 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002304 HANDLE hStderr,
2305 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002306{
2307 PROCESS_INFORMATION piProcInfo;
2308 STARTUPINFO siStartInfo;
2309 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002310 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002311 int i;
2312 int x;
2313
2314 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2315 s1 = (char *)_alloca(i);
2316 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2317 return x;
2318 if (GetVersion() < 0x80000000) {
2319 /*
2320 * NT/2000
2321 */
2322 x = i + strlen(s3) + strlen(cmdstring) + 1;
2323 s2 = (char *)_alloca(x);
2324 ZeroMemory(s2, x);
2325 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2326 }
2327 else {
2328 /*
2329 * Oh gag, we're on Win9x. Use the workaround listed in
2330 * KB: Q150956
2331 */
Mark Hammond08501372001-01-31 07:30:29 +00002332 char modulepath[_MAX_PATH];
2333 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002334 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2335 for (i = x = 0; modulepath[i]; i++)
2336 if (modulepath[i] == '\\')
2337 x = i+1;
2338 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002339 /* Create the full-name to w9xpopen, so we can test it exists */
2340 strncat(modulepath,
2341 szConsoleSpawn,
2342 (sizeof(modulepath)/sizeof(modulepath[0]))
2343 -strlen(modulepath));
2344 if (stat(modulepath, &statinfo) != 0) {
2345 /* Eeek - file-not-found - possibly an embedding
2346 situation - see if we can locate it in sys.prefix
2347 */
2348 strncpy(modulepath,
2349 Py_GetExecPrefix(),
2350 sizeof(modulepath)/sizeof(modulepath[0]));
2351 if (modulepath[strlen(modulepath)-1] != '\\')
2352 strcat(modulepath, "\\");
2353 strncat(modulepath,
2354 szConsoleSpawn,
2355 (sizeof(modulepath)/sizeof(modulepath[0]))
2356 -strlen(modulepath));
2357 /* No where else to look - raise an easily identifiable
2358 error, rather than leaving Windows to report
2359 "file not found" - as the user is probably blissfully
2360 unaware this shim EXE is used, and it will confuse them.
2361 (well, it confused me for a while ;-)
2362 */
2363 if (stat(modulepath, &statinfo) != 0) {
2364 PyErr_Format(PyExc_RuntimeError,
2365 "Can not locate '%s' which is needed "
2366 "for popen to work on this platform.",
2367 szConsoleSpawn);
2368 return FALSE;
2369 }
2370 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002371 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2372 strlen(modulepath) +
2373 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002374
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002375 s2 = (char *)_alloca(x);
2376 ZeroMemory(s2, x);
2377 sprintf(
2378 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002379 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002380 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002381 s1,
2382 s3,
2383 cmdstring);
2384 }
2385 }
2386
2387 /* Could be an else here to try cmd.exe / command.com in the path
2388 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002389 else {
2390 PyErr_SetString(PyExc_RuntimeError, "Can not locate a COMSPEC environment variable to use as the shell");
2391 return FALSE;
2392 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002393
2394 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2395 siStartInfo.cb = sizeof(STARTUPINFO);
2396 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2397 siStartInfo.hStdInput = hStdin;
2398 siStartInfo.hStdOutput = hStdout;
2399 siStartInfo.hStdError = hStderr;
2400 siStartInfo.wShowWindow = SW_HIDE;
2401
2402 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002403 s2,
2404 NULL,
2405 NULL,
2406 TRUE,
2407 CREATE_NEW_CONSOLE,
2408 NULL,
2409 NULL,
2410 &siStartInfo,
2411 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002412 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002413 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002414
Mark Hammondb37a3732000-08-14 04:47:33 +00002415 /* Return process handle */
2416 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002417 return TRUE;
2418 }
Mark Hammond08501372001-01-31 07:30:29 +00002419 win32_error("CreateProcess", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002420 return FALSE;
2421}
2422
2423/* The following code is based off of KB: Q190351 */
2424
2425static PyObject *
2426_PyPopen(char *cmdstring, int mode, int n)
2427{
2428 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2429 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002430 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002431
2432 SECURITY_ATTRIBUTES saAttr;
2433 BOOL fSuccess;
2434 int fd1, fd2, fd3;
2435 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002436 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002437 PyObject *f;
2438
2439 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2440 saAttr.bInheritHandle = TRUE;
2441 saAttr.lpSecurityDescriptor = NULL;
2442
2443 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2444 return win32_error("CreatePipe", NULL);
2445
2446 /* Create new output read handle and the input write handle. Set
2447 * the inheritance properties to FALSE. Otherwise, the child inherits
2448 * the these handles; resulting in non-closeable handles to the pipes
2449 * being created. */
2450 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002451 GetCurrentProcess(), &hChildStdinWrDup, 0,
2452 FALSE,
2453 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002454 if (!fSuccess)
2455 return win32_error("DuplicateHandle", NULL);
2456
2457 /* Close the inheritable version of ChildStdin
2458 that we're using. */
2459 CloseHandle(hChildStdinWr);
2460
2461 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2462 return win32_error("CreatePipe", NULL);
2463
2464 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002465 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2466 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002467 if (!fSuccess)
2468 return win32_error("DuplicateHandle", NULL);
2469
2470 /* Close the inheritable version of ChildStdout
2471 that we're using. */
2472 CloseHandle(hChildStdoutRd);
2473
2474 if (n != POPEN_4) {
2475 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2476 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002477 fSuccess = DuplicateHandle(GetCurrentProcess(),
2478 hChildStderrRd,
2479 GetCurrentProcess(),
2480 &hChildStderrRdDup, 0,
2481 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002482 if (!fSuccess)
2483 return win32_error("DuplicateHandle", NULL);
2484 /* Close the inheritable version of ChildStdErr that we're using. */
2485 CloseHandle(hChildStderrRd);
2486 }
2487
2488 switch (n) {
2489 case POPEN_1:
2490 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2491 case _O_WRONLY | _O_TEXT:
2492 /* Case for writing to child Stdin in text mode. */
2493 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2494 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002495 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002496 PyFile_SetBufSize(f, 0);
2497 /* We don't care about these pipes anymore, so close them. */
2498 CloseHandle(hChildStdoutRdDup);
2499 CloseHandle(hChildStderrRdDup);
2500 break;
2501
2502 case _O_RDONLY | _O_TEXT:
2503 /* Case for reading from child Stdout in text mode. */
2504 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2505 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002506 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002507 PyFile_SetBufSize(f, 0);
2508 /* We don't care about these pipes anymore, so close them. */
2509 CloseHandle(hChildStdinWrDup);
2510 CloseHandle(hChildStderrRdDup);
2511 break;
2512
2513 case _O_RDONLY | _O_BINARY:
2514 /* Case for readinig from child Stdout in binary mode. */
2515 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2516 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002517 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002518 PyFile_SetBufSize(f, 0);
2519 /* We don't care about these pipes anymore, so close them. */
2520 CloseHandle(hChildStdinWrDup);
2521 CloseHandle(hChildStderrRdDup);
2522 break;
2523
2524 case _O_WRONLY | _O_BINARY:
2525 /* Case for writing to child Stdin in binary mode. */
2526 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2527 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002528 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002529 PyFile_SetBufSize(f, 0);
2530 /* We don't care about these pipes anymore, so close them. */
2531 CloseHandle(hChildStdoutRdDup);
2532 CloseHandle(hChildStderrRdDup);
2533 break;
2534 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002535 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002536 break;
2537
2538 case POPEN_2:
2539 case POPEN_4:
2540 {
2541 char *m1, *m2;
2542 PyObject *p1, *p2;
2543
2544 if (mode && _O_TEXT) {
2545 m1 = "r";
2546 m2 = "w";
2547 } else {
2548 m1 = "rb";
2549 m2 = "wb";
2550 }
2551
2552 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2553 f1 = _fdopen(fd1, m2);
2554 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2555 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002556 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002557 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002558 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002559 PyFile_SetBufSize(p2, 0);
2560
2561 if (n != 4)
2562 CloseHandle(hChildStderrRdDup);
2563
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002564 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002565 Py_XDECREF(p1);
2566 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002567 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002568 break;
2569 }
2570
2571 case POPEN_3:
2572 {
2573 char *m1, *m2;
2574 PyObject *p1, *p2, *p3;
2575
2576 if (mode && _O_TEXT) {
2577 m1 = "r";
2578 m2 = "w";
2579 } else {
2580 m1 = "rb";
2581 m2 = "wb";
2582 }
2583
2584 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2585 f1 = _fdopen(fd1, m2);
2586 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2587 f2 = _fdopen(fd2, m1);
2588 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2589 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002590 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002591 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2592 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002593 PyFile_SetBufSize(p1, 0);
2594 PyFile_SetBufSize(p2, 0);
2595 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002596 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002597 Py_XDECREF(p1);
2598 Py_XDECREF(p2);
2599 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002600 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002601 break;
2602 }
2603 }
2604
2605 if (n == POPEN_4) {
2606 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002607 hChildStdinRd,
2608 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002609 hChildStdoutWr,
2610 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002611 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002612 }
2613 else {
2614 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002615 hChildStdinRd,
2616 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002617 hChildStderrWr,
2618 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002619 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002620 }
2621
Mark Hammondb37a3732000-08-14 04:47:33 +00002622 /*
2623 * Insert the files we've created into the process dictionary
2624 * all referencing the list with the process handle and the
2625 * initial number of files (see description below in _PyPclose).
2626 * Since if _PyPclose later tried to wait on a process when all
2627 * handles weren't closed, it could create a deadlock with the
2628 * child, we spend some energy here to try to ensure that we
2629 * either insert all file handles into the dictionary or none
2630 * at all. It's a little clumsy with the various popen modes
2631 * and variable number of files involved.
2632 */
2633 if (!_PyPopenProcs) {
2634 _PyPopenProcs = PyDict_New();
2635 }
2636
2637 if (_PyPopenProcs) {
2638 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2639 int ins_rc[3];
2640
2641 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2642 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2643
2644 procObj = PyList_New(2);
2645 hProcessObj = PyLong_FromVoidPtr(hProcess);
2646 intObj = PyInt_FromLong(file_count);
2647
2648 if (procObj && hProcessObj && intObj) {
2649 PyList_SetItem(procObj,0,hProcessObj);
2650 PyList_SetItem(procObj,1,intObj);
2651
2652 fileObj[0] = PyLong_FromVoidPtr(f1);
2653 if (fileObj[0]) {
2654 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2655 fileObj[0],
2656 procObj);
2657 }
2658 if (file_count >= 2) {
2659 fileObj[1] = PyLong_FromVoidPtr(f2);
2660 if (fileObj[1]) {
2661 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2662 fileObj[1],
2663 procObj);
2664 }
2665 }
2666 if (file_count >= 3) {
2667 fileObj[2] = PyLong_FromVoidPtr(f3);
2668 if (fileObj[2]) {
2669 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2670 fileObj[2],
2671 procObj);
2672 }
2673 }
2674
2675 if (ins_rc[0] < 0 || !fileObj[0] ||
2676 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2677 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2678 /* Something failed - remove any dictionary
2679 * entries that did make it.
2680 */
2681 if (!ins_rc[0] && fileObj[0]) {
2682 PyDict_DelItem(_PyPopenProcs,
2683 fileObj[0]);
2684 }
2685 if (!ins_rc[1] && fileObj[1]) {
2686 PyDict_DelItem(_PyPopenProcs,
2687 fileObj[1]);
2688 }
2689 if (!ins_rc[2] && fileObj[2]) {
2690 PyDict_DelItem(_PyPopenProcs,
2691 fileObj[2]);
2692 }
2693 }
2694 }
2695
2696 /*
2697 * Clean up our localized references for the dictionary keys
2698 * and value since PyDict_SetItem will Py_INCREF any copies
2699 * that got placed in the dictionary.
2700 */
2701 Py_XDECREF(procObj);
2702 Py_XDECREF(fileObj[0]);
2703 Py_XDECREF(fileObj[1]);
2704 Py_XDECREF(fileObj[2]);
2705 }
2706
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002707 /* Child is launched. Close the parents copy of those pipe
2708 * handles that only the child should have open. You need to
2709 * make sure that no handles to the write end of the output pipe
2710 * are maintained in this process or else the pipe will not close
2711 * when the child process exits and the ReadFile will hang. */
2712
2713 if (!CloseHandle(hChildStdinRd))
2714 return win32_error("CloseHandle", NULL);
2715
2716 if (!CloseHandle(hChildStdoutWr))
2717 return win32_error("CloseHandle", NULL);
2718
2719 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2720 return win32_error("CloseHandle", NULL);
2721
2722 return f;
2723}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002724
2725/*
2726 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2727 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002728 *
2729 * This function uses the _PyPopenProcs dictionary in order to map the
2730 * input file pointer to information about the process that was
2731 * originally created by the popen* call that created the file pointer.
2732 * The dictionary uses the file pointer as a key (with one entry
2733 * inserted for each file returned by the original popen* call) and a
2734 * single list object as the value for all files from a single call.
2735 * The list object contains the Win32 process handle at [0], and a file
2736 * count at [1], which is initialized to the total number of file
2737 * handles using that list.
2738 *
2739 * This function closes whichever handle it is passed, and decrements
2740 * the file count in the dictionary for the process handle pointed to
2741 * by this file. On the last close (when the file count reaches zero),
2742 * this function will wait for the child process and then return its
2743 * exit code as the result of the close() operation. This permits the
2744 * files to be closed in any order - it is always the close() of the
2745 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002746 */
Tim Peters736aa322000-09-01 06:51:24 +00002747
2748 /* RED_FLAG 31-Aug-2000 Tim
2749 * This is always called (today!) between a pair of
2750 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2751 * macros. So the thread running this has no valid thread state, as
2752 * far as Python is concerned. However, this calls some Python API
2753 * functions that cannot be called safely without a valid thread
2754 * state, in particular PyDict_GetItem.
2755 * As a temporary hack (although it may last for years ...), we
2756 * *rely* on not having a valid thread state in this function, in
2757 * order to create our own "from scratch".
2758 * This will deadlock if _PyPclose is ever called by a thread
2759 * holding the global lock.
2760 */
2761
Fredrik Lundh56055a42000-07-23 19:47:12 +00002762static int _PyPclose(FILE *file)
2763{
Fredrik Lundh20318932000-07-26 17:29:12 +00002764 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002765 DWORD exit_code;
2766 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002767 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2768 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002769#ifdef WITH_THREAD
2770 PyInterpreterState* pInterpreterState;
2771 PyThreadState* pThreadState;
2772#endif
2773
Fredrik Lundh20318932000-07-26 17:29:12 +00002774 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002775 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002776 */
2777 result = fclose(file);
2778
Tim Peters736aa322000-09-01 06:51:24 +00002779#ifdef WITH_THREAD
2780 /* Bootstrap a valid thread state into existence. */
2781 pInterpreterState = PyInterpreterState_New();
2782 if (!pInterpreterState) {
2783 /* Well, we're hosed now! We don't have a thread
2784 * state, so can't call a nice error routine, or raise
2785 * an exception. Just die.
2786 */
2787 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002788 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002789 return -1; /* unreachable */
2790 }
2791 pThreadState = PyThreadState_New(pInterpreterState);
2792 if (!pThreadState) {
2793 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002794 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002795 return -1; /* unreachable */
2796 }
2797 /* Grab the global lock. Note that this will deadlock if the
2798 * current thread already has the lock! (see RED_FLAG comments
2799 * before this function)
2800 */
2801 PyEval_RestoreThread(pThreadState);
2802#endif
2803
Fredrik Lundh56055a42000-07-23 19:47:12 +00002804 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002805 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2806 (procObj = PyDict_GetItem(_PyPopenProcs,
2807 fileObj)) != NULL &&
2808 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2809 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2810
2811 hProcess = PyLong_AsVoidPtr(hProcessObj);
2812 file_count = PyInt_AsLong(intObj);
2813
2814 if (file_count > 1) {
2815 /* Still other files referencing process */
2816 file_count--;
2817 PyList_SetItem(procObj,1,
2818 PyInt_FromLong(file_count));
2819 } else {
2820 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002821 if (result != EOF &&
2822 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2823 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002824 /* Possible truncation here in 16-bit environments, but
2825 * real exit codes are just the lower byte in any event.
2826 */
2827 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002828 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002829 /* Indicate failure - this will cause the file object
2830 * to raise an I/O error and translate the last Win32
2831 * error code from errno. We do have a problem with
2832 * last errors that overlap the normal errno table,
2833 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002834 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002835 if (result != EOF) {
2836 /* If the error wasn't from the fclose(), then
2837 * set errno for the file object error handling.
2838 */
2839 errno = GetLastError();
2840 }
2841 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002842 }
2843
2844 /* Free up the native handle at this point */
2845 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002846 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002847
Mark Hammondb37a3732000-08-14 04:47:33 +00002848 /* Remove this file pointer from dictionary */
2849 PyDict_DelItem(_PyPopenProcs, fileObj);
2850
2851 if (PyDict_Size(_PyPopenProcs) == 0) {
2852 Py_DECREF(_PyPopenProcs);
2853 _PyPopenProcs = NULL;
2854 }
2855
2856 } /* if object retrieval ok */
2857
2858 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002859 } /* if _PyPopenProcs */
2860
Tim Peters736aa322000-09-01 06:51:24 +00002861#ifdef WITH_THREAD
2862 /* Tear down the thread & interpreter states.
2863 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002864 * call the thread clear & delete functions, and indeed insist on
2865 * doing that themselves. The lock must be held during the clear, but
2866 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002867 */
2868 PyInterpreterState_Clear(pInterpreterState);
2869 PyEval_ReleaseThread(pThreadState);
2870 PyInterpreterState_Delete(pInterpreterState);
2871#endif
2872
Fredrik Lundh56055a42000-07-23 19:47:12 +00002873 return result;
2874}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002875
2876#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002878posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002879{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002880 char *name;
2881 char *mode = "r";
2882 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002883 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002884 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002885 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002886 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002887 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002888 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002889 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002890 if (fp == NULL)
2891 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002892 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002893 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002894 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002895 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002896}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002897#endif
2898
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002899#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002901
Guido van Rossumb6775db1994-08-01 11:34:53 +00002902#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002903static char posix_setuid__doc__[] =
2904"setuid(uid) -> None\n\
2905Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002907posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002908{
2909 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002910 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002911 return NULL;
2912 if (setuid(uid) < 0)
2913 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002914 Py_INCREF(Py_None);
2915 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002916}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002917#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002918
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002919
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002920#ifdef HAVE_SETEUID
2921static char posix_seteuid__doc__[] =
2922"seteuid(uid) -> None\n\
2923Set the current process's effective user id.";
2924static PyObject *
2925posix_seteuid (PyObject *self, PyObject *args)
2926{
2927 int euid;
2928 if (!PyArg_ParseTuple(args, "i", &euid)) {
2929 return NULL;
2930 } else if (seteuid(euid) < 0) {
2931 return posix_error();
2932 } else {
2933 Py_INCREF(Py_None);
2934 return Py_None;
2935 }
2936}
2937#endif /* HAVE_SETEUID */
2938
2939#ifdef HAVE_SETEGID
2940static char posix_setegid__doc__[] =
2941"setegid(gid) -> None\n\
2942Set the current process's effective group id.";
2943static PyObject *
2944posix_setegid (PyObject *self, PyObject *args)
2945{
2946 int egid;
2947 if (!PyArg_ParseTuple(args, "i", &egid)) {
2948 return NULL;
2949 } else if (setegid(egid) < 0) {
2950 return posix_error();
2951 } else {
2952 Py_INCREF(Py_None);
2953 return Py_None;
2954 }
2955}
2956#endif /* HAVE_SETEGID */
2957
2958#ifdef HAVE_SETREUID
2959static char posix_setreuid__doc__[] =
2960"seteuid(ruid, euid) -> None\n\
2961Set the current process's real and effective user ids.";
2962static PyObject *
2963posix_setreuid (PyObject *self, PyObject *args)
2964{
2965 int ruid, euid;
2966 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2967 return NULL;
2968 } else if (setreuid(ruid, euid) < 0) {
2969 return posix_error();
2970 } else {
2971 Py_INCREF(Py_None);
2972 return Py_None;
2973 }
2974}
2975#endif /* HAVE_SETREUID */
2976
2977#ifdef HAVE_SETREGID
2978static char posix_setregid__doc__[] =
2979"setegid(rgid, egid) -> None\n\
2980Set the current process's real and effective group ids.";
2981static PyObject *
2982posix_setregid (PyObject *self, PyObject *args)
2983{
2984 int rgid, egid;
2985 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2986 return NULL;
2987 } else if (setregid(rgid, egid) < 0) {
2988 return posix_error();
2989 } else {
2990 Py_INCREF(Py_None);
2991 return Py_None;
2992 }
2993}
2994#endif /* HAVE_SETREGID */
2995
Guido van Rossumb6775db1994-08-01 11:34:53 +00002996#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002997static char posix_setgid__doc__[] =
2998"setgid(gid) -> None\n\
2999Set the current process's group id.";
3000
Barry Warsaw53699e91996-12-10 23:23:01 +00003001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003002posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003003{
3004 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003005 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003006 return NULL;
3007 if (setgid(gid) < 0)
3008 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003009 Py_INCREF(Py_None);
3010 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003011}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003012#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003014
Guido van Rossumb6775db1994-08-01 11:34:53 +00003015#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003016static char posix_waitpid__doc__[] =
3017"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003018Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003019
Barry Warsaw53699e91996-12-10 23:23:01 +00003020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003021posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003022{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003023 int pid, options;
3024#ifdef UNION_WAIT
3025 union wait status;
3026#define status_i (status.w_status)
3027#else
3028 int status;
3029#define status_i status
3030#endif
3031 status_i = 0;
3032
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003033 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003034 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003035 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003036#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003037 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003038#else
3039 pid = waitpid(pid, &status, options);
3040#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003041 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003042 if (pid == -1)
3043 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003044 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003045 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003046}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003047#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003049
Guido van Rossumad0ee831995-03-01 10:34:45 +00003050#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003051static char posix_wait__doc__[] =
3052"wait() -> (pid, status)\n\
3053Wait for completion of a child process.";
3054
Barry Warsaw53699e91996-12-10 23:23:01 +00003055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003056posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003057{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003058 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003059#ifdef UNION_WAIT
3060 union wait status;
3061#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003062#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003063 int status;
3064#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003065#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003066 if (!PyArg_ParseTuple(args, ":wait"))
3067 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003068 status_i = 0;
3069 Py_BEGIN_ALLOW_THREADS
3070 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003071 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003072 if (pid == -1)
3073 return posix_error();
3074 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003075 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003076#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003077}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003078#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003079
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003080
3081static char posix_lstat__doc__[] =
3082"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3083Like stat(path), but do not follow symbolic links.";
3084
Barry Warsaw53699e91996-12-10 23:23:01 +00003085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003086posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003087{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003088#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003089 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003090#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00003091 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003092#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003093}
3094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003095
Guido van Rossumb6775db1994-08-01 11:34:53 +00003096#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003097static char posix_readlink__doc__[] =
3098"readlink(path) -> path\n\
3099Return a string representing the path to which the symbolic link points.";
3100
Barry Warsaw53699e91996-12-10 23:23:01 +00003101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003102posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003103{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003104 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003105 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003106 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003107 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003108 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003109 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003110 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003111 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003112 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003113 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003114 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003115}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003116#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003117
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003118
Guido van Rossumb6775db1994-08-01 11:34:53 +00003119#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003120static char posix_symlink__doc__[] =
3121"symlink(src, dst) -> None\n\
3122Create a symbolic link.";
3123
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003125posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003126{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003127 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003128}
3129#endif /* HAVE_SYMLINK */
3130
3131
3132#ifdef HAVE_TIMES
3133#ifndef HZ
3134#define HZ 60 /* Universal constant :-) */
3135#endif /* HZ */
3136
Guido van Rossumd48f2521997-12-05 22:19:34 +00003137#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3138static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003139system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003140{
3141 ULONG value = 0;
3142
3143 Py_BEGIN_ALLOW_THREADS
3144 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3145 Py_END_ALLOW_THREADS
3146
3147 return value;
3148}
3149
3150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003151posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003152{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003153 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003154 return NULL;
3155
3156 /* Currently Only Uptime is Provided -- Others Later */
3157 return Py_BuildValue("ddddd",
3158 (double)0 /* t.tms_utime / HZ */,
3159 (double)0 /* t.tms_stime / HZ */,
3160 (double)0 /* t.tms_cutime / HZ */,
3161 (double)0 /* t.tms_cstime / HZ */,
3162 (double)system_uptime() / 1000);
3163}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003164#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003166posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003167{
3168 struct tms t;
3169 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003170 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003171 return NULL;
3172 errno = 0;
3173 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003174 if (c == (clock_t) -1)
3175 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003176 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003177 (double)t.tms_utime / HZ,
3178 (double)t.tms_stime / HZ,
3179 (double)t.tms_cutime / HZ,
3180 (double)t.tms_cstime / HZ,
3181 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003182}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003183#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003184#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003185
3186
Guido van Rossum87755a21996-09-07 00:59:43 +00003187#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003188#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003189static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003190posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003191{
3192 FILETIME create, exit, kernel, user;
3193 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003194 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003195 return NULL;
3196 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003197 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3198 /* The fields of a FILETIME structure are the hi and lo part
3199 of a 64-bit value expressed in 100 nanosecond units.
3200 1e7 is one second in such units; 1e-7 the inverse.
3201 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3202 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003203 return Py_BuildValue(
3204 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003205 (double)(kernel.dwHighDateTime*429.4967296 +
3206 kernel.dwLowDateTime*1e-7),
3207 (double)(user.dwHighDateTime*429.4967296 +
3208 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003209 (double)0,
3210 (double)0,
3211 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003212}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003213#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003214
3215#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003216static char posix_times__doc__[] =
3217"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3218Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003219#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003221
Guido van Rossumb6775db1994-08-01 11:34:53 +00003222#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003223static char posix_setsid__doc__[] =
3224"setsid() -> None\n\
3225Call the system call setsid().";
3226
Barry Warsaw53699e91996-12-10 23:23:01 +00003227static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003228posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003229{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003230 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003231 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003232 if (setsid() < 0)
3233 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003234 Py_INCREF(Py_None);
3235 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003236}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003237#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003238
Guido van Rossumb6775db1994-08-01 11:34:53 +00003239#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003240static char posix_setpgid__doc__[] =
3241"setpgid(pid, pgrp) -> None\n\
3242Call the system call setpgid().";
3243
Barry Warsaw53699e91996-12-10 23:23:01 +00003244static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003245posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003246{
3247 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003248 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003249 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003250 if (setpgid(pid, pgrp) < 0)
3251 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003252 Py_INCREF(Py_None);
3253 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003254}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003255#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003256
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003257
Guido van Rossumb6775db1994-08-01 11:34:53 +00003258#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003259static char posix_tcgetpgrp__doc__[] =
3260"tcgetpgrp(fd) -> pgid\n\
3261Return the process group associated with the terminal given by a fd.";
3262
Barry Warsaw53699e91996-12-10 23:23:01 +00003263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003264posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003265{
3266 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003267 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003268 return NULL;
3269 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003270 if (pgid < 0)
3271 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003272 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003273}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003274#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003276
Guido van Rossumb6775db1994-08-01 11:34:53 +00003277#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003278static char posix_tcsetpgrp__doc__[] =
3279"tcsetpgrp(fd, pgid) -> None\n\
3280Set the process group associated with the terminal given by a fd.";
3281
Barry Warsaw53699e91996-12-10 23:23:01 +00003282static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003283posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003284{
3285 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003286 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003287 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003288 if (tcsetpgrp(fd, pgid) < 0)
3289 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003290 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003291 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003292}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003293#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003294
Guido van Rossum687dd131993-05-17 08:34:16 +00003295/* Functions acting on file descriptors */
3296
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003297static char posix_open__doc__[] =
3298"open(filename, flag [, mode=0777]) -> fd\n\
3299Open a file (for low level IO).";
3300
Barry Warsaw53699e91996-12-10 23:23:01 +00003301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003302posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003303{
3304 char *file;
3305 int flag;
3306 int mode = 0777;
3307 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003308 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3309 return NULL;
3310
Barry Warsaw53699e91996-12-10 23:23:01 +00003311 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003312 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003313 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003314 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003315 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003316 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003317}
3318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003319
3320static char posix_close__doc__[] =
3321"close(fd) -> None\n\
3322Close a file descriptor (for low level IO).";
3323
Barry Warsaw53699e91996-12-10 23:23:01 +00003324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003325posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003326{
3327 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003328 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003329 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003330 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003331 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003332 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003333 if (res < 0)
3334 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003335 Py_INCREF(Py_None);
3336 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003337}
3338
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003339
3340static char posix_dup__doc__[] =
3341"dup(fd) -> fd2\n\
3342Return a duplicate of a file descriptor.";
3343
Barry Warsaw53699e91996-12-10 23:23:01 +00003344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003345posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003346{
3347 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003348 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003349 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003350 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003351 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003352 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003353 if (fd < 0)
3354 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003355 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003356}
3357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003358
3359static char posix_dup2__doc__[] =
3360"dup2(fd, fd2) -> None\n\
3361Duplicate file descriptor.";
3362
Barry Warsaw53699e91996-12-10 23:23:01 +00003363static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003364posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003365{
3366 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003367 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003368 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003369 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003370 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003371 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003372 if (res < 0)
3373 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003374 Py_INCREF(Py_None);
3375 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003376}
3377
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003378
3379static char posix_lseek__doc__[] =
3380"lseek(fd, pos, how) -> newpos\n\
3381Set the current position of a file descriptor.";
3382
Barry Warsaw53699e91996-12-10 23:23:01 +00003383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003384posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003385{
3386 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003387#ifdef MS_WIN64
3388 LONG_LONG pos, res;
3389#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003390 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003391#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003392 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003393 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003394 return NULL;
3395#ifdef SEEK_SET
3396 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3397 switch (how) {
3398 case 0: how = SEEK_SET; break;
3399 case 1: how = SEEK_CUR; break;
3400 case 2: how = SEEK_END; break;
3401 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003402#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003403
3404#if !defined(HAVE_LARGEFILE_SUPPORT)
3405 pos = PyInt_AsLong(posobj);
3406#else
3407 pos = PyLong_Check(posobj) ?
3408 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3409#endif
3410 if (PyErr_Occurred())
3411 return NULL;
3412
Barry Warsaw53699e91996-12-10 23:23:01 +00003413 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003414#ifdef MS_WIN64
3415 res = _lseeki64(fd, pos, how);
3416#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003417 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003418#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003419 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003420 if (res < 0)
3421 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003422
3423#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003424 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003425#else
3426 return PyLong_FromLongLong(res);
3427#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003428}
3429
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003430
3431static char posix_read__doc__[] =
3432"read(fd, buffersize) -> string\n\
3433Read a file descriptor.";
3434
Barry Warsaw53699e91996-12-10 23:23:01 +00003435static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003436posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003437{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003438 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003439 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003440 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003441 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003442 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003443 if (buffer == NULL)
3444 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003445 Py_BEGIN_ALLOW_THREADS
3446 n = read(fd, PyString_AsString(buffer), size);
3447 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003448 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003449 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003450 return posix_error();
3451 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003452 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003453 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003454 return buffer;
3455}
3456
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003457
3458static char posix_write__doc__[] =
3459"write(fd, string) -> byteswritten\n\
3460Write a string to a file descriptor.";
3461
Barry Warsaw53699e91996-12-10 23:23:01 +00003462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003463posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003464{
3465 int fd, size;
3466 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003467 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003468 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003469 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003470 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003471 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003472 if (size < 0)
3473 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003474 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003475}
3476
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003477
3478static char posix_fstat__doc__[]=
3479"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3480Like stat(), but for an open file descriptor.";
3481
Barry Warsaw53699e91996-12-10 23:23:01 +00003482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003483posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003484{
3485 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003486 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003487 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003488 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003489 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003490 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003491 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003492 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003493 if (res != 0)
3494 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003495
3496 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003497}
3498
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003499
3500static char posix_fdopen__doc__[] =
3501"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3502Return an open file object connected to a file descriptor.";
3503
Barry Warsaw53699e91996-12-10 23:23:01 +00003504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003505posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003506{
Guido van Rossum687dd131993-05-17 08:34:16 +00003507 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003508 char *mode = "r";
3509 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003510 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003511 PyObject *f;
3512 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003513 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003514
Barry Warsaw53699e91996-12-10 23:23:01 +00003515 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003516 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003517 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003518 if (fp == NULL)
3519 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003520 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003521 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003522 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003523 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003524}
3525
Skip Montanaro1517d842000-07-19 14:34:14 +00003526static char posix_isatty__doc__[] =
3527"isatty(fd) -> Boolean\n\
3528Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003529connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003530
3531static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003532posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003533{
3534 int fd;
3535 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3536 return NULL;
3537 return Py_BuildValue("i", isatty(fd));
3538}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003539
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003540#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003541static char posix_pipe__doc__[] =
3542"pipe() -> (read_end, write_end)\n\
3543Create a pipe.";
3544
Barry Warsaw53699e91996-12-10 23:23:01 +00003545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003546posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003547{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003548#if defined(PYOS_OS2)
3549 HFILE read, write;
3550 APIRET rc;
3551
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003552 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003553 return NULL;
3554
3555 Py_BEGIN_ALLOW_THREADS
3556 rc = DosCreatePipe( &read, &write, 4096);
3557 Py_END_ALLOW_THREADS
3558 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003559 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003560
3561 return Py_BuildValue("(ii)", read, write);
3562#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003563#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003564 int fds[2];
3565 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003566 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003567 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003568 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003569 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003570 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003571 if (res != 0)
3572 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003573 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003574#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003575 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003576 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003577 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003578 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003579 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003580 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003581 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003582 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003583 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003584 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003585 read_fd = _open_osfhandle((intptr_t)read, 0);
3586 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003587 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003588#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003589#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003590}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003591#endif /* HAVE_PIPE */
3592
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003593
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003594#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003595static char posix_mkfifo__doc__[] =
3596"mkfifo(file, [, mode=0666]) -> None\n\
3597Create a FIFO (a POSIX named pipe).";
3598
Barry Warsaw53699e91996-12-10 23:23:01 +00003599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003600posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003601{
3602 char *file;
3603 int mode = 0666;
3604 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003605 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003606 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003607 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003608 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003609 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003610 if (res < 0)
3611 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003612 Py_INCREF(Py_None);
3613 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003614}
3615#endif
3616
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003617
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003618#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003619static char posix_ftruncate__doc__[] =
3620"ftruncate(fd, length) -> None\n\
3621Truncate a file to a specified length.";
3622
Barry Warsaw53699e91996-12-10 23:23:01 +00003623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003624posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003625{
3626 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003627 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003628 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003629 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003630
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003631 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003632 return NULL;
3633
3634#if !defined(HAVE_LARGEFILE_SUPPORT)
3635 length = PyInt_AsLong(lenobj);
3636#else
3637 length = PyLong_Check(lenobj) ?
3638 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3639#endif
3640 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003641 return NULL;
3642
Barry Warsaw53699e91996-12-10 23:23:01 +00003643 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003644 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003645 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003646 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003647 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003648 return NULL;
3649 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003650 Py_INCREF(Py_None);
3651 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003652}
3653#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003654
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003655#ifdef NeXT
3656#define HAVE_PUTENV
3657/* Steve Spicklemire got this putenv from NeXTAnswers */
3658static int
3659putenv(char *newval)
3660{
3661 extern char **environ;
3662
3663 static int firstTime = 1;
3664 char **ep;
3665 char *cp;
3666 int esiz;
3667 char *np;
3668
3669 if (!(np = strchr(newval, '=')))
3670 return 1;
3671 *np = '\0';
3672
3673 /* look it up */
3674 for (ep=environ ; *ep ; ep++)
3675 {
3676 /* this should always be true... */
3677 if (cp = strchr(*ep, '='))
3678 {
3679 *cp = '\0';
3680 if (!strcmp(*ep, newval))
3681 {
3682 /* got it! */
3683 *cp = '=';
3684 break;
3685 }
3686 *cp = '=';
3687 }
3688 else
3689 {
3690 *np = '=';
3691 return 1;
3692 }
3693 }
3694
3695 *np = '=';
3696 if (*ep)
3697 {
3698 /* the string was already there:
3699 just replace it with the new one */
3700 *ep = newval;
3701 return 0;
3702 }
3703
3704 /* expand environ by one */
3705 for (esiz=2, ep=environ ; *ep ; ep++)
3706 esiz++;
3707 if (firstTime)
3708 {
3709 char **epp;
3710 char **newenv;
3711 if (!(newenv = malloc(esiz * sizeof(char *))))
3712 return 1;
3713
3714 for (ep=environ, epp=newenv ; *ep ;)
3715 *epp++ = *ep++;
3716 *epp++ = newval;
3717 *epp = (char *) 0;
3718 environ = newenv;
3719 }
3720 else
3721 {
3722 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3723 return 1;
3724 environ[esiz - 2] = newval;
3725 environ[esiz - 1] = (char *) 0;
3726 firstTime = 0;
3727 }
3728
3729 return 0;
3730}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003731#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003732
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003733
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003734#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003735static char posix_putenv__doc__[] =
3736"putenv(key, value) -> None\n\
3737Change or add an environment variable.";
3738
Fred Drake762e2061999-08-26 17:23:54 +00003739/* Save putenv() parameters as values here, so we can collect them when they
3740 * get re-set with another call for the same key. */
3741static PyObject *posix_putenv_garbage;
3742
Barry Warsaw53699e91996-12-10 23:23:01 +00003743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003744posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003745{
3746 char *s1, *s2;
3747 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003748 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003749
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003750 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003751 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003752
3753#if defined(PYOS_OS2)
3754 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3755 APIRET rc;
3756
3757 if (strlen(s2) == 0) /* If New Value is an Empty String */
3758 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3759
3760 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3761 if (rc != NO_ERROR)
3762 return os2_error(rc);
3763
3764 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3765 APIRET rc;
3766
3767 if (strlen(s2) == 0) /* If New Value is an Empty String */
3768 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3769
3770 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3771 if (rc != NO_ERROR)
3772 return os2_error(rc);
3773 } else {
3774#endif
3775
Fred Drake762e2061999-08-26 17:23:54 +00003776 /* XXX This can leak memory -- not easy to fix :-( */
3777 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3778 if (newstr == NULL)
3779 return PyErr_NoMemory();
3780 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003781 (void) sprintf(new, "%s=%s", s1, s2);
3782 if (putenv(new)) {
3783 posix_error();
3784 return NULL;
3785 }
Fred Drake762e2061999-08-26 17:23:54 +00003786 /* Install the first arg and newstr in posix_putenv_garbage;
3787 * this will cause previous value to be collected. This has to
3788 * happen after the real putenv() call because the old value
3789 * was still accessible until then. */
3790 if (PyDict_SetItem(posix_putenv_garbage,
3791 PyTuple_GET_ITEM(args, 0), newstr)) {
3792 /* really not much we can do; just leak */
3793 PyErr_Clear();
3794 }
3795 else {
3796 Py_DECREF(newstr);
3797 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003798
3799#if defined(PYOS_OS2)
3800 }
3801#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003802 Py_INCREF(Py_None);
3803 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003804}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003805#endif /* putenv */
3806
3807#ifdef HAVE_STRERROR
3808static char posix_strerror__doc__[] =
3809"strerror(code) -> string\n\
3810Translate an error code to a message string.";
3811
3812PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003813posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003814{
3815 int code;
3816 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003817 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003818 return NULL;
3819 message = strerror(code);
3820 if (message == NULL) {
3821 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003822 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003823 return NULL;
3824 }
3825 return PyString_FromString(message);
3826}
3827#endif /* strerror */
3828
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003829
Guido van Rossumc9641791998-08-04 15:26:23 +00003830#ifdef HAVE_SYS_WAIT_H
3831
3832#ifdef WIFSTOPPED
3833static char posix_WIFSTOPPED__doc__[] =
3834"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003835Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003836
3837static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003838posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003839{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003840#ifdef UNION_WAIT
3841 union wait status;
3842#define status_i (status.w_status)
3843#else
3844 int status;
3845#define status_i status
3846#endif
3847 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003848
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003849 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003850 {
3851 return NULL;
3852 }
3853
3854 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003855#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003856}
3857#endif /* WIFSTOPPED */
3858
3859#ifdef WIFSIGNALED
3860static char posix_WIFSIGNALED__doc__[] =
3861"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003862Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003863
3864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003865posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003866{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003867#ifdef UNION_WAIT
3868 union wait status;
3869#define status_i (status.w_status)
3870#else
3871 int status;
3872#define status_i status
3873#endif
3874 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003875
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003876 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003877 {
3878 return NULL;
3879 }
3880
3881 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003882#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003883}
3884#endif /* WIFSIGNALED */
3885
3886#ifdef WIFEXITED
3887static char posix_WIFEXITED__doc__[] =
3888"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003889Return true if the process returning 'status' exited using the exit()\n\
3890system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003891
3892static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003893posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003894{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003895#ifdef UNION_WAIT
3896 union wait status;
3897#define status_i (status.w_status)
3898#else
3899 int status;
3900#define status_i status
3901#endif
3902 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003903
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003904 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003905 {
3906 return NULL;
3907 }
3908
3909 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003910#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003911}
3912#endif /* WIFEXITED */
3913
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003914#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003915static char posix_WEXITSTATUS__doc__[] =
3916"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003917Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003918
3919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003920posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003921{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003922#ifdef UNION_WAIT
3923 union wait status;
3924#define status_i (status.w_status)
3925#else
3926 int status;
3927#define status_i status
3928#endif
3929 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003930
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003931 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003932 {
3933 return NULL;
3934 }
3935
3936 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003937#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003938}
3939#endif /* WEXITSTATUS */
3940
3941#ifdef WTERMSIG
3942static char posix_WTERMSIG__doc__[] =
3943"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003944Return the signal that terminated the process that provided the 'status'\n\
3945value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003946
3947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003948posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003949{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003950#ifdef UNION_WAIT
3951 union wait status;
3952#define status_i (status.w_status)
3953#else
3954 int status;
3955#define status_i status
3956#endif
3957 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003958
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003959 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003960 {
3961 return NULL;
3962 }
3963
3964 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003965#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003966}
3967#endif /* WTERMSIG */
3968
3969#ifdef WSTOPSIG
3970static char posix_WSTOPSIG__doc__[] =
3971"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003972Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003973
3974static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003975posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003976{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003977#ifdef UNION_WAIT
3978 union wait status;
3979#define status_i (status.w_status)
3980#else
3981 int status;
3982#define status_i status
3983#endif
3984 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003985
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003986 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003987 {
3988 return NULL;
3989 }
3990
3991 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003992#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003993}
3994#endif /* WSTOPSIG */
3995
3996#endif /* HAVE_SYS_WAIT_H */
3997
3998
Guido van Rossum94f6f721999-01-06 18:42:14 +00003999#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004000#ifdef _SCO_DS
4001/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4002 needed definitions in sys/statvfs.h */
4003#define _SVID3
4004#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004005#include <sys/statvfs.h>
4006
4007static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004008"fstatvfs(fd) -> \n\
4009 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004010Perform an fstatvfs system call on the given fd.";
4011
4012static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004013posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004014{
4015 int fd, res;
4016 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004017 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004018 return NULL;
4019 Py_BEGIN_ALLOW_THREADS
4020 res = fstatvfs(fd, &st);
4021 Py_END_ALLOW_THREADS
4022 if (res != 0)
4023 return posix_error();
4024#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004025 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004026 (long) st.f_bsize,
4027 (long) st.f_frsize,
4028 (long) st.f_blocks,
4029 (long) st.f_bfree,
4030 (long) st.f_bavail,
4031 (long) st.f_files,
4032 (long) st.f_ffree,
4033 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004034 (long) st.f_flag,
4035 (long) st.f_namemax);
4036#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004037 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004038 (long) st.f_bsize,
4039 (long) st.f_frsize,
4040 (LONG_LONG) st.f_blocks,
4041 (LONG_LONG) st.f_bfree,
4042 (LONG_LONG) st.f_bavail,
4043 (LONG_LONG) st.f_files,
4044 (LONG_LONG) st.f_ffree,
4045 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004046 (long) st.f_flag,
4047 (long) st.f_namemax);
4048#endif
4049}
4050#endif /* HAVE_FSTATVFS */
4051
4052
4053#if defined(HAVE_STATVFS)
4054#include <sys/statvfs.h>
4055
4056static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004057"statvfs(path) -> \n\
4058 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004059Perform a statvfs system call on the given path.";
4060
4061static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004062posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004063{
4064 char *path;
4065 int res;
4066 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004067 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004068 return NULL;
4069 Py_BEGIN_ALLOW_THREADS
4070 res = statvfs(path, &st);
4071 Py_END_ALLOW_THREADS
4072 if (res != 0)
4073 return posix_error_with_filename(path);
4074#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004075 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004076 (long) st.f_bsize,
4077 (long) st.f_frsize,
4078 (long) st.f_blocks,
4079 (long) st.f_bfree,
4080 (long) st.f_bavail,
4081 (long) st.f_files,
4082 (long) st.f_ffree,
4083 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004084 (long) st.f_flag,
4085 (long) st.f_namemax);
4086#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004087 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004088 (long) st.f_bsize,
4089 (long) st.f_frsize,
4090 (LONG_LONG) st.f_blocks,
4091 (LONG_LONG) st.f_bfree,
4092 (LONG_LONG) st.f_bavail,
4093 (LONG_LONG) st.f_files,
4094 (LONG_LONG) st.f_ffree,
4095 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004096 (long) st.f_flag,
4097 (long) st.f_namemax);
4098#endif
4099}
4100#endif /* HAVE_STATVFS */
4101
4102
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004103#ifdef HAVE_TEMPNAM
4104static char posix_tempnam__doc__[] = "\
4105tempnam([dir[, prefix]]) -> string\n\
4106Return a unique name for a temporary file.\n\
4107The directory and a short may be specified as strings; they may be omitted\n\
4108or None if not needed.";
4109
4110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004111posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004112{
4113 PyObject *result = NULL;
4114 char *dir = NULL;
4115 char *pfx = NULL;
4116 char *name;
4117
4118 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4119 return NULL;
4120 name = tempnam(dir, pfx);
4121 if (name == NULL)
4122 return PyErr_NoMemory();
4123 result = PyString_FromString(name);
4124 free(name);
4125 return result;
4126}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004127#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004128
4129
4130#ifdef HAVE_TMPFILE
4131static char posix_tmpfile__doc__[] = "\
4132tmpfile() -> file object\n\
4133Create a temporary file with no directory entries.";
4134
4135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004136posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004137{
4138 FILE *fp;
4139
4140 if (!PyArg_ParseTuple(args, ":tmpfile"))
4141 return NULL;
4142 fp = tmpfile();
4143 if (fp == NULL)
4144 return posix_error();
4145 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4146}
4147#endif
4148
4149
4150#ifdef HAVE_TMPNAM
4151static char posix_tmpnam__doc__[] = "\
4152tmpnam() -> string\n\
4153Return a unique name for a temporary file.";
4154
4155static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004156posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004157{
4158 char buffer[L_tmpnam];
4159 char *name;
4160
4161 if (!PyArg_ParseTuple(args, ":tmpnam"))
4162 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004163#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004164 name = tmpnam_r(buffer);
4165#else
4166 name = tmpnam(buffer);
4167#endif
4168 if (name == NULL) {
4169 PyErr_SetObject(PyExc_OSError,
4170 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004171#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004172 "unexpected NULL from tmpnam_r"
4173#else
4174 "unexpected NULL from tmpnam"
4175#endif
4176 ));
4177 return NULL;
4178 }
4179 return PyString_FromString(buffer);
4180}
4181#endif
4182
4183
Fred Drakec9680921999-12-13 16:37:25 +00004184/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4185 * It maps strings representing configuration variable names to
4186 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004187 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004188 * rarely-used constants. There are three separate tables that use
4189 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004190 *
4191 * This code is always included, even if none of the interfaces that
4192 * need it are included. The #if hackery needed to avoid it would be
4193 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004194 */
4195struct constdef {
4196 char *name;
4197 long value;
4198};
4199
Fred Drake12c6e2d1999-12-14 21:25:03 +00004200static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004201conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4202 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004203{
4204 if (PyInt_Check(arg)) {
4205 *valuep = PyInt_AS_LONG(arg);
4206 return 1;
4207 }
4208 if (PyString_Check(arg)) {
4209 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004210 size_t lo = 0;
4211 size_t mid;
4212 size_t hi = tablesize;
4213 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004214 char *confname = PyString_AS_STRING(arg);
4215 while (lo < hi) {
4216 mid = (lo + hi) / 2;
4217 cmp = strcmp(confname, table[mid].name);
4218 if (cmp < 0)
4219 hi = mid;
4220 else if (cmp > 0)
4221 lo = mid + 1;
4222 else {
4223 *valuep = table[mid].value;
4224 return 1;
4225 }
4226 }
4227 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4228 }
4229 else
4230 PyErr_SetString(PyExc_TypeError,
4231 "configuration names must be strings or integers");
4232 return 0;
4233}
4234
4235
4236#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4237static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004238#ifdef _PC_ABI_AIO_XFER_MAX
4239 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4240#endif
4241#ifdef _PC_ABI_ASYNC_IO
4242 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4243#endif
Fred Drakec9680921999-12-13 16:37:25 +00004244#ifdef _PC_ASYNC_IO
4245 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4246#endif
4247#ifdef _PC_CHOWN_RESTRICTED
4248 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4249#endif
4250#ifdef _PC_FILESIZEBITS
4251 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4252#endif
4253#ifdef _PC_LAST
4254 {"PC_LAST", _PC_LAST},
4255#endif
4256#ifdef _PC_LINK_MAX
4257 {"PC_LINK_MAX", _PC_LINK_MAX},
4258#endif
4259#ifdef _PC_MAX_CANON
4260 {"PC_MAX_CANON", _PC_MAX_CANON},
4261#endif
4262#ifdef _PC_MAX_INPUT
4263 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4264#endif
4265#ifdef _PC_NAME_MAX
4266 {"PC_NAME_MAX", _PC_NAME_MAX},
4267#endif
4268#ifdef _PC_NO_TRUNC
4269 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4270#endif
4271#ifdef _PC_PATH_MAX
4272 {"PC_PATH_MAX", _PC_PATH_MAX},
4273#endif
4274#ifdef _PC_PIPE_BUF
4275 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4276#endif
4277#ifdef _PC_PRIO_IO
4278 {"PC_PRIO_IO", _PC_PRIO_IO},
4279#endif
4280#ifdef _PC_SOCK_MAXBUF
4281 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4282#endif
4283#ifdef _PC_SYNC_IO
4284 {"PC_SYNC_IO", _PC_SYNC_IO},
4285#endif
4286#ifdef _PC_VDISABLE
4287 {"PC_VDISABLE", _PC_VDISABLE},
4288#endif
4289};
4290
Fred Drakec9680921999-12-13 16:37:25 +00004291static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004292conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004293{
4294 return conv_confname(arg, valuep, posix_constants_pathconf,
4295 sizeof(posix_constants_pathconf)
4296 / sizeof(struct constdef));
4297}
4298#endif
4299
4300#ifdef HAVE_FPATHCONF
4301static char posix_fpathconf__doc__[] = "\
4302fpathconf(fd, name) -> integer\n\
4303Return the configuration limit name for the file descriptor fd.\n\
4304If there is no limit, return -1.";
4305
4306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004307posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004308{
4309 PyObject *result = NULL;
4310 int name, fd;
4311
Fred Drake12c6e2d1999-12-14 21:25:03 +00004312 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4313 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004314 long limit;
4315
4316 errno = 0;
4317 limit = fpathconf(fd, name);
4318 if (limit == -1 && errno != 0)
4319 posix_error();
4320 else
4321 result = PyInt_FromLong(limit);
4322 }
4323 return result;
4324}
4325#endif
4326
4327
4328#ifdef HAVE_PATHCONF
4329static char posix_pathconf__doc__[] = "\
4330pathconf(path, name) -> integer\n\
4331Return the configuration limit name for the file or directory path.\n\
4332If there is no limit, return -1.";
4333
4334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004335posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004336{
4337 PyObject *result = NULL;
4338 int name;
4339 char *path;
4340
4341 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4342 conv_path_confname, &name)) {
4343 long limit;
4344
4345 errno = 0;
4346 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004347 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004348 if (errno == EINVAL)
4349 /* could be a path or name problem */
4350 posix_error();
4351 else
4352 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004353 }
Fred Drakec9680921999-12-13 16:37:25 +00004354 else
4355 result = PyInt_FromLong(limit);
4356 }
4357 return result;
4358}
4359#endif
4360
4361#ifdef HAVE_CONFSTR
4362static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004363#ifdef _CS_ARCHITECTURE
4364 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4365#endif
4366#ifdef _CS_HOSTNAME
4367 {"CS_HOSTNAME", _CS_HOSTNAME},
4368#endif
4369#ifdef _CS_HW_PROVIDER
4370 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4371#endif
4372#ifdef _CS_HW_SERIAL
4373 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4374#endif
4375#ifdef _CS_INITTAB_NAME
4376 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4377#endif
Fred Drakec9680921999-12-13 16:37:25 +00004378#ifdef _CS_LFS64_CFLAGS
4379 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4380#endif
4381#ifdef _CS_LFS64_LDFLAGS
4382 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4383#endif
4384#ifdef _CS_LFS64_LIBS
4385 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4386#endif
4387#ifdef _CS_LFS64_LINTFLAGS
4388 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4389#endif
4390#ifdef _CS_LFS_CFLAGS
4391 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4392#endif
4393#ifdef _CS_LFS_LDFLAGS
4394 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4395#endif
4396#ifdef _CS_LFS_LIBS
4397 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4398#endif
4399#ifdef _CS_LFS_LINTFLAGS
4400 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4401#endif
Fred Draked86ed291999-12-15 15:34:33 +00004402#ifdef _CS_MACHINE
4403 {"CS_MACHINE", _CS_MACHINE},
4404#endif
Fred Drakec9680921999-12-13 16:37:25 +00004405#ifdef _CS_PATH
4406 {"CS_PATH", _CS_PATH},
4407#endif
Fred Draked86ed291999-12-15 15:34:33 +00004408#ifdef _CS_RELEASE
4409 {"CS_RELEASE", _CS_RELEASE},
4410#endif
4411#ifdef _CS_SRPC_DOMAIN
4412 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4413#endif
4414#ifdef _CS_SYSNAME
4415 {"CS_SYSNAME", _CS_SYSNAME},
4416#endif
4417#ifdef _CS_VERSION
4418 {"CS_VERSION", _CS_VERSION},
4419#endif
Fred Drakec9680921999-12-13 16:37:25 +00004420#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4421 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4422#endif
4423#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4424 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4425#endif
4426#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4427 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4428#endif
4429#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4430 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4431#endif
4432#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4433 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4434#endif
4435#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4436 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4437#endif
4438#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4439 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4440#endif
4441#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4442 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4443#endif
4444#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4445 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4446#endif
4447#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4448 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4449#endif
4450#ifdef _CS_XBS5_LP64_OFF64_LIBS
4451 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4452#endif
4453#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4454 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4455#endif
4456#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4457 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4458#endif
4459#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4460 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4461#endif
4462#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4463 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4464#endif
4465#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4466 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4467#endif
Fred Draked86ed291999-12-15 15:34:33 +00004468#ifdef _MIPS_CS_AVAIL_PROCESSORS
4469 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4470#endif
4471#ifdef _MIPS_CS_BASE
4472 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4473#endif
4474#ifdef _MIPS_CS_HOSTID
4475 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4476#endif
4477#ifdef _MIPS_CS_HW_NAME
4478 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4479#endif
4480#ifdef _MIPS_CS_NUM_PROCESSORS
4481 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4482#endif
4483#ifdef _MIPS_CS_OSREL_MAJ
4484 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4485#endif
4486#ifdef _MIPS_CS_OSREL_MIN
4487 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4488#endif
4489#ifdef _MIPS_CS_OSREL_PATCH
4490 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4491#endif
4492#ifdef _MIPS_CS_OS_NAME
4493 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4494#endif
4495#ifdef _MIPS_CS_OS_PROVIDER
4496 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4497#endif
4498#ifdef _MIPS_CS_PROCESSORS
4499 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4500#endif
4501#ifdef _MIPS_CS_SERIAL
4502 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4503#endif
4504#ifdef _MIPS_CS_VENDOR
4505 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4506#endif
Fred Drakec9680921999-12-13 16:37:25 +00004507};
4508
4509static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004510conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004511{
4512 return conv_confname(arg, valuep, posix_constants_confstr,
4513 sizeof(posix_constants_confstr)
4514 / sizeof(struct constdef));
4515}
4516
4517static char posix_confstr__doc__[] = "\
4518confstr(name) -> string\n\
4519Return a string-valued system configuration variable.";
4520
4521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004522posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004523{
4524 PyObject *result = NULL;
4525 int name;
4526 char buffer[64];
4527
4528 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4529 int len = confstr(name, buffer, sizeof(buffer));
4530
Fred Drakec9680921999-12-13 16:37:25 +00004531 errno = 0;
4532 if (len == 0) {
4533 if (errno != 0)
4534 posix_error();
4535 else
4536 result = PyString_FromString("");
4537 }
4538 else {
4539 if (len >= sizeof(buffer)) {
4540 result = PyString_FromStringAndSize(NULL, len);
4541 if (result != NULL)
4542 confstr(name, PyString_AS_STRING(result), len+1);
4543 }
4544 else
4545 result = PyString_FromString(buffer);
4546 }
4547 }
4548 return result;
4549}
4550#endif
4551
4552
4553#ifdef HAVE_SYSCONF
4554static struct constdef posix_constants_sysconf[] = {
4555#ifdef _SC_2_CHAR_TERM
4556 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4557#endif
4558#ifdef _SC_2_C_BIND
4559 {"SC_2_C_BIND", _SC_2_C_BIND},
4560#endif
4561#ifdef _SC_2_C_DEV
4562 {"SC_2_C_DEV", _SC_2_C_DEV},
4563#endif
4564#ifdef _SC_2_C_VERSION
4565 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4566#endif
4567#ifdef _SC_2_FORT_DEV
4568 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4569#endif
4570#ifdef _SC_2_FORT_RUN
4571 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4572#endif
4573#ifdef _SC_2_LOCALEDEF
4574 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4575#endif
4576#ifdef _SC_2_SW_DEV
4577 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4578#endif
4579#ifdef _SC_2_UPE
4580 {"SC_2_UPE", _SC_2_UPE},
4581#endif
4582#ifdef _SC_2_VERSION
4583 {"SC_2_VERSION", _SC_2_VERSION},
4584#endif
Fred Draked86ed291999-12-15 15:34:33 +00004585#ifdef _SC_ABI_ASYNCHRONOUS_IO
4586 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4587#endif
4588#ifdef _SC_ACL
4589 {"SC_ACL", _SC_ACL},
4590#endif
Fred Drakec9680921999-12-13 16:37:25 +00004591#ifdef _SC_AIO_LISTIO_MAX
4592 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4593#endif
Fred Drakec9680921999-12-13 16:37:25 +00004594#ifdef _SC_AIO_MAX
4595 {"SC_AIO_MAX", _SC_AIO_MAX},
4596#endif
4597#ifdef _SC_AIO_PRIO_DELTA_MAX
4598 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4599#endif
4600#ifdef _SC_ARG_MAX
4601 {"SC_ARG_MAX", _SC_ARG_MAX},
4602#endif
4603#ifdef _SC_ASYNCHRONOUS_IO
4604 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4605#endif
4606#ifdef _SC_ATEXIT_MAX
4607 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4608#endif
Fred Draked86ed291999-12-15 15:34:33 +00004609#ifdef _SC_AUDIT
4610 {"SC_AUDIT", _SC_AUDIT},
4611#endif
Fred Drakec9680921999-12-13 16:37:25 +00004612#ifdef _SC_AVPHYS_PAGES
4613 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4614#endif
4615#ifdef _SC_BC_BASE_MAX
4616 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4617#endif
4618#ifdef _SC_BC_DIM_MAX
4619 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4620#endif
4621#ifdef _SC_BC_SCALE_MAX
4622 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4623#endif
4624#ifdef _SC_BC_STRING_MAX
4625 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4626#endif
Fred Draked86ed291999-12-15 15:34:33 +00004627#ifdef _SC_CAP
4628 {"SC_CAP", _SC_CAP},
4629#endif
Fred Drakec9680921999-12-13 16:37:25 +00004630#ifdef _SC_CHARCLASS_NAME_MAX
4631 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4632#endif
4633#ifdef _SC_CHAR_BIT
4634 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4635#endif
4636#ifdef _SC_CHAR_MAX
4637 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4638#endif
4639#ifdef _SC_CHAR_MIN
4640 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4641#endif
4642#ifdef _SC_CHILD_MAX
4643 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4644#endif
4645#ifdef _SC_CLK_TCK
4646 {"SC_CLK_TCK", _SC_CLK_TCK},
4647#endif
4648#ifdef _SC_COHER_BLKSZ
4649 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4650#endif
4651#ifdef _SC_COLL_WEIGHTS_MAX
4652 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4653#endif
4654#ifdef _SC_DCACHE_ASSOC
4655 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4656#endif
4657#ifdef _SC_DCACHE_BLKSZ
4658 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4659#endif
4660#ifdef _SC_DCACHE_LINESZ
4661 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4662#endif
4663#ifdef _SC_DCACHE_SZ
4664 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4665#endif
4666#ifdef _SC_DCACHE_TBLKSZ
4667 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4668#endif
4669#ifdef _SC_DELAYTIMER_MAX
4670 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4671#endif
4672#ifdef _SC_EQUIV_CLASS_MAX
4673 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4674#endif
4675#ifdef _SC_EXPR_NEST_MAX
4676 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4677#endif
4678#ifdef _SC_FSYNC
4679 {"SC_FSYNC", _SC_FSYNC},
4680#endif
4681#ifdef _SC_GETGR_R_SIZE_MAX
4682 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4683#endif
4684#ifdef _SC_GETPW_R_SIZE_MAX
4685 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4686#endif
4687#ifdef _SC_ICACHE_ASSOC
4688 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4689#endif
4690#ifdef _SC_ICACHE_BLKSZ
4691 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4692#endif
4693#ifdef _SC_ICACHE_LINESZ
4694 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4695#endif
4696#ifdef _SC_ICACHE_SZ
4697 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4698#endif
Fred Draked86ed291999-12-15 15:34:33 +00004699#ifdef _SC_INF
4700 {"SC_INF", _SC_INF},
4701#endif
Fred Drakec9680921999-12-13 16:37:25 +00004702#ifdef _SC_INT_MAX
4703 {"SC_INT_MAX", _SC_INT_MAX},
4704#endif
4705#ifdef _SC_INT_MIN
4706 {"SC_INT_MIN", _SC_INT_MIN},
4707#endif
4708#ifdef _SC_IOV_MAX
4709 {"SC_IOV_MAX", _SC_IOV_MAX},
4710#endif
Fred Draked86ed291999-12-15 15:34:33 +00004711#ifdef _SC_IP_SECOPTS
4712 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4713#endif
Fred Drakec9680921999-12-13 16:37:25 +00004714#ifdef _SC_JOB_CONTROL
4715 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4716#endif
Fred Draked86ed291999-12-15 15:34:33 +00004717#ifdef _SC_KERN_POINTERS
4718 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4719#endif
4720#ifdef _SC_KERN_SIM
4721 {"SC_KERN_SIM", _SC_KERN_SIM},
4722#endif
Fred Drakec9680921999-12-13 16:37:25 +00004723#ifdef _SC_LINE_MAX
4724 {"SC_LINE_MAX", _SC_LINE_MAX},
4725#endif
4726#ifdef _SC_LOGIN_NAME_MAX
4727 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4728#endif
4729#ifdef _SC_LOGNAME_MAX
4730 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4731#endif
4732#ifdef _SC_LONG_BIT
4733 {"SC_LONG_BIT", _SC_LONG_BIT},
4734#endif
Fred Draked86ed291999-12-15 15:34:33 +00004735#ifdef _SC_MAC
4736 {"SC_MAC", _SC_MAC},
4737#endif
Fred Drakec9680921999-12-13 16:37:25 +00004738#ifdef _SC_MAPPED_FILES
4739 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4740#endif
4741#ifdef _SC_MAXPID
4742 {"SC_MAXPID", _SC_MAXPID},
4743#endif
4744#ifdef _SC_MB_LEN_MAX
4745 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4746#endif
4747#ifdef _SC_MEMLOCK
4748 {"SC_MEMLOCK", _SC_MEMLOCK},
4749#endif
4750#ifdef _SC_MEMLOCK_RANGE
4751 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4752#endif
4753#ifdef _SC_MEMORY_PROTECTION
4754 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4755#endif
4756#ifdef _SC_MESSAGE_PASSING
4757 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4758#endif
Fred Draked86ed291999-12-15 15:34:33 +00004759#ifdef _SC_MMAP_FIXED_ALIGNMENT
4760 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4761#endif
Fred Drakec9680921999-12-13 16:37:25 +00004762#ifdef _SC_MQ_OPEN_MAX
4763 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4764#endif
4765#ifdef _SC_MQ_PRIO_MAX
4766 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4767#endif
Fred Draked86ed291999-12-15 15:34:33 +00004768#ifdef _SC_NACLS_MAX
4769 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4770#endif
Fred Drakec9680921999-12-13 16:37:25 +00004771#ifdef _SC_NGROUPS_MAX
4772 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4773#endif
4774#ifdef _SC_NL_ARGMAX
4775 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4776#endif
4777#ifdef _SC_NL_LANGMAX
4778 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4779#endif
4780#ifdef _SC_NL_MSGMAX
4781 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4782#endif
4783#ifdef _SC_NL_NMAX
4784 {"SC_NL_NMAX", _SC_NL_NMAX},
4785#endif
4786#ifdef _SC_NL_SETMAX
4787 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4788#endif
4789#ifdef _SC_NL_TEXTMAX
4790 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4791#endif
4792#ifdef _SC_NPROCESSORS_CONF
4793 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4794#endif
4795#ifdef _SC_NPROCESSORS_ONLN
4796 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4797#endif
Fred Draked86ed291999-12-15 15:34:33 +00004798#ifdef _SC_NPROC_CONF
4799 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4800#endif
4801#ifdef _SC_NPROC_ONLN
4802 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4803#endif
Fred Drakec9680921999-12-13 16:37:25 +00004804#ifdef _SC_NZERO
4805 {"SC_NZERO", _SC_NZERO},
4806#endif
4807#ifdef _SC_OPEN_MAX
4808 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4809#endif
4810#ifdef _SC_PAGESIZE
4811 {"SC_PAGESIZE", _SC_PAGESIZE},
4812#endif
4813#ifdef _SC_PAGE_SIZE
4814 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4815#endif
4816#ifdef _SC_PASS_MAX
4817 {"SC_PASS_MAX", _SC_PASS_MAX},
4818#endif
4819#ifdef _SC_PHYS_PAGES
4820 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4821#endif
4822#ifdef _SC_PII
4823 {"SC_PII", _SC_PII},
4824#endif
4825#ifdef _SC_PII_INTERNET
4826 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4827#endif
4828#ifdef _SC_PII_INTERNET_DGRAM
4829 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4830#endif
4831#ifdef _SC_PII_INTERNET_STREAM
4832 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4833#endif
4834#ifdef _SC_PII_OSI
4835 {"SC_PII_OSI", _SC_PII_OSI},
4836#endif
4837#ifdef _SC_PII_OSI_CLTS
4838 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4839#endif
4840#ifdef _SC_PII_OSI_COTS
4841 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4842#endif
4843#ifdef _SC_PII_OSI_M
4844 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4845#endif
4846#ifdef _SC_PII_SOCKET
4847 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4848#endif
4849#ifdef _SC_PII_XTI
4850 {"SC_PII_XTI", _SC_PII_XTI},
4851#endif
4852#ifdef _SC_POLL
4853 {"SC_POLL", _SC_POLL},
4854#endif
4855#ifdef _SC_PRIORITIZED_IO
4856 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4857#endif
4858#ifdef _SC_PRIORITY_SCHEDULING
4859 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4860#endif
4861#ifdef _SC_REALTIME_SIGNALS
4862 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4863#endif
4864#ifdef _SC_RE_DUP_MAX
4865 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4866#endif
4867#ifdef _SC_RTSIG_MAX
4868 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4869#endif
4870#ifdef _SC_SAVED_IDS
4871 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4872#endif
4873#ifdef _SC_SCHAR_MAX
4874 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4875#endif
4876#ifdef _SC_SCHAR_MIN
4877 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4878#endif
4879#ifdef _SC_SELECT
4880 {"SC_SELECT", _SC_SELECT},
4881#endif
4882#ifdef _SC_SEMAPHORES
4883 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4884#endif
4885#ifdef _SC_SEM_NSEMS_MAX
4886 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4887#endif
4888#ifdef _SC_SEM_VALUE_MAX
4889 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4890#endif
4891#ifdef _SC_SHARED_MEMORY_OBJECTS
4892 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4893#endif
4894#ifdef _SC_SHRT_MAX
4895 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4896#endif
4897#ifdef _SC_SHRT_MIN
4898 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4899#endif
4900#ifdef _SC_SIGQUEUE_MAX
4901 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4902#endif
4903#ifdef _SC_SIGRT_MAX
4904 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4905#endif
4906#ifdef _SC_SIGRT_MIN
4907 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4908#endif
Fred Draked86ed291999-12-15 15:34:33 +00004909#ifdef _SC_SOFTPOWER
4910 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4911#endif
Fred Drakec9680921999-12-13 16:37:25 +00004912#ifdef _SC_SPLIT_CACHE
4913 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4914#endif
4915#ifdef _SC_SSIZE_MAX
4916 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4917#endif
4918#ifdef _SC_STACK_PROT
4919 {"SC_STACK_PROT", _SC_STACK_PROT},
4920#endif
4921#ifdef _SC_STREAM_MAX
4922 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4923#endif
4924#ifdef _SC_SYNCHRONIZED_IO
4925 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4926#endif
4927#ifdef _SC_THREADS
4928 {"SC_THREADS", _SC_THREADS},
4929#endif
4930#ifdef _SC_THREAD_ATTR_STACKADDR
4931 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4932#endif
4933#ifdef _SC_THREAD_ATTR_STACKSIZE
4934 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4935#endif
4936#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4937 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4938#endif
4939#ifdef _SC_THREAD_KEYS_MAX
4940 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4941#endif
4942#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4943 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4944#endif
4945#ifdef _SC_THREAD_PRIO_INHERIT
4946 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4947#endif
4948#ifdef _SC_THREAD_PRIO_PROTECT
4949 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4950#endif
4951#ifdef _SC_THREAD_PROCESS_SHARED
4952 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4953#endif
4954#ifdef _SC_THREAD_SAFE_FUNCTIONS
4955 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4956#endif
4957#ifdef _SC_THREAD_STACK_MIN
4958 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4959#endif
4960#ifdef _SC_THREAD_THREADS_MAX
4961 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4962#endif
4963#ifdef _SC_TIMERS
4964 {"SC_TIMERS", _SC_TIMERS},
4965#endif
4966#ifdef _SC_TIMER_MAX
4967 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4968#endif
4969#ifdef _SC_TTY_NAME_MAX
4970 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4971#endif
4972#ifdef _SC_TZNAME_MAX
4973 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4974#endif
4975#ifdef _SC_T_IOV_MAX
4976 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4977#endif
4978#ifdef _SC_UCHAR_MAX
4979 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4980#endif
4981#ifdef _SC_UINT_MAX
4982 {"SC_UINT_MAX", _SC_UINT_MAX},
4983#endif
4984#ifdef _SC_UIO_MAXIOV
4985 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4986#endif
4987#ifdef _SC_ULONG_MAX
4988 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4989#endif
4990#ifdef _SC_USHRT_MAX
4991 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4992#endif
4993#ifdef _SC_VERSION
4994 {"SC_VERSION", _SC_VERSION},
4995#endif
4996#ifdef _SC_WORD_BIT
4997 {"SC_WORD_BIT", _SC_WORD_BIT},
4998#endif
4999#ifdef _SC_XBS5_ILP32_OFF32
5000 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5001#endif
5002#ifdef _SC_XBS5_ILP32_OFFBIG
5003 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5004#endif
5005#ifdef _SC_XBS5_LP64_OFF64
5006 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5007#endif
5008#ifdef _SC_XBS5_LPBIG_OFFBIG
5009 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5010#endif
5011#ifdef _SC_XOPEN_CRYPT
5012 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5013#endif
5014#ifdef _SC_XOPEN_ENH_I18N
5015 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5016#endif
5017#ifdef _SC_XOPEN_LEGACY
5018 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5019#endif
5020#ifdef _SC_XOPEN_REALTIME
5021 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5022#endif
5023#ifdef _SC_XOPEN_REALTIME_THREADS
5024 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5025#endif
5026#ifdef _SC_XOPEN_SHM
5027 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5028#endif
5029#ifdef _SC_XOPEN_UNIX
5030 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5031#endif
5032#ifdef _SC_XOPEN_VERSION
5033 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5034#endif
5035#ifdef _SC_XOPEN_XCU_VERSION
5036 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5037#endif
5038#ifdef _SC_XOPEN_XPG2
5039 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5040#endif
5041#ifdef _SC_XOPEN_XPG3
5042 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5043#endif
5044#ifdef _SC_XOPEN_XPG4
5045 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5046#endif
5047};
5048
5049static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005050conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005051{
5052 return conv_confname(arg, valuep, posix_constants_sysconf,
5053 sizeof(posix_constants_sysconf)
5054 / sizeof(struct constdef));
5055}
5056
5057static char posix_sysconf__doc__[] = "\
5058sysconf(name) -> integer\n\
5059Return an integer-valued system configuration variable.";
5060
5061static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005062posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005063{
5064 PyObject *result = NULL;
5065 int name;
5066
5067 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5068 int value;
5069
5070 errno = 0;
5071 value = sysconf(name);
5072 if (value == -1 && errno != 0)
5073 posix_error();
5074 else
5075 result = PyInt_FromLong(value);
5076 }
5077 return result;
5078}
5079#endif
5080
5081
Fred Drakebec628d1999-12-15 18:31:10 +00005082/* This code is used to ensure that the tables of configuration value names
5083 * are in sorted order as required by conv_confname(), and also to build the
5084 * the exported dictionaries that are used to publish information about the
5085 * names available on the host platform.
5086 *
5087 * Sorting the table at runtime ensures that the table is properly ordered
5088 * when used, even for platforms we're not able to test on. It also makes
5089 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005090 */
Fred Drakebec628d1999-12-15 18:31:10 +00005091
5092static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005093cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005094{
5095 const struct constdef *c1 =
5096 (const struct constdef *) v1;
5097 const struct constdef *c2 =
5098 (const struct constdef *) v2;
5099
5100 return strcmp(c1->name, c2->name);
5101}
5102
5103static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005104setup_confname_table(struct constdef *table, size_t tablesize,
5105 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005106{
Fred Drakebec628d1999-12-15 18:31:10 +00005107 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005108 size_t i;
5109 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005110
5111 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5112 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005113 if (d == NULL)
5114 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005115
Barry Warsaw3155db32000-04-13 15:20:40 +00005116 for (i=0; i < tablesize; ++i) {
5117 PyObject *o = PyInt_FromLong(table[i].value);
5118 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5119 Py_XDECREF(o);
5120 Py_DECREF(d);
5121 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005122 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005123 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005124 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005125 status = PyDict_SetItemString(moddict, tablename, d);
5126 Py_DECREF(d);
5127 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005128}
5129
Fred Drakebec628d1999-12-15 18:31:10 +00005130/* Return -1 on failure, 0 on success. */
5131static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005132setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005133{
5134#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005135 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005136 sizeof(posix_constants_pathconf)
5137 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005138 "pathconf_names", moddict))
5139 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005140#endif
5141#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005142 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005143 sizeof(posix_constants_confstr)
5144 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005145 "confstr_names", moddict))
5146 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005147#endif
5148#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005149 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005150 sizeof(posix_constants_sysconf)
5151 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005152 "sysconf_names", moddict))
5153 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005154#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005155 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005156}
Fred Draked86ed291999-12-15 15:34:33 +00005157
5158
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005159static char posix_abort__doc__[] = "\
5160abort() -> does not return!\n\
5161Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5162in the hardest way possible on the hosting operating system.";
5163
5164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005165posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005166{
5167 if (!PyArg_ParseTuple(args, ":abort"))
5168 return NULL;
5169 abort();
5170 /*NOTREACHED*/
5171 Py_FatalError("abort() called from Python code didn't abort!");
5172 return NULL;
5173}
Fred Drakebec628d1999-12-15 18:31:10 +00005174
Tim Petersf58a7aa2000-09-22 10:05:54 +00005175#ifdef MS_WIN32
5176static char win32_startfile__doc__[] = "\
5177startfile(filepath) - Start a file with its associated application.\n\
5178\n\
5179This acts like double-clicking the file in Explorer, or giving the file\n\
5180name as an argument to the DOS \"start\" command: the file is opened\n\
5181with whatever application (if any) its extension is associated.\n\
5182\n\
5183startfile returns as soon as the associated application is launched.\n\
5184There is no option to wait for the application to close, and no way\n\
5185to retrieve the application's exit status.\n\
5186\n\
5187The filepath is relative to the current directory. If you want to use\n\
5188an absolute path, make sure the first character is not a slash (\"/\");\n\
5189the underlying Win32 ShellExecute function doesn't work if it is.";
5190
5191static PyObject *
5192win32_startfile(PyObject *self, PyObject *args)
5193{
5194 char *filepath;
5195 HINSTANCE rc;
5196 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5197 return NULL;
5198 Py_BEGIN_ALLOW_THREADS
5199 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5200 Py_END_ALLOW_THREADS
5201 if (rc <= (HINSTANCE)32)
5202 return win32_error("startfile", filepath);
5203 Py_INCREF(Py_None);
5204 return Py_None;
5205}
5206#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005207
5208static PyMethodDef posix_methods[] = {
5209 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5210#ifdef HAVE_TTYNAME
5211 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5212#endif
5213 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5214 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005215#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005216 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005217#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005218#ifdef HAVE_CTERMID
5219 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5220#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005221#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005222 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005223#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005224#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005225 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005226#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005227 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5228 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5229 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005230#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005231 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005232#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005233#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005234 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005235#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005236 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5237 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5238 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005239#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005240 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005241#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005242#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005243 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005244#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005245 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005246#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005247 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005248#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005249 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5250 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5251 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005252#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005253 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005254#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005255 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005256#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005257 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5258 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005259#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005260#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005261 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5262 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005263#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005264#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005265 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005266#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005267#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005268 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005269#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005270#ifdef HAVE_FORKPTY
5271 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5272#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005273#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005274 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005275#endif /* HAVE_GETEGID */
5276#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005277 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005278#endif /* HAVE_GETEUID */
5279#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005280 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005281#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005282#ifdef HAVE_GETGROUPS
5283 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5284#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005285 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005286#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005287 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005288#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005289#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005290 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005291#endif /* HAVE_GETPPID */
5292#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005293 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005294#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005295#ifdef HAVE_GETLOGIN
5296 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5297#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005298#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005299 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005300#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005301#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005302 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005303#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005304#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005305 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005306#ifdef MS_WIN32
5307 {"popen2", win32_popen2, METH_VARARGS},
5308 {"popen3", win32_popen3, METH_VARARGS},
5309 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005310 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005311#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005312#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005313#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005314 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005315#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005316#ifdef HAVE_SETEUID
5317 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5318#endif /* HAVE_SETEUID */
5319#ifdef HAVE_SETEGID
5320 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5321#endif /* HAVE_SETEGID */
5322#ifdef HAVE_SETREUID
5323 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5324#endif /* HAVE_SETREUID */
5325#ifdef HAVE_SETREGID
5326 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5327#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005328#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005329 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005330#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005331#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005332 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005333#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005334#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005335 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005336#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005337#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005338 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005339#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005340#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005341 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005342#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005343#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005344 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005345#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005346#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005347 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005348#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005349#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005350 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005351#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005352 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5353 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5354 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5355 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5356 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5357 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5358 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5359 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5360 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005361 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005362#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005363 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005364#endif
5365#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005366 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005367#endif
5368#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005369 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005370#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005371#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005372 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005373#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005374#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005375 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005376#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005377#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005378 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005379#endif
5380#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005381 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005382#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005383#ifdef HAVE_SYS_WAIT_H
5384#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005385 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005386#endif /* WIFSTOPPED */
5387#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005388 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005389#endif /* WIFSIGNALED */
5390#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005391 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005392#endif /* WIFEXITED */
5393#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005394 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005395#endif /* WEXITSTATUS */
5396#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005397 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005398#endif /* WTERMSIG */
5399#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005400 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005401#endif /* WSTOPSIG */
5402#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005403#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005404 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005405#endif
5406#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005407 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005408#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005409#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005410 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5411#endif
5412#ifdef HAVE_TEMPNAM
5413 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5414#endif
5415#ifdef HAVE_TMPNAM
5416 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5417#endif
Fred Drakec9680921999-12-13 16:37:25 +00005418#ifdef HAVE_CONFSTR
5419 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5420#endif
5421#ifdef HAVE_SYSCONF
5422 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5423#endif
5424#ifdef HAVE_FPATHCONF
5425 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5426#endif
5427#ifdef HAVE_PATHCONF
5428 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5429#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005430 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005431 {NULL, NULL} /* Sentinel */
5432};
5433
5434
Barry Warsaw4a342091996-12-19 23:50:02 +00005435static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005436ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005437{
5438 PyObject* v = PyInt_FromLong(value);
5439 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5440 return -1; /* triggers fatal error */
5441
5442 Py_DECREF(v);
5443 return 0;
5444}
5445
Guido van Rossumd48f2521997-12-05 22:19:34 +00005446#if defined(PYOS_OS2)
5447/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5448static int insertvalues(PyObject *d)
5449{
5450 APIRET rc;
5451 ULONG values[QSV_MAX+1];
5452 PyObject *v;
5453 char *ver, tmp[10];
5454
5455 Py_BEGIN_ALLOW_THREADS
5456 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5457 Py_END_ALLOW_THREADS
5458
5459 if (rc != NO_ERROR) {
5460 os2_error(rc);
5461 return -1;
5462 }
5463
5464 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5465 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5466 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5467 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5468 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5469 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5470 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5471
5472 switch (values[QSV_VERSION_MINOR]) {
5473 case 0: ver = "2.00"; break;
5474 case 10: ver = "2.10"; break;
5475 case 11: ver = "2.11"; break;
5476 case 30: ver = "3.00"; break;
5477 case 40: ver = "4.00"; break;
5478 case 50: ver = "5.00"; break;
5479 default:
5480 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5481 values[QSV_VERSION_MINOR]);
5482 ver = &tmp[0];
5483 }
5484
5485 /* Add Indicator of the Version of the Operating System */
5486 v = PyString_FromString(ver);
5487 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5488 return -1;
5489 Py_DECREF(v);
5490
5491 /* Add Indicator of Which Drive was Used to Boot the System */
5492 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5493 tmp[1] = ':';
5494 tmp[2] = '\0';
5495
5496 v = PyString_FromString(tmp);
5497 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5498 return -1;
5499 Py_DECREF(v);
5500
5501 return 0;
5502}
5503#endif
5504
Barry Warsaw4a342091996-12-19 23:50:02 +00005505static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005506all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005507{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005508#ifdef F_OK
5509 if (ins(d, "F_OK", (long)F_OK)) return -1;
5510#endif
5511#ifdef R_OK
5512 if (ins(d, "R_OK", (long)R_OK)) return -1;
5513#endif
5514#ifdef W_OK
5515 if (ins(d, "W_OK", (long)W_OK)) return -1;
5516#endif
5517#ifdef X_OK
5518 if (ins(d, "X_OK", (long)X_OK)) return -1;
5519#endif
Fred Drakec9680921999-12-13 16:37:25 +00005520#ifdef NGROUPS_MAX
5521 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5522#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005523#ifdef TMP_MAX
5524 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5525#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005526#ifdef WNOHANG
5527 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5528#endif
5529#ifdef O_RDONLY
5530 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5531#endif
5532#ifdef O_WRONLY
5533 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5534#endif
5535#ifdef O_RDWR
5536 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5537#endif
5538#ifdef O_NDELAY
5539 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5540#endif
5541#ifdef O_NONBLOCK
5542 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5543#endif
5544#ifdef O_APPEND
5545 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5546#endif
5547#ifdef O_DSYNC
5548 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5549#endif
5550#ifdef O_RSYNC
5551 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5552#endif
5553#ifdef O_SYNC
5554 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5555#endif
5556#ifdef O_NOCTTY
5557 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5558#endif
5559#ifdef O_CREAT
5560 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5561#endif
5562#ifdef O_EXCL
5563 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5564#endif
5565#ifdef O_TRUNC
5566 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5567#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005568#ifdef O_BINARY
5569 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5570#endif
5571#ifdef O_TEXT
5572 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5573#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005574
Guido van Rossum246bc171999-02-01 23:54:31 +00005575#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005576 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5577 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5578 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5579 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5580 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005581#endif
5582
Guido van Rossumd48f2521997-12-05 22:19:34 +00005583#if defined(PYOS_OS2)
5584 if (insertvalues(d)) return -1;
5585#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005586 return 0;
5587}
5588
5589
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005590#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005591#define INITFUNC initnt
5592#define MODNAME "nt"
5593#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005594#if defined(PYOS_OS2)
5595#define INITFUNC initos2
5596#define MODNAME "os2"
5597#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005598#define INITFUNC initposix
5599#define MODNAME "posix"
5600#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005601#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005602
Guido van Rossum3886bb61998-12-04 18:50:17 +00005603DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005604INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005605{
Barry Warsaw53699e91996-12-10 23:23:01 +00005606 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005607
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005608 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005609 posix_methods,
5610 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005611 (PyObject *)NULL,
5612 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005613 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005614
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005615 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005616 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005617 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005618 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005619 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005620
Barry Warsaw4a342091996-12-19 23:50:02 +00005621 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005622 return;
5623
Fred Drakebec628d1999-12-15 18:31:10 +00005624 if (setup_confname_tables(d))
5625 return;
5626
Barry Warsawca74da41999-02-09 19:31:45 +00005627 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005628
Guido van Rossumb3d39562000-01-31 18:41:26 +00005629#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005630 if (posix_putenv_garbage == NULL)
5631 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005632#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005633}