blob: fef4bbb2c34b18befd8c7fcb3b670357a2c72935 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011/* POSIX module implementation */
12
Guido van Rossuma4916fa1996-05-23 22:58:55 +000013/* This file is also used for Windows NT and MS-Win. In that case the module
Guido van Rossumad0ee831995-03-01 10:34:45 +000014 actually calls itself 'nt', not 'posix', and a few functions are
15 either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +000016 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +000017 of the compiler used. Different compilers define their own feature
Guido van Rossuma4916fa1996-05-23 22:58:55 +000018 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000019
Guido van Rossuma4916fa1996-05-23 22:58:55 +000020/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000022static char posix__doc__ [] =
23"This module provides access to operating system functionality that is\n\
24standardized by the C Standard and the POSIX standard (a thinly\n\
25disguised Unix interface). Refer to the library manual and\n\
26corresponding Unix manual entries for more information on calls.";
27
Barry Warsaw53699e91996-12-10 23:23:01 +000028#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000029
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000030#if defined(PYOS_OS2)
31#define INCL_DOS
32#define INCL_DOSERRORS
33#define INCL_DOSPROCESS
34#define INCL_NOPMAPI
35#include <os2.h>
36#endif
37
Guido van Rossumb6775db1994-08-01 11:34:53 +000038#include <sys/types.h>
39#include <sys/stat.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +000040#ifdef HAVE_SYS_WAIT_H
41#include <sys/wait.h> /* For WNOHANG */
42#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000043
Guido van Rossuma376cc51996-12-05 23:43:35 +000044#ifdef HAVE_SIGNAL_H
45#include <signal.h>
46#endif
47
Guido van Rossumb6775db1994-08-01 11:34:53 +000048#include "mytime.h" /* For clock_t on some systems */
49
50#ifdef HAVE_FCNTL_H
51#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000052#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000053
Guido van Rossuma4916fa1996-05-23 22:58:55 +000054/* Various compilers have only certain posix functions */
Guido van Rossum6d8841c1997-08-14 19:57:39 +000055/* XXX Gosh I wish these were all moved into config.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000056#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000057#include <process.h>
58#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000059#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000060#define HAVE_GETCWD 1
61#define HAVE_OPENDIR 1
62#define HAVE_SYSTEM 1
63#if defined(__OS2__)
64#define HAVE_EXECV 1
65#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000066#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000067#include <process.h>
68#else
69#ifdef __BORLANDC__ /* Borland compiler */
70#define HAVE_EXECV 1
71#define HAVE_GETCWD 1
72#define HAVE_GETEGID 1
73#define HAVE_GETEUID 1
74#define HAVE_GETGID 1
75#define HAVE_GETPPID 1
76#define HAVE_GETUID 1
77#define HAVE_KILL 1
78#define HAVE_OPENDIR 1
79#define HAVE_PIPE 1
80#define HAVE_POPEN 1
81#define HAVE_SYSTEM 1
82#define HAVE_WAIT 1
83#else
84#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000085#define HAVE_GETCWD 1
86#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000087#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000088#define HAVE_EXECV 1
89#define HAVE_PIPE 1
90#define HAVE_POPEN 1
91#define HAVE_SYSTEM 1
92#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000093#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000094#else /* all other compilers */
95/* Unix functions that the configure script doesn't check for */
96#define HAVE_EXECV 1
97#define HAVE_FORK 1
98#define HAVE_GETCWD 1
99#define HAVE_GETEGID 1
100#define HAVE_GETEUID 1
101#define HAVE_GETGID 1
102#define HAVE_GETPPID 1
103#define HAVE_GETUID 1
104#define HAVE_KILL 1
105#define HAVE_OPENDIR 1
106#define HAVE_PIPE 1
107#define HAVE_POPEN 1
108#define HAVE_SYSTEM 1
109#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000110#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000111#endif /* _MSC_VER */
112#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000113#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000114#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000115
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000116#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000117
Guido van Rossumb6775db1994-08-01 11:34:53 +0000118#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000119#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000120#endif
121
122#ifdef NeXT
123/* NeXT's <unistd.h> and <utime.h> aren't worth much */
124#undef HAVE_UNISTD_H
125#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000126#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000127/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000128#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000129#endif
130
131#ifdef HAVE_UNISTD_H
Guido van Rossumad0ee831995-03-01 10:34:45 +0000132/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +0000133extern int rename(const char *, const char *);
134extern int pclose(FILE *);
135extern int lstat(const char *, struct stat *);
136extern int symlink(const char *, const char *);
137extern int fsync(int fd);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000138#else /* !HAVE_UNISTD_H */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(char *);
150extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chdir(const char *);
153extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int chmod(const char *, mode_t);
156extern int chown(const char *, uid_t, gid_t);
157extern char *getcwd(char *, int);
158extern char *strerror(int);
159extern int link(const char *, const char *);
160extern int rename(const char *, const char *);
161extern int stat(const char *, struct stat *);
162extern int unlink(const char *);
163extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000164#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000165extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000166#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000167#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000168extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000169#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000170#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000171
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#ifdef HAVE_UTIME_H
175#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000176#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000178#ifdef HAVE_SYS_UTIME_H
179#include <sys/utime.h>
180#define HAVE_UTIME_H /* pretend we do for the rest of this file */
181#endif /* HAVE_SYS_UTIME_H */
182
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#ifdef HAVE_SYS_TIMES_H
184#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000185#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186
187#ifdef HAVE_SYS_PARAM_H
188#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
191#ifdef HAVE_SYS_UTSNAME_H
192#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000193#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194
195#ifndef MAXPATHLEN
196#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#define NAMLEN(dirent) strlen((dirent)->d_name)
202#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#include <direct.h>
205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000218#endif
219#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <direct.h>
223#include <io.h>
224#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000225#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000227#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000229#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000230#else /* 16-bit Windows */
231#include <dos.h>
232#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000233#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235
Guido van Rossumd48f2521997-12-05 22:19:34 +0000236#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000239
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000240#ifdef UNION_WAIT
241/* Emulate some macros on systems that have a union instead of macros */
242
243#ifndef WIFEXITED
244#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
245#endif
246
247#ifndef WEXITSTATUS
248#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
249#endif
250
251#ifndef WTERMSIG
252#define WTERMSIG(u_wait) ((u_wait).w_termsig)
253#endif
254
255#endif /* UNION_WAIT */
256
Greg Wardb48bc172000-03-01 21:51:56 +0000257/* Don't use the "_r" form if we don't need it (also, won't have a
258 prototype for it, at least on Solaris -- maybe others as well?). */
259#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
260#define USE_CTERMID_R
261#endif
262
263#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
264#define USE_TMPNAM_R
265#endif
266
Fred Drake699f3522000-06-29 21:12:41 +0000267/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000268#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000269#ifdef MS_WIN64
270# define STAT _stati64
271# define FSTAT _fstati64
272# define STRUCT_STAT struct _stati64
273#else
274# define STAT stat
275# define FSTAT fstat
276# define STRUCT_STAT struct stat
277#endif
278
279
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280/* Return a dictionary corresponding to the POSIX environment table */
281
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000282#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000284#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285
Barry Warsaw53699e91996-12-10 23:23:01 +0000286static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000287convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288{
Barry Warsaw53699e91996-12-10 23:23:01 +0000289 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000291 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 if (d == NULL)
293 return NULL;
294 if (environ == NULL)
295 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000296 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000298 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000299 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300 char *p = strchr(*e, '=');
301 if (p == NULL)
302 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000303 k = PyString_FromStringAndSize(*e, (int)(p-*e));
304 if (k == NULL) {
305 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000307 }
308 v = PyString_FromString(p+1);
309 if (v == NULL) {
310 PyErr_Clear();
311 Py_DECREF(k);
312 continue;
313 }
314 if (PyDict_GetItem(d, k) == NULL) {
315 if (PyDict_SetItem(d, k, v) != 0)
316 PyErr_Clear();
317 }
318 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000319 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000320 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000321#if defined(PYOS_OS2)
322 {
323 APIRET rc;
324 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
325
326 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000327 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000328 PyObject *v = PyString_FromString(buffer);
329 PyDict_SetItemString(d, "BEGINLIBPATH", v);
330 Py_DECREF(v);
331 }
332 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
333 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
334 PyObject *v = PyString_FromString(buffer);
335 PyDict_SetItemString(d, "ENDLIBPATH", v);
336 Py_DECREF(v);
337 }
338 }
339#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000340 return d;
341}
342
343
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000344/* Set a POSIX-specific error from errno, and return NULL */
345
Barry Warsawd58d7641998-07-23 16:14:40 +0000346static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000347posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000348{
Barry Warsawca74da41999-02-09 19:31:45 +0000349 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000350}
Barry Warsawd58d7641998-07-23 16:14:40 +0000351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000352posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000353{
Barry Warsawca74da41999-02-09 19:31:45 +0000354 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000355}
356
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000357#ifdef MS_WIN32
358static PyObject *
359win32_error(char* function, char* filename)
360{
361 /* XXX this could be improved */
362 errno = GetLastError();
363 if (filename)
364 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
365 else
366 return PyErr_SetFromErrno(PyExc_OSError);
367}
368#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369
Guido van Rossumd48f2521997-12-05 22:19:34 +0000370#if defined(PYOS_OS2)
371/**********************************************************************
372 * Helper Function to Trim and Format OS/2 Messages
373 **********************************************************************/
374 static void
375os2_formatmsg(char *msgbuf, int msglen, char *reason)
376{
377 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
378
379 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
380 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
381
382 while (lastc > msgbuf && isspace(*lastc))
383 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
384 }
385
386 /* Add Optional Reason Text */
387 if (reason) {
388 strcat(msgbuf, " : ");
389 strcat(msgbuf, reason);
390 }
391}
392
393/**********************************************************************
394 * Decode an OS/2 Operating System Error Code
395 *
396 * A convenience function to lookup an OS/2 error code and return a
397 * text message we can use to raise a Python exception.
398 *
399 * Notes:
400 * The messages for errors returned from the OS/2 kernel reside in
401 * the file OSO001.MSG in the \OS2 directory hierarchy.
402 *
403 **********************************************************************/
404 static char *
405os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
406{
407 APIRET rc;
408 ULONG msglen;
409
410 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
411 Py_BEGIN_ALLOW_THREADS
412 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
413 errorcode, "oso001.msg", &msglen);
414 Py_END_ALLOW_THREADS
415
416 if (rc == NO_ERROR)
417 os2_formatmsg(msgbuf, msglen, reason);
418 else
419 sprintf(msgbuf, "unknown OS error #%d", errorcode);
420
421 return msgbuf;
422}
423
424/* Set an OS/2-specific error and return NULL. OS/2 kernel
425 errors are not in a global variable e.g. 'errno' nor are
426 they congruent with posix error numbers. */
427
428static PyObject * os2_error(int code)
429{
430 char text[1024];
431 PyObject *v;
432
433 os2_strerror(text, sizeof(text), code, "");
434
435 v = Py_BuildValue("(is)", code, text);
436 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000437 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000438 Py_DECREF(v);
439 }
440 return NULL; /* Signal to Python that an Exception is Pending */
441}
442
443#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444
445/* POSIX generic methods */
446
Barry Warsaw53699e91996-12-10 23:23:01 +0000447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000448posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000449{
450 int fd;
451 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000452 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000453 return NULL;
454 Py_BEGIN_ALLOW_THREADS
455 res = (*func)(fd);
456 Py_END_ALLOW_THREADS
457 if (res < 0)
458 return posix_error();
459 Py_INCREF(Py_None);
460 return Py_None;
461}
462
463
464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000465posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000466{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000467 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000468 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000469 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000470 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000471 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000472 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000473 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000474 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000475 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000476 Py_INCREF(Py_None);
477 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000478}
479
Barry Warsaw53699e91996-12-10 23:23:01 +0000480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000481posix_2str(PyObject *args, char *format,
482 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000484 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000486 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000488 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000489 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000490 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000491 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000492 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000493 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000494 Py_INCREF(Py_None);
495 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000496}
497
Fred Drake699f3522000-06-29 21:12:41 +0000498/* pack a system stat C structure into the Python stat tuple
499 (used by posix_stat() and posix_fstat()) */
500static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000501_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000502{
503 PyObject *v = PyTuple_New(10);
504 if (v == NULL)
505 return NULL;
506
507 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
508#ifdef HAVE_LARGEFILE_SUPPORT
509 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
510#else
511 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
512#endif
513#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
514 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
515#else
516 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
517#endif
518 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
519 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
520 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
521#ifdef HAVE_LARGEFILE_SUPPORT
522 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
523#else
524 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
525#endif
526#if SIZEOF_TIME_T > SIZEOF_LONG
527 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
528 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
529 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
530#else
531 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
532 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
533 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
534#endif
535
536 if (PyErr_Occurred()) {
537 Py_DECREF(v);
538 return NULL;
539 }
540
541 return v;
542}
543
544
Barry Warsaw53699e91996-12-10 23:23:01 +0000545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000546posix_do_stat(PyObject *self, PyObject *args, char *format,
547 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000548{
Fred Drake699f3522000-06-29 21:12:41 +0000549 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000550 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000551 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000552
553#ifdef MS_WIN32
554 int pathlen;
555 char pathcopy[MAX_PATH];
556#endif /* MS_WIN32 */
557
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000558 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000559 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000560
561#ifdef MS_WIN32
562 pathlen = strlen(path);
563 /* the library call can blow up if the file name is too long! */
564 if (pathlen > MAX_PATH) {
565 errno = ENAMETOOLONG;
566 return posix_error();
567 }
568
569 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000570 /* exception for specific or current drive root */
571 if (!((pathlen == 1) ||
572 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000573 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000574 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000575 {
576 strncpy(pathcopy, path, pathlen);
577 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
578 path = pathcopy;
579 }
580 }
581#endif /* MS_WIN32 */
582
Barry Warsaw53699e91996-12-10 23:23:01 +0000583 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000584 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000585 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000586 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000587 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000588
589 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000590}
591
592
593/* POSIX methods */
594
Guido van Rossum94f6f721999-01-06 18:42:14 +0000595static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000596"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000597Test for access to a file.";
598
599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000600posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000601{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000602 char *path;
603 int mode;
604 int res;
605
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000606 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000607 return NULL;
608 Py_BEGIN_ALLOW_THREADS
609 res = access(path, mode);
610 Py_END_ALLOW_THREADS
611 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000612}
613
Guido van Rossumd371ff11999-01-25 16:12:23 +0000614#ifndef F_OK
615#define F_OK 0
616#endif
617#ifndef R_OK
618#define R_OK 4
619#endif
620#ifndef W_OK
621#define W_OK 2
622#endif
623#ifndef X_OK
624#define X_OK 1
625#endif
626
627#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000628static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000629"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000630Return the name of the terminal device connected to 'fd'.";
631
632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000633posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000634{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000635 int id;
636 char *ret;
637
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000638 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000639 return NULL;
640
Guido van Rossum94f6f721999-01-06 18:42:14 +0000641 ret = ttyname(id);
642 if (ret == NULL)
643 return(posix_error());
644 return(PyString_FromString(ret));
645}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000646#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000647
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000648#ifdef HAVE_CTERMID
649static char posix_ctermid__doc__[] =
650"ctermid() -> String\n\
651Return the name of the controlling terminal for this process.";
652
653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000654posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000655{
656 char *ret;
657 char buffer[L_ctermid];
658
659 if (!PyArg_ParseTuple(args, ":ctermid"))
660 return NULL;
661
Greg Wardb48bc172000-03-01 21:51:56 +0000662#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000663 ret = ctermid_r(buffer);
664#else
665 ret = ctermid(buffer);
666#endif
667 if (ret == NULL)
668 return(posix_error());
669 return(PyString_FromString(buffer));
670}
671#endif
672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000673static char posix_chdir__doc__[] =
674"chdir(path) -> None\n\
675Change the current working directory to the specified path.";
676
Barry Warsaw53699e91996-12-10 23:23:01 +0000677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000678posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000679{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000680 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681}
682
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000683
684static char posix_chmod__doc__[] =
685"chmod(path, mode) -> None\n\
686Change the access permissions of a file.";
687
Barry Warsaw53699e91996-12-10 23:23:01 +0000688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000689posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000690{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000691 char *path;
692 int i;
693 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000694 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000695 return NULL;
696 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000697 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000698 Py_END_ALLOW_THREADS
699 if (res < 0)
700 return posix_error_with_filename(path);
701 Py_INCREF(Py_None);
702 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000703}
704
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000705
Guido van Rossum21142a01999-01-08 21:05:37 +0000706#ifdef HAVE_FSYNC
707static char posix_fsync__doc__[] =
708"fsync(fildes) -> None\n\
709force write of file with filedescriptor to disk.";
710
711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000712posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000713{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000714 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000715}
716#endif /* HAVE_FSYNC */
717
718#ifdef HAVE_FDATASYNC
719static char posix_fdatasync__doc__[] =
720"fdatasync(fildes) -> None\n\
721force write of file with filedescriptor to disk.\n\
722 does not force update of metadata.";
723
Guido van Rossum5d00b6d1999-01-08 21:28:05 +0000724extern int fdatasync(int); /* Prototype just in case */
725
Guido van Rossum21142a01999-01-08 21:05:37 +0000726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000727posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000728{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000729 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000730}
731#endif /* HAVE_FDATASYNC */
732
733
Fredrik Lundh10723342000-07-10 16:38:09 +0000734#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000735static char posix_chown__doc__[] =
736"chown(path, uid, gid) -> None\n\
737Change the owner and group id of path to the numeric uid and gid.";
738
Barry Warsaw53699e91996-12-10 23:23:01 +0000739static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000740posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000741{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000742 char *path;
743 int uid, gid;
744 int res;
745 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
746 return NULL;
747 Py_BEGIN_ALLOW_THREADS
748 res = chown(path, (uid_t) uid, (gid_t) gid);
749 Py_END_ALLOW_THREADS
750 if (res < 0)
751 return posix_error_with_filename(path);
752 Py_INCREF(Py_None);
753 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000754}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000755#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000756
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000757
Guido van Rossum36bc6801995-06-14 22:54:23 +0000758#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000759static char posix_getcwd__doc__[] =
760"getcwd() -> path\n\
761Return a string representing the current working directory.";
762
Barry Warsaw53699e91996-12-10 23:23:01 +0000763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000764posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765{
766 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000767 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000768 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000769 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000770 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000771 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000772 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000773 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000774 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000775 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000777#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000778
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000779
Guido van Rossumb6775db1994-08-01 11:34:53 +0000780#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000781static char posix_link__doc__[] =
782"link(src, dst) -> None\n\
783Create a hard link to a file.";
784
Barry Warsaw53699e91996-12-10 23:23:01 +0000785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000786posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000788 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000789}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000790#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000791
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000792
793static char posix_listdir__doc__[] =
794"listdir(path) -> list_of_strings\n\
795Return a list containing the names of the entries in the directory.\n\
796\n\
797 path: path of directory to list\n\
798\n\
799The list is in arbitrary order. It does not include the special\n\
800entries '.' and '..' even if they are present in the directory.";
801
Barry Warsaw53699e91996-12-10 23:23:01 +0000802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000803posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000804{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000805 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000806 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000807#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000808
Guido van Rossumb6775db1994-08-01 11:34:53 +0000809 char *name;
810 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000811 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000812 HANDLE hFindFile;
813 WIN32_FIND_DATA FileData;
814 char namebuf[MAX_PATH+5];
815
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000816 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000817 return NULL;
818 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000819 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000820 return NULL;
821 }
822 strcpy(namebuf, name);
823 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
824 namebuf[len++] = '/';
825 strcpy(namebuf + len, "*.*");
826
Barry Warsaw53699e91996-12-10 23:23:01 +0000827 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000828 return NULL;
829
830 hFindFile = FindFirstFile(namebuf, &FileData);
831 if (hFindFile == INVALID_HANDLE_VALUE) {
832 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000833 if (errno == ERROR_FILE_NOT_FOUND)
834 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000835 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000836 }
837 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000838 if (FileData.cFileName[0] == '.' &&
839 (FileData.cFileName[1] == '\0' ||
840 FileData.cFileName[1] == '.' &&
841 FileData.cFileName[2] == '\0'))
842 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000843 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000844 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000845 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000846 d = NULL;
847 break;
848 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000849 if (PyList_Append(d, v) != 0) {
850 Py_DECREF(v);
851 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 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000856 } while (FindNextFile(hFindFile, &FileData) == TRUE);
857
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000858 if (FindClose(hFindFile) == FALSE)
859 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000860
861 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000862
Guido van Rossum8d665e61996-06-26 18:22:49 +0000863#else /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000864#ifdef _MSC_VER /* 16-bit Windows */
865
866#ifndef MAX_PATH
867#define MAX_PATH 250
868#endif
869 char *name, *pt;
870 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000871 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000872 char namebuf[MAX_PATH+5];
873 struct _find_t ep;
874
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000875 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000876 return NULL;
877 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000878 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000879 return NULL;
880 }
881 strcpy(namebuf, name);
882 for (pt = namebuf; *pt; pt++)
883 if (*pt == '/')
884 *pt = '\\';
885 if (namebuf[len-1] != '\\')
886 namebuf[len++] = '\\';
887 strcpy(namebuf + len, "*.*");
888
Barry Warsaw53699e91996-12-10 23:23:01 +0000889 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000890 return NULL;
891
892 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000893 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
894 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000895 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000896 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000897 }
898 do {
899 if (ep.name[0] == '.' &&
900 (ep.name[1] == '\0' ||
901 ep.name[1] == '.' &&
902 ep.name[2] == '\0'))
903 continue;
904 strcpy(namebuf, ep.name);
905 for (pt = namebuf; *pt; pt++)
906 if (isupper(*pt))
907 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000908 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000909 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000910 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000911 d = NULL;
912 break;
913 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000914 if (PyList_Append(d, v) != 0) {
915 Py_DECREF(v);
916 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000917 d = NULL;
918 break;
919 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000920 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000921 } while (_dos_findnext(&ep) == 0);
922
923 return d;
924
925#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000926#if defined(PYOS_OS2)
927
928#ifndef MAX_PATH
929#define MAX_PATH CCHMAXPATH
930#endif
931 char *name, *pt;
932 int len;
933 PyObject *d, *v;
934 char namebuf[MAX_PATH+5];
935 HDIR hdir = 1;
936 ULONG srchcnt = 1;
937 FILEFINDBUF3 ep;
938 APIRET rc;
939
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000940 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000941 return NULL;
942 if (len >= MAX_PATH) {
943 PyErr_SetString(PyExc_ValueError, "path too long");
944 return NULL;
945 }
946 strcpy(namebuf, name);
947 for (pt = namebuf; *pt; pt++)
948 if (*pt == '/')
949 *pt = '\\';
950 if (namebuf[len-1] != '\\')
951 namebuf[len++] = '\\';
952 strcpy(namebuf + len, "*.*");
953
954 if ((d = PyList_New(0)) == NULL)
955 return NULL;
956
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000957 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
958 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000959 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000960 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
961 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
962 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963
964 if (rc != NO_ERROR) {
965 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000966 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000967 }
968
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000969 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000970 do {
971 if (ep.achName[0] == '.'
972 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000973 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000974
975 strcpy(namebuf, ep.achName);
976
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000977 /* Leave Case of Name Alone -- In Native Form */
978 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000979
980 v = PyString_FromString(namebuf);
981 if (v == NULL) {
982 Py_DECREF(d);
983 d = NULL;
984 break;
985 }
986 if (PyList_Append(d, v) != 0) {
987 Py_DECREF(v);
988 Py_DECREF(d);
989 d = NULL;
990 break;
991 }
992 Py_DECREF(v);
993 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
994 }
995
996 return d;
997#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000998
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000999 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001000 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001001 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001002 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001003 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001004 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001005 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001006 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001007 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001008 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001009 closedir(dirp);
1010 return NULL;
1011 }
1012 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001013 if (ep->d_name[0] == '.' &&
1014 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001015 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001016 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001017 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001018 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001019 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001020 d = NULL;
1021 break;
1022 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001023 if (PyList_Append(d, v) != 0) {
1024 Py_DECREF(v);
1025 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001026 d = NULL;
1027 break;
1028 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001029 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001030 }
1031 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001032
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001033 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001034
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001035#endif /* !PYOS_OS2 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001036#endif /* !_MSC_VER */
Guido van Rossum8d665e61996-06-26 18:22:49 +00001037#endif /* !MS_WIN32 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001038}
1039
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001040static char posix_mkdir__doc__[] =
1041"mkdir(path [, mode=0777]) -> None\n\
1042Create a directory.";
1043
Barry Warsaw53699e91996-12-10 23:23:01 +00001044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001045posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001046{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001047 int res;
1048 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001049 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001050 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001051 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001052 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001053#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001054 res = mkdir(path);
1055#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001056 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001057#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001058 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001059 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001060 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001061 Py_INCREF(Py_None);
1062 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001063}
1064
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001065
Guido van Rossumb6775db1994-08-01 11:34:53 +00001066#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001067static char posix_nice__doc__[] =
1068"nice(inc) -> new_priority\n\
1069Decrease the priority of process and return new priority.";
1070
Barry Warsaw53699e91996-12-10 23:23:01 +00001071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001072posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001073{
1074 int increment, value;
1075
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001076 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001077 return NULL;
1078 value = nice(increment);
1079 if (value == -1)
1080 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001081 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001082}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001083#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001085
1086static char posix_rename__doc__[] =
1087"rename(old, new) -> None\n\
1088Rename a file or directory.";
1089
Barry Warsaw53699e91996-12-10 23:23:01 +00001090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001091posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001092{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001093 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001094}
1095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001096
1097static char posix_rmdir__doc__[] =
1098"rmdir(path) -> None\n\
1099Remove a directory.";
1100
Barry Warsaw53699e91996-12-10 23:23:01 +00001101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001102posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001103{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001104 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001105}
1106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001107
1108static char posix_stat__doc__[] =
1109"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1110Perform a stat system call on the given path.";
1111
Barry Warsaw53699e91996-12-10 23:23:01 +00001112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001113posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001114{
Fred Drake699f3522000-06-29 21:12:41 +00001115 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001116}
1117
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001118
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001119#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001120static char posix_system__doc__[] =
1121"system(command) -> exit_status\n\
1122Execute the command (a string) in a subshell.";
1123
Barry Warsaw53699e91996-12-10 23:23:01 +00001124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001125posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001126{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001127 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001128 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001129 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001131 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001132 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001133 Py_END_ALLOW_THREADS
1134 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001135}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001136#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001138
1139static char posix_umask__doc__[] =
1140"umask(new_mask) -> old_mask\n\
1141Set the current numeric umask and return the previous umask.";
1142
Barry Warsaw53699e91996-12-10 23:23:01 +00001143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001144posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001145{
1146 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001147 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001148 return NULL;
1149 i = umask(i);
1150 if (i < 0)
1151 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001152 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153}
1154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001155
1156static char posix_unlink__doc__[] =
1157"unlink(path) -> None\n\
1158Remove a file (same as remove(path)).";
1159
1160static char posix_remove__doc__[] =
1161"remove(path) -> None\n\
1162Remove a file (same as unlink(path)).";
1163
Barry Warsaw53699e91996-12-10 23:23:01 +00001164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001165posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001166{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001167 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001168}
1169
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001170
Guido van Rossumb6775db1994-08-01 11:34:53 +00001171#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001172static char posix_uname__doc__[] =
1173"uname() -> (sysname, nodename, release, version, machine)\n\
1174Return a tuple identifying the current operating system.";
1175
Barry Warsaw53699e91996-12-10 23:23:01 +00001176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001177posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001178{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001179 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001180 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001181 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001182 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001183 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001184 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001185 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001186 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001187 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001188 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001189 u.sysname,
1190 u.nodename,
1191 u.release,
1192 u.version,
1193 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001194}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001195#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001196
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001197
1198static char posix_utime__doc__[] =
1199"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001200utime(path, None) -> None\n\
1201Set the access and modified time of the file to the given values. If the\n\
1202second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001203
Barry Warsaw53699e91996-12-10 23:23:01 +00001204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001205posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001206{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001207 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001208 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001209 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001210 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001211
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001212/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001213#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001214 struct utimbuf buf;
1215#define ATIME buf.actime
1216#define MTIME buf.modtime
1217#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001218#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001219 time_t buf[2];
1220#define ATIME buf[0]
1221#define MTIME buf[1]
1222#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001223#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001224
Barry Warsaw3cef8562000-05-01 16:17:24 +00001225 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001227 if (arg == Py_None) {
1228 /* optional time values not given */
1229 Py_BEGIN_ALLOW_THREADS
1230 res = utime(path, NULL);
1231 Py_END_ALLOW_THREADS
1232 }
1233 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1234 PyErr_SetString(PyExc_TypeError,
1235 "Second argument must be a 2-tuple of numbers.");
1236 return NULL;
1237 }
1238 else {
1239 ATIME = atime;
1240 MTIME = mtime;
1241 Py_BEGIN_ALLOW_THREADS
1242 res = utime(path, UTIME_ARG);
1243 Py_END_ALLOW_THREADS
1244 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001245 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001246 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001247 Py_INCREF(Py_None);
1248 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001249#undef UTIME_ARG
1250#undef ATIME
1251#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001252}
1253
Guido van Rossum85e3b011991-06-03 12:42:10 +00001254
Guido van Rossum3b066191991-06-04 19:40:25 +00001255/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001256
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001257static char posix__exit__doc__[] =
1258"_exit(status)\n\
1259Exit to the system with specified status, without normal exit processing.";
1260
Barry Warsaw53699e91996-12-10 23:23:01 +00001261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001262posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001263{
1264 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001265 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001266 return NULL;
1267 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001268 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001269}
1270
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001271
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001272#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001273static char posix_execv__doc__[] =
1274"execv(path, args)\n\
1275Execute an executable path with arguments, replacing current process.\n\
1276\n\
1277 path: path of executable file\n\
1278 args: tuple or list of strings";
1279
Barry Warsaw53699e91996-12-10 23:23:01 +00001280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001281posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001282{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001283 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001284 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001285 char **argvlist;
1286 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001287 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001288
Guido van Rossum89b33251993-10-22 14:26:06 +00001289 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001290 argv is a list or tuple of strings. */
1291
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001292 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001293 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001294 if (PyList_Check(argv)) {
1295 argc = PyList_Size(argv);
1296 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001297 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001298 else if (PyTuple_Check(argv)) {
1299 argc = PyTuple_Size(argv);
1300 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001301 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001302 else {
Guido van Rossum50422b42000-04-26 20:34:28 +00001303 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1304 return NULL;
1305 }
1306
1307 if (argc == 0) {
1308 PyErr_SetString(PyExc_ValueError, "empty argument list");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001309 return NULL;
1310 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001311
Barry Warsaw53699e91996-12-10 23:23:01 +00001312 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001313 if (argvlist == NULL)
1314 return NULL;
1315 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001316 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1317 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001318 PyErr_SetString(PyExc_TypeError,
1319 "all arguments must be strings");
1320 return NULL;
1321
Guido van Rossum85e3b011991-06-03 12:42:10 +00001322 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001323 }
1324 argvlist[argc] = NULL;
1325
Guido van Rossumb6775db1994-08-01 11:34:53 +00001326#ifdef BAD_EXEC_PROTOTYPES
1327 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001328#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001329 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001330#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001331
Guido van Rossum85e3b011991-06-03 12:42:10 +00001332 /* If we get here it's definitely an error */
1333
Barry Warsaw53699e91996-12-10 23:23:01 +00001334 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001335 return posix_error();
1336}
1337
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001338
1339static char posix_execve__doc__[] =
1340"execve(path, args, env)\n\
1341Execute a path with arguments and environment, replacing current process.\n\
1342\n\
1343 path: path of executable file\n\
1344 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001345 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001346
Barry Warsaw53699e91996-12-10 23:23:01 +00001347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001348posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001349{
1350 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001351 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001352 char **argvlist;
1353 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001354 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001355 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001356 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001357
1358 /* execve has three arguments: (path, argv, env), where
1359 argv is a list or tuple of strings and env is a dictionary
1360 like posix.environ. */
1361
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001362 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001363 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001364 if (PyList_Check(argv)) {
1365 argc = PyList_Size(argv);
1366 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001367 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001368 else if (PyTuple_Check(argv)) {
1369 argc = PyTuple_Size(argv);
1370 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001371 }
1372 else {
Barry Warsaw53699e91996-12-10 23:23:01 +00001373 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001374 return NULL;
1375 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001376 if (!PyMapping_Check(env)) {
1377 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001378 return NULL;
1379 }
1380
Guido van Rossum50422b42000-04-26 20:34:28 +00001381 if (argc == 0) {
1382 PyErr_SetString(PyExc_ValueError,
1383 "empty argument list");
1384 return NULL;
1385 }
1386
Barry Warsaw53699e91996-12-10 23:23:01 +00001387 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001388 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001389 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001390 return NULL;
1391 }
1392 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001393 if (!PyArg_Parse((*getitem)(argv, i),
Barry Warsaw43d68b81996-12-19 22:10:44 +00001394 "s;argv must be list of strings",
1395 &argvlist[i]))
1396 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001397 goto fail_1;
1398 }
1399 }
1400 argvlist[argc] = NULL;
1401
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001402 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001403 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001404 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001405 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001406 goto fail_1;
1407 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001408 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001409 keys = PyMapping_Keys(env);
1410 vals = PyMapping_Values(env);
1411 if (!keys || !vals)
1412 goto fail_2;
1413
1414 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001415 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001416
1417 key = PyList_GetItem(keys, pos);
1418 val = PyList_GetItem(vals, pos);
1419 if (!key || !val)
1420 goto fail_2;
1421
Barry Warsaw53699e91996-12-10 23:23:01 +00001422 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
Barry Warsaw43d68b81996-12-19 22:10:44 +00001423 !PyArg_Parse(val, "s;non-string value in env", &v))
1424 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001425 goto fail_2;
1426 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001427
1428#if defined(PYOS_OS2)
1429 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1430 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1431#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001432 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001433 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001434 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001435 goto fail_2;
1436 }
1437 sprintf(p, "%s=%s", k, v);
1438 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001439#if defined(PYOS_OS2)
1440 }
1441#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001442 }
1443 envlist[envc] = 0;
1444
Guido van Rossumb6775db1994-08-01 11:34:53 +00001445
1446#ifdef BAD_EXEC_PROTOTYPES
1447 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001448#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001449 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001450#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001451
1452 /* If we get here it's definitely an error */
1453
1454 (void) posix_error();
1455
1456 fail_2:
1457 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001458 PyMem_DEL(envlist[envc]);
1459 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001460 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001461 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001462 Py_XDECREF(vals);
1463 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001464 return NULL;
1465}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001466#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001468
Guido van Rossuma1065681999-01-25 23:20:23 +00001469#ifdef HAVE_SPAWNV
1470static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001471"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001472Execute an executable path with arguments, replacing current process.\n\
1473\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001474 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001475 path: path of executable file\n\
1476 args: tuple or list of strings";
1477
1478static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001479posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001480{
1481 char *path;
1482 PyObject *argv;
1483 char **argvlist;
1484 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001485 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001486 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001487
1488 /* spawnv has three arguments: (mode, path, argv), where
1489 argv is a list or tuple of strings. */
1490
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001491 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001492 return NULL;
1493 if (PyList_Check(argv)) {
1494 argc = PyList_Size(argv);
1495 getitem = PyList_GetItem;
1496 }
1497 else if (PyTuple_Check(argv)) {
1498 argc = PyTuple_Size(argv);
1499 getitem = PyTuple_GetItem;
1500 }
1501 else {
Fred Drake137507e2000-06-01 02:02:46 +00001502 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001503 return NULL;
1504 }
1505
1506 argvlist = PyMem_NEW(char *, argc+1);
1507 if (argvlist == NULL)
1508 return NULL;
1509 for (i = 0; i < argc; i++) {
1510 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1511 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001512 PyErr_SetString(PyExc_TypeError,
1513 "all arguments must be strings");
1514 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001515 }
1516 }
1517 argvlist[argc] = NULL;
1518
Guido van Rossum246bc171999-02-01 23:54:31 +00001519 if (mode == _OLD_P_OVERLAY)
1520 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001521 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001522
1523 PyMem_DEL(argvlist);
1524
Fred Drake699f3522000-06-29 21:12:41 +00001525 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001526 return posix_error();
1527 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001528#if SIZEOF_LONG == SIZEOF_VOID_P
1529 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001530#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001531 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001532#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001533}
1534
1535
1536static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001537"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001538Execute a path with arguments and environment, replacing current process.\n\
1539\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001540 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001541 path: path of executable file\n\
1542 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001543 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001544
1545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001546posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001547{
1548 char *path;
1549 PyObject *argv, *env;
1550 char **argvlist;
1551 char **envlist;
1552 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1553 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001554 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001555 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001556
1557 /* spawnve has four arguments: (mode, path, argv, env), where
1558 argv is a list or tuple of strings and env is a dictionary
1559 like posix.environ. */
1560
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001561 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001562 return NULL;
1563 if (PyList_Check(argv)) {
1564 argc = PyList_Size(argv);
1565 getitem = PyList_GetItem;
1566 }
1567 else if (PyTuple_Check(argv)) {
1568 argc = PyTuple_Size(argv);
1569 getitem = PyTuple_GetItem;
1570 }
1571 else {
1572 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1573 return NULL;
1574 }
1575 if (!PyMapping_Check(env)) {
1576 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1577 return NULL;
1578 }
1579
1580 argvlist = PyMem_NEW(char *, argc+1);
1581 if (argvlist == NULL) {
1582 PyErr_NoMemory();
1583 return NULL;
1584 }
1585 for (i = 0; i < argc; i++) {
1586 if (!PyArg_Parse((*getitem)(argv, i),
1587 "s;argv must be list of strings",
1588 &argvlist[i]))
1589 {
1590 goto fail_1;
1591 }
1592 }
1593 argvlist[argc] = NULL;
1594
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001595 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001596 envlist = PyMem_NEW(char *, i + 1);
1597 if (envlist == NULL) {
1598 PyErr_NoMemory();
1599 goto fail_1;
1600 }
1601 envc = 0;
1602 keys = PyMapping_Keys(env);
1603 vals = PyMapping_Values(env);
1604 if (!keys || !vals)
1605 goto fail_2;
1606
1607 for (pos = 0; pos < i; pos++) {
1608 char *p, *k, *v;
1609
1610 key = PyList_GetItem(keys, pos);
1611 val = PyList_GetItem(vals, pos);
1612 if (!key || !val)
1613 goto fail_2;
1614
1615 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1616 !PyArg_Parse(val, "s;non-string value in env", &v))
1617 {
1618 goto fail_2;
1619 }
1620 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1621 if (p == NULL) {
1622 PyErr_NoMemory();
1623 goto fail_2;
1624 }
1625 sprintf(p, "%s=%s", k, v);
1626 envlist[envc++] = p;
1627 }
1628 envlist[envc] = 0;
1629
Guido van Rossum246bc171999-02-01 23:54:31 +00001630 if (mode == _OLD_P_OVERLAY)
1631 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001632 spawnval = _spawnve(mode, path, argvlist, envlist);
1633 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001634 (void) posix_error();
1635 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001636#if SIZEOF_LONG == SIZEOF_VOID_P
1637 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001638#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001639 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001640#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001641
1642 fail_2:
1643 while (--envc >= 0)
1644 PyMem_DEL(envlist[envc]);
1645 PyMem_DEL(envlist);
1646 fail_1:
1647 PyMem_DEL(argvlist);
1648 Py_XDECREF(vals);
1649 Py_XDECREF(keys);
1650 return res;
1651}
1652#endif /* HAVE_SPAWNV */
1653
1654
Guido van Rossumad0ee831995-03-01 10:34:45 +00001655#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001656static char posix_fork__doc__[] =
1657"fork() -> pid\n\
1658Fork a child process.\n\
1659\n\
1660Return 0 to child process and PID of child to parent process.";
1661
Barry Warsaw53699e91996-12-10 23:23:01 +00001662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001663posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001664{
1665 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001666 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001667 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001668 pid = fork();
1669 if (pid == -1)
1670 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001671 if (pid == 0)
1672 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001673 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001674}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001675#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001676
Fred Drake8cef4cf2000-06-28 16:40:38 +00001677#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1678#ifdef HAVE_PTY_H
1679#include <pty.h>
1680#else
1681#ifdef HAVE_LIBUTIL_H
1682#include <libutil.h>
1683#else
1684/* BSDI does not supply a prototype for the 'openpty' and 'forkpty'
Thomas Wouters7e474022000-07-16 12:04:32 +00001685 functions, even though they are included in libutil. */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001686#include <termios.h>
1687extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
1688extern int forkpty(int *, char *, struct termios *, struct winsize *);
1689#endif /* HAVE_LIBUTIL_H */
1690#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001691#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001692
Thomas Wouters70c21a12000-07-14 14:28:33 +00001693#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001694static char posix_openpty__doc__[] =
1695"openpty() -> (master_fd, slave_fd)\n\
1696Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1697
1698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001699posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001700{
1701 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001702#ifndef HAVE_OPENPTY
1703 char * slave_name;
1704 /* SGI apparently needs this forward declaration */
1705 extern char * _getpty(int *, int, mode_t, int);
1706#endif
1707
Fred Drake8cef4cf2000-06-28 16:40:38 +00001708 if (!PyArg_ParseTuple(args, ":openpty"))
1709 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001710
1711#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001712 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1713 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001714#else
1715 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1716 if (slave_name == NULL)
1717 return posix_error();
1718
1719 slave_fd = open(slave_name, O_RDWR);
1720 if (slave_fd < 0)
1721 return posix_error();
1722#endif /* defined(HAVE_OPENPTY) */
1723
Fred Drake8cef4cf2000-06-28 16:40:38 +00001724 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001725
Fred Drake8cef4cf2000-06-28 16:40:38 +00001726}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001727#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001728
1729#ifdef HAVE_FORKPTY
1730static char posix_forkpty__doc__[] =
1731"forkpty() -> (pid, master_fd)\n\
1732Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1733Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1734To both, return fd of newly opened pseudo-terminal.\n";
1735
1736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001737posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001738{
1739 int master_fd, pid;
1740
1741 if (!PyArg_ParseTuple(args, ":forkpty"))
1742 return NULL;
1743 pid = forkpty(&master_fd, NULL, NULL, NULL);
1744 if (pid == -1)
1745 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001746 if (pid == 0)
1747 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001748 return Py_BuildValue("(ii)", pid, master_fd);
1749}
1750#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001751
Guido van Rossumad0ee831995-03-01 10:34:45 +00001752#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001753static char posix_getegid__doc__[] =
1754"getegid() -> egid\n\
1755Return the current process's effective group id.";
1756
Barry Warsaw53699e91996-12-10 23:23:01 +00001757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001758posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001759{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001760 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001761 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001762 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001763}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001764#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001765
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001766
Guido van Rossumad0ee831995-03-01 10:34:45 +00001767#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001768static char posix_geteuid__doc__[] =
1769"geteuid() -> euid\n\
1770Return the current process's effective user id.";
1771
Barry Warsaw53699e91996-12-10 23:23:01 +00001772static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001773posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001774{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001775 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001776 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001777 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001778}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001779#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001781
Guido van Rossumad0ee831995-03-01 10:34:45 +00001782#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001783static char posix_getgid__doc__[] =
1784"getgid() -> gid\n\
1785Return the current process's group id.";
1786
Barry Warsaw53699e91996-12-10 23:23:01 +00001787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001788posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001789{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001790 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001791 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001792 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001793}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001794#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001796
1797static char posix_getpid__doc__[] =
1798"getpid() -> pid\n\
1799Return the current process id";
1800
Barry Warsaw53699e91996-12-10 23:23:01 +00001801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001802posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001803{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001804 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001805 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001806 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001807}
1808
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001809
Fred Drakec9680921999-12-13 16:37:25 +00001810#ifdef HAVE_GETGROUPS
1811static char posix_getgroups__doc__[] = "\
1812getgroups() -> list of group IDs\n\
1813Return list of supplemental group IDs for the process.";
1814
1815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001816posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001817{
1818 PyObject *result = NULL;
1819
1820 if (PyArg_ParseTuple(args, ":getgroups")) {
1821#ifdef NGROUPS_MAX
1822#define MAX_GROUPS NGROUPS_MAX
1823#else
1824 /* defined to be 16 on Solaris7, so this should be a small number */
1825#define MAX_GROUPS 64
1826#endif
1827 gid_t grouplist[MAX_GROUPS];
1828 int n;
1829
1830 n = getgroups(MAX_GROUPS, grouplist);
1831 if (n < 0)
1832 posix_error();
1833 else {
1834 result = PyList_New(n);
1835 if (result != NULL) {
1836 PyObject *o;
1837 int i;
1838 for (i = 0; i < n; ++i) {
1839 o = PyInt_FromLong((long)grouplist[i]);
1840 if (o == NULL) {
1841 Py_DECREF(result);
1842 result = NULL;
1843 break;
1844 }
1845 PyList_SET_ITEM(result, i, o);
1846 }
1847 }
1848 }
1849 }
1850 return result;
1851}
1852#endif
1853
Guido van Rossumb6775db1994-08-01 11:34:53 +00001854#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001855static char posix_getpgrp__doc__[] =
1856"getpgrp() -> pgrp\n\
1857Return the current process group id.";
1858
Barry Warsaw53699e91996-12-10 23:23:01 +00001859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001860posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001861{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001862 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001863 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001864#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001865 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001866#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001867 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001868#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001869}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001870#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001871
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001872
Guido van Rossumb6775db1994-08-01 11:34:53 +00001873#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001874static char posix_setpgrp__doc__[] =
1875"setpgrp() -> None\n\
1876Make this process a session leader.";
1877
Barry Warsaw53699e91996-12-10 23:23:01 +00001878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001879posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001880{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001881 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001882 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001883#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001884 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001885#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001886 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001887#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001888 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001889 Py_INCREF(Py_None);
1890 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001891}
1892
Guido van Rossumb6775db1994-08-01 11:34:53 +00001893#endif /* HAVE_SETPGRP */
1894
Guido van Rossumad0ee831995-03-01 10:34:45 +00001895#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001896static char posix_getppid__doc__[] =
1897"getppid() -> ppid\n\
1898Return the parent's process id.";
1899
Barry Warsaw53699e91996-12-10 23:23:01 +00001900static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001901posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001902{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001903 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001904 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001905 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001906}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001907#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001909
Fred Drake12c6e2d1999-12-14 21:25:03 +00001910#ifdef HAVE_GETLOGIN
1911static char posix_getlogin__doc__[] = "\
1912getlogin() -> string\n\
1913Return the actual login name.";
1914
1915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001916posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001917{
1918 PyObject *result = NULL;
1919
1920 if (PyArg_ParseTuple(args, ":getlogin")) {
1921 char *name = getlogin();
1922
1923 if (name == NULL)
1924 posix_error();
1925 else
1926 result = PyString_FromString(name);
1927 }
1928 return result;
1929}
1930#endif
1931
Guido van Rossumad0ee831995-03-01 10:34:45 +00001932#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001933static char posix_getuid__doc__[] =
1934"getuid() -> uid\n\
1935Return the current process's user id.";
1936
Barry Warsaw53699e91996-12-10 23:23:01 +00001937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001938posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001939{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001940 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001941 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001942 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001943}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001944#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001946
Guido van Rossumad0ee831995-03-01 10:34:45 +00001947#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001948static char posix_kill__doc__[] =
1949"kill(pid, sig) -> None\n\
1950Kill a process with a signal.";
1951
Barry Warsaw53699e91996-12-10 23:23:01 +00001952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001953posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001954{
1955 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001956 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001957 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001958#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001959 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1960 APIRET rc;
1961 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001962 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001963
1964 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1965 APIRET rc;
1966 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001967 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001968
1969 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001970 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001971#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001972 if (kill(pid, sig) == -1)
1973 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001974#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001975 Py_INCREF(Py_None);
1976 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001977}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001978#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001979
Guido van Rossumc0125471996-06-28 18:55:32 +00001980#ifdef HAVE_PLOCK
1981
1982#ifdef HAVE_SYS_LOCK_H
1983#include <sys/lock.h>
1984#endif
1985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001986static char posix_plock__doc__[] =
1987"plock(op) -> None\n\
1988Lock program segments into memory.";
1989
Barry Warsaw53699e91996-12-10 23:23:01 +00001990static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001991posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001992{
1993 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001994 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001995 return NULL;
1996 if (plock(op) == -1)
1997 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001998 Py_INCREF(Py_None);
1999 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002000}
2001#endif
2002
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002003
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002004#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002005static char posix_popen__doc__[] =
2006"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2007Open a pipe to/from a command returning a file object.";
2008
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002009#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002010static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002011async_system(const char *command)
2012{
2013 char *p, errormsg[256], args[1024];
2014 RESULTCODES rcodes;
2015 APIRET rc;
2016 char *shell = getenv("COMSPEC");
2017 if (!shell)
2018 shell = "cmd";
2019
2020 strcpy(args, shell);
2021 p = &args[ strlen(args)+1 ];
2022 strcpy(p, "/c ");
2023 strcat(p, command);
2024 p += strlen(p) + 1;
2025 *p = '\0';
2026
2027 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002028 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002029 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002030 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002031 &rcodes, shell);
2032 return rc;
2033}
2034
Guido van Rossumd48f2521997-12-05 22:19:34 +00002035static FILE *
2036popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002037{
2038 HFILE rhan, whan;
2039 FILE *retfd = NULL;
2040 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2041
Guido van Rossumd48f2521997-12-05 22:19:34 +00002042 if (rc != NO_ERROR) {
2043 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002044 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002045 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002046
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002047 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2048 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002049
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002050 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2051 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002052
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002053 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2054 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002055
2056 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002057 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002058 }
2059
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002060 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2061 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002062
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002063 close(oldfd); /* And Close Saved STDOUT Handle */
2064 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002065
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002066 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2067 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002068
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002069 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2070 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002071
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002072 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2073 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074
2075 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002076 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002077 }
2078
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002079 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2080 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002081
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002082 close(oldfd); /* And Close Saved STDIN Handle */
2083 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002084
Guido van Rossumd48f2521997-12-05 22:19:34 +00002085 } else {
2086 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002087 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002088 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002089}
2090
2091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002092posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002093{
2094 char *name;
2095 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002096 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002097 FILE *fp;
2098 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002099 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002100 return NULL;
2101 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002102 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002103 Py_END_ALLOW_THREADS
2104 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002105 return os2_error(err);
2106
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002107 f = PyFile_FromFile(fp, name, mode, fclose);
2108 if (f != NULL)
2109 PyFile_SetBufSize(f, bufsize);
2110 return f;
2111}
2112
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002113#elif defined(MS_WIN32)
2114
2115/*
2116 * Portable 'popen' replacement for Win32.
2117 *
2118 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2119 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
2120 */
2121
2122#include <malloc.h>
2123#include <io.h>
2124#include <fcntl.h>
2125
2126/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2127#define POPEN_1 1
2128#define POPEN_2 2
2129#define POPEN_3 3
2130#define POPEN_4 4
2131
2132static PyObject *_PyPopen(char *, int, int);
2133
2134/* popen that works from a GUI.
2135 *
2136 * The result of this function is a pipe (file) connected to the
2137 * processes stdin or stdout, depending on the requested mode.
2138 */
2139
2140static PyObject *
2141posix_popen(PyObject *self, PyObject *args)
2142{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002143 PyObject *f, *s;
2144 int tm = 0;
2145
2146 char *cmdstring;
2147 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002148 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002149 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002150 return NULL;
2151
2152 s = PyTuple_New(0);
2153
2154 if (*mode == 'r')
2155 tm = _O_RDONLY;
2156 else if (*mode != 'w') {
2157 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'");
2158 return NULL;
2159 } else
2160 tm = _O_WRONLY;
2161
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002162 if (bufsize != -1) {
2163 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2164 return NULL;
2165 }
2166
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002167 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002168 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002169 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002170 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002171 else
2172 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2173
2174 return f;
2175}
2176
2177/* Variation on win32pipe.popen
2178 *
2179 * The result of this function is a pipe (file) connected to the
2180 * process's stdin, and a pipe connected to the process's stdout.
2181 */
2182
2183static PyObject *
2184win32_popen2(PyObject *self, PyObject *args)
2185{
2186 PyObject *f;
2187 int tm=0;
2188
2189 char *cmdstring;
2190 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002191 int bufsize = -1;
2192 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002193 return NULL;
2194
2195 if (*mode == 't')
2196 tm = _O_TEXT;
2197 else if (*mode != 'b') {
2198 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2199 return NULL;
2200 } else
2201 tm = _O_BINARY;
2202
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002203 if (bufsize != -1) {
2204 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2205 return NULL;
2206 }
2207
2208 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002209
2210 return f;
2211}
2212
2213/*
2214 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002215 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002216 * The result of this function is 3 pipes - the process's stdin,
2217 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002218 */
2219
2220static PyObject *
2221win32_popen3(PyObject *self, PyObject *args)
2222{
2223 PyObject *f;
2224 int tm = 0;
2225
2226 char *cmdstring;
2227 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002228 int bufsize = -1;
2229 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002230 return NULL;
2231
2232 if (*mode == 't')
2233 tm = _O_TEXT;
2234 else if (*mode != 'b') {
2235 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2236 return NULL;
2237 } else
2238 tm = _O_BINARY;
2239
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002240 if (bufsize != -1) {
2241 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2242 return NULL;
2243 }
2244
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002245 f = _PyPopen(cmdstring, tm, POPEN_3);
2246
2247 return f;
2248}
2249
2250/*
2251 * Variation on win32pipe.popen
2252 *
2253 * The result of this function is 2 pipes - the processes stdin,
2254 * and stdout+stderr combined as a single pipe.
2255 */
2256
2257static PyObject *
2258win32_popen4(PyObject *self, PyObject *args)
2259{
2260 PyObject *f;
2261 int tm = 0;
2262
2263 char *cmdstring;
2264 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002265 int bufsize = -1;
2266 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002267 return NULL;
2268
2269 if (*mode == 't')
2270 tm = _O_TEXT;
2271 else if (*mode != 'b') {
2272 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2273 return NULL;
2274 } else
2275 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002276
2277 if (bufsize != -1) {
2278 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2279 return NULL;
2280 }
2281
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002282 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002283
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002284 return f;
2285}
2286
2287static int
2288_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002289 HANDLE hStdin,
2290 HANDLE hStdout,
2291 HANDLE hStderr)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002292{
2293 PROCESS_INFORMATION piProcInfo;
2294 STARTUPINFO siStartInfo;
2295 char *s1,*s2, *s3 = " /c ";
2296 const char *szConsoleSpawn = "w9xpopen.exe \"";
2297 int i;
2298 int x;
2299
2300 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2301 s1 = (char *)_alloca(i);
2302 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2303 return x;
2304 if (GetVersion() < 0x80000000) {
2305 /*
2306 * NT/2000
2307 */
2308 x = i + strlen(s3) + strlen(cmdstring) + 1;
2309 s2 = (char *)_alloca(x);
2310 ZeroMemory(s2, x);
2311 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2312 }
2313 else {
2314 /*
2315 * Oh gag, we're on Win9x. Use the workaround listed in
2316 * KB: Q150956
2317 */
2318 char modulepath[256];
2319 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2320 for (i = x = 0; modulepath[i]; i++)
2321 if (modulepath[i] == '\\')
2322 x = i+1;
2323 modulepath[x] = '\0';
2324 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2325 strlen(modulepath) +
2326 strlen(szConsoleSpawn) + 1;
2327 s2 = (char *)_alloca(x);
2328 ZeroMemory(s2, x);
2329 sprintf(
2330 s2,
2331 "%s%s%s%s%s\"",
2332 modulepath,
2333 szConsoleSpawn,
2334 s1,
2335 s3,
2336 cmdstring);
2337 }
2338 }
2339
2340 /* Could be an else here to try cmd.exe / command.com in the path
2341 Now we'll just error out.. */
2342 else
2343 return -1;
2344
2345 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2346 siStartInfo.cb = sizeof(STARTUPINFO);
2347 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2348 siStartInfo.hStdInput = hStdin;
2349 siStartInfo.hStdOutput = hStdout;
2350 siStartInfo.hStdError = hStderr;
2351 siStartInfo.wShowWindow = SW_HIDE;
2352
2353 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002354 s2,
2355 NULL,
2356 NULL,
2357 TRUE,
2358 CREATE_NEW_CONSOLE,
2359 NULL,
2360 NULL,
2361 &siStartInfo,
2362 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002363 /* Close the handles now so anyone waiting is woken. */
2364 CloseHandle(piProcInfo.hProcess);
2365 CloseHandle(piProcInfo.hThread);
2366 return TRUE;
2367 }
2368 return FALSE;
2369}
2370
2371/* The following code is based off of KB: Q190351 */
2372
2373static PyObject *
2374_PyPopen(char *cmdstring, int mode, int n)
2375{
2376 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2377 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
2378 hChildStderrRdDup; /* hChildStdoutWrDup; */
2379
2380 SECURITY_ATTRIBUTES saAttr;
2381 BOOL fSuccess;
2382 int fd1, fd2, fd3;
2383 FILE *f1, *f2, *f3;
2384 PyObject *f;
2385
2386 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2387 saAttr.bInheritHandle = TRUE;
2388 saAttr.lpSecurityDescriptor = NULL;
2389
2390 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2391 return win32_error("CreatePipe", NULL);
2392
2393 /* Create new output read handle and the input write handle. Set
2394 * the inheritance properties to FALSE. Otherwise, the child inherits
2395 * the these handles; resulting in non-closeable handles to the pipes
2396 * being created. */
2397 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002398 GetCurrentProcess(), &hChildStdinWrDup, 0,
2399 FALSE,
2400 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002401 if (!fSuccess)
2402 return win32_error("DuplicateHandle", NULL);
2403
2404 /* Close the inheritable version of ChildStdin
2405 that we're using. */
2406 CloseHandle(hChildStdinWr);
2407
2408 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2409 return win32_error("CreatePipe", NULL);
2410
2411 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002412 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2413 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002414 if (!fSuccess)
2415 return win32_error("DuplicateHandle", NULL);
2416
2417 /* Close the inheritable version of ChildStdout
2418 that we're using. */
2419 CloseHandle(hChildStdoutRd);
2420
2421 if (n != POPEN_4) {
2422 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2423 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002424 fSuccess = DuplicateHandle(GetCurrentProcess(),
2425 hChildStderrRd,
2426 GetCurrentProcess(),
2427 &hChildStderrRdDup, 0,
2428 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002429 if (!fSuccess)
2430 return win32_error("DuplicateHandle", NULL);
2431 /* Close the inheritable version of ChildStdErr that we're using. */
2432 CloseHandle(hChildStderrRd);
2433 }
2434
2435 switch (n) {
2436 case POPEN_1:
2437 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2438 case _O_WRONLY | _O_TEXT:
2439 /* Case for writing to child Stdin in text mode. */
2440 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2441 f1 = _fdopen(fd1, "w");
2442 f = PyFile_FromFile(f1, cmdstring, "w", fclose);
2443 PyFile_SetBufSize(f, 0);
2444 /* We don't care about these pipes anymore, so close them. */
2445 CloseHandle(hChildStdoutRdDup);
2446 CloseHandle(hChildStderrRdDup);
2447 break;
2448
2449 case _O_RDONLY | _O_TEXT:
2450 /* Case for reading from child Stdout in text mode. */
2451 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2452 f1 = _fdopen(fd1, "r");
2453 f = PyFile_FromFile(f1, cmdstring, "r", fclose);
2454 PyFile_SetBufSize(f, 0);
2455 /* We don't care about these pipes anymore, so close them. */
2456 CloseHandle(hChildStdinWrDup);
2457 CloseHandle(hChildStderrRdDup);
2458 break;
2459
2460 case _O_RDONLY | _O_BINARY:
2461 /* Case for readinig from child Stdout in binary mode. */
2462 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2463 f1 = _fdopen(fd1, "rb");
2464 f = PyFile_FromFile(f1, cmdstring, "rb", fclose);
2465 PyFile_SetBufSize(f, 0);
2466 /* We don't care about these pipes anymore, so close them. */
2467 CloseHandle(hChildStdinWrDup);
2468 CloseHandle(hChildStderrRdDup);
2469 break;
2470
2471 case _O_WRONLY | _O_BINARY:
2472 /* Case for writing to child Stdin in binary mode. */
2473 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2474 f1 = _fdopen(fd1, "wb");
2475 f = PyFile_FromFile(f1, cmdstring, "wb", fclose);
2476 PyFile_SetBufSize(f, 0);
2477 /* We don't care about these pipes anymore, so close them. */
2478 CloseHandle(hChildStdoutRdDup);
2479 CloseHandle(hChildStderrRdDup);
2480 break;
2481 }
2482 break;
2483
2484 case POPEN_2:
2485 case POPEN_4:
2486 {
2487 char *m1, *m2;
2488 PyObject *p1, *p2;
2489
2490 if (mode && _O_TEXT) {
2491 m1 = "r";
2492 m2 = "w";
2493 } else {
2494 m1 = "rb";
2495 m2 = "wb";
2496 }
2497
2498 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2499 f1 = _fdopen(fd1, m2);
2500 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2501 f2 = _fdopen(fd2, m1);
2502 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose);
2503 PyFile_SetBufSize(p1, 0);
2504 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2505 PyFile_SetBufSize(p2, 0);
2506
2507 if (n != 4)
2508 CloseHandle(hChildStderrRdDup);
2509
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002510 f = Py_BuildValue("OO",p1,p2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002511 break;
2512 }
2513
2514 case POPEN_3:
2515 {
2516 char *m1, *m2;
2517 PyObject *p1, *p2, *p3;
2518
2519 if (mode && _O_TEXT) {
2520 m1 = "r";
2521 m2 = "w";
2522 } else {
2523 m1 = "rb";
2524 m2 = "wb";
2525 }
2526
2527 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2528 f1 = _fdopen(fd1, m2);
2529 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2530 f2 = _fdopen(fd2, m1);
2531 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2532 f3 = _fdopen(fd3, m1);
2533 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose);
2534 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2535 p3 = PyFile_FromFile(f3, cmdstring, m1, fclose);
2536 PyFile_SetBufSize(p1, 0);
2537 PyFile_SetBufSize(p2, 0);
2538 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002539 f = Py_BuildValue("OOO",p1,p2,p3);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002540 break;
2541 }
2542 }
2543
2544 if (n == POPEN_4) {
2545 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002546 hChildStdinRd,
2547 hChildStdoutWr,
2548 hChildStdoutWr))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002549 return win32_error("CreateProcess", NULL);
2550 }
2551 else {
2552 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002553 hChildStdinRd,
2554 hChildStdoutWr,
2555 hChildStderrWr))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002556 return win32_error("CreateProcess", NULL);
2557 }
2558
2559 /* Child is launched. Close the parents copy of those pipe
2560 * handles that only the child should have open. You need to
2561 * make sure that no handles to the write end of the output pipe
2562 * are maintained in this process or else the pipe will not close
2563 * when the child process exits and the ReadFile will hang. */
2564
2565 if (!CloseHandle(hChildStdinRd))
2566 return win32_error("CloseHandle", NULL);
2567
2568 if (!CloseHandle(hChildStdoutWr))
2569 return win32_error("CloseHandle", NULL);
2570
2571 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2572 return win32_error("CloseHandle", NULL);
2573
2574 return f;
2575}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002576#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002578posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002579{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002580 char *name;
2581 char *mode = "r";
2582 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002583 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002584 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002585 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002586 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002587 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002588 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002589 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002590 if (fp == NULL)
2591 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002592 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002593 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002594 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002595 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002596}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002597#endif
2598
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002599#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002600
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002601
Guido van Rossumb6775db1994-08-01 11:34:53 +00002602#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002603static char posix_setuid__doc__[] =
2604"setuid(uid) -> None\n\
2605Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002607posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002608{
2609 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002610 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002611 return NULL;
2612 if (setuid(uid) < 0)
2613 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002614 Py_INCREF(Py_None);
2615 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002616}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002617#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002618
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002619
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002620#ifdef HAVE_SETEUID
2621static char posix_seteuid__doc__[] =
2622"seteuid(uid) -> None\n\
2623Set the current process's effective user id.";
2624static PyObject *
2625posix_seteuid (PyObject *self, PyObject *args)
2626{
2627 int euid;
2628 if (!PyArg_ParseTuple(args, "i", &euid)) {
2629 return NULL;
2630 } else if (seteuid(euid) < 0) {
2631 return posix_error();
2632 } else {
2633 Py_INCREF(Py_None);
2634 return Py_None;
2635 }
2636}
2637#endif /* HAVE_SETEUID */
2638
2639#ifdef HAVE_SETEGID
2640static char posix_setegid__doc__[] =
2641"setegid(gid) -> None\n\
2642Set the current process's effective group id.";
2643static PyObject *
2644posix_setegid (PyObject *self, PyObject *args)
2645{
2646 int egid;
2647 if (!PyArg_ParseTuple(args, "i", &egid)) {
2648 return NULL;
2649 } else if (setegid(egid) < 0) {
2650 return posix_error();
2651 } else {
2652 Py_INCREF(Py_None);
2653 return Py_None;
2654 }
2655}
2656#endif /* HAVE_SETEGID */
2657
2658#ifdef HAVE_SETREUID
2659static char posix_setreuid__doc__[] =
2660"seteuid(ruid, euid) -> None\n\
2661Set the current process's real and effective user ids.";
2662static PyObject *
2663posix_setreuid (PyObject *self, PyObject *args)
2664{
2665 int ruid, euid;
2666 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2667 return NULL;
2668 } else if (setreuid(ruid, euid) < 0) {
2669 return posix_error();
2670 } else {
2671 Py_INCREF(Py_None);
2672 return Py_None;
2673 }
2674}
2675#endif /* HAVE_SETREUID */
2676
2677#ifdef HAVE_SETREGID
2678static char posix_setregid__doc__[] =
2679"setegid(rgid, egid) -> None\n\
2680Set the current process's real and effective group ids.";
2681static PyObject *
2682posix_setregid (PyObject *self, PyObject *args)
2683{
2684 int rgid, egid;
2685 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2686 return NULL;
2687 } else if (setregid(rgid, egid) < 0) {
2688 return posix_error();
2689 } else {
2690 Py_INCREF(Py_None);
2691 return Py_None;
2692 }
2693}
2694#endif /* HAVE_SETREGID */
2695
Guido van Rossumb6775db1994-08-01 11:34:53 +00002696#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002697static char posix_setgid__doc__[] =
2698"setgid(gid) -> None\n\
2699Set the current process's group id.";
2700
Barry Warsaw53699e91996-12-10 23:23:01 +00002701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002702posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002703{
2704 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002705 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002706 return NULL;
2707 if (setgid(gid) < 0)
2708 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002709 Py_INCREF(Py_None);
2710 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002711}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002712#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002713
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002714
Guido van Rossumb6775db1994-08-01 11:34:53 +00002715#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002716static char posix_waitpid__doc__[] =
2717"waitpid(pid, options) -> (pid, status)\n\
2718Wait for completion of a give child process.";
2719
Barry Warsaw53699e91996-12-10 23:23:01 +00002720static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002721posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002722{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002723 int pid, options;
2724#ifdef UNION_WAIT
2725 union wait status;
2726#define status_i (status.w_status)
2727#else
2728 int status;
2729#define status_i status
2730#endif
2731 status_i = 0;
2732
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002733 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00002734 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002735 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002736#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002737 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002738#else
2739 pid = waitpid(pid, &status, options);
2740#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002741 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00002742 if (pid == -1)
2743 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00002744 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002745 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00002746}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002747#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00002748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002749
Guido van Rossumad0ee831995-03-01 10:34:45 +00002750#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002751static char posix_wait__doc__[] =
2752"wait() -> (pid, status)\n\
2753Wait for completion of a child process.";
2754
Barry Warsaw53699e91996-12-10 23:23:01 +00002755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002756posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00002757{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002758 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002759#ifdef UNION_WAIT
2760 union wait status;
2761#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002762#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002763 int status;
2764#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002765#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002766 if (!PyArg_ParseTuple(args, ":wait"))
2767 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002768 status_i = 0;
2769 Py_BEGIN_ALLOW_THREADS
2770 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00002771 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00002772 if (pid == -1)
2773 return posix_error();
2774 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002775 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002776#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00002777}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002778#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002780
2781static char posix_lstat__doc__[] =
2782"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
2783Like stat(path), but do not follow symbolic links.";
2784
Barry Warsaw53699e91996-12-10 23:23:01 +00002785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002786posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002787{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002788#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002789 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002790#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00002791 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002792#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002793}
2794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002795
Guido van Rossumb6775db1994-08-01 11:34:53 +00002796#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002797static char posix_readlink__doc__[] =
2798"readlink(path) -> path\n\
2799Return a string representing the path to which the symbolic link points.";
2800
Barry Warsaw53699e91996-12-10 23:23:01 +00002801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002802posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002803{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002804 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002805 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002806 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002807 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002808 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002809 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002810 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00002811 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002812 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002813 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002814 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002815}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002816#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002818
Guido van Rossumb6775db1994-08-01 11:34:53 +00002819#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002820static char posix_symlink__doc__[] =
2821"symlink(src, dst) -> None\n\
2822Create a symbolic link.";
2823
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002825posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002826{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002827 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002828}
2829#endif /* HAVE_SYMLINK */
2830
2831
2832#ifdef HAVE_TIMES
2833#ifndef HZ
2834#define HZ 60 /* Universal constant :-) */
2835#endif /* HZ */
2836
Guido van Rossumd48f2521997-12-05 22:19:34 +00002837#if defined(PYCC_VACPP) && defined(PYOS_OS2)
2838static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002839system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002840{
2841 ULONG value = 0;
2842
2843 Py_BEGIN_ALLOW_THREADS
2844 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
2845 Py_END_ALLOW_THREADS
2846
2847 return value;
2848}
2849
2850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002851posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002852{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002853 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00002854 return NULL;
2855
2856 /* Currently Only Uptime is Provided -- Others Later */
2857 return Py_BuildValue("ddddd",
2858 (double)0 /* t.tms_utime / HZ */,
2859 (double)0 /* t.tms_stime / HZ */,
2860 (double)0 /* t.tms_cutime / HZ */,
2861 (double)0 /* t.tms_cstime / HZ */,
2862 (double)system_uptime() / 1000);
2863}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002864#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002865static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002866posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00002867{
2868 struct tms t;
2869 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002870 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00002871 return NULL;
2872 errno = 0;
2873 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00002874 if (c == (clock_t) -1)
2875 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002876 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002877 (double)t.tms_utime / HZ,
2878 (double)t.tms_stime / HZ,
2879 (double)t.tms_cutime / HZ,
2880 (double)t.tms_cstime / HZ,
2881 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00002882}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002883#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002884#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002885
2886
Guido van Rossum87755a21996-09-07 00:59:43 +00002887#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002888#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00002889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002890posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002891{
2892 FILETIME create, exit, kernel, user;
2893 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002894 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002895 return NULL;
2896 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002897 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
2898 /* The fields of a FILETIME structure are the hi and lo part
2899 of a 64-bit value expressed in 100 nanosecond units.
2900 1e7 is one second in such units; 1e-7 the inverse.
2901 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
2902 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002903 return Py_BuildValue(
2904 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002905 (double)(kernel.dwHighDateTime*429.4967296 +
2906 kernel.dwLowDateTime*1e-7),
2907 (double)(user.dwHighDateTime*429.4967296 +
2908 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00002909 (double)0,
2910 (double)0,
2911 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002912}
Guido van Rossum8d665e61996-06-26 18:22:49 +00002913#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002914
2915#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00002916static char posix_times__doc__[] =
2917"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
2918Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002919#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00002920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002921
Guido van Rossumb6775db1994-08-01 11:34:53 +00002922#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002923static char posix_setsid__doc__[] =
2924"setsid() -> None\n\
2925Call the system call setsid().";
2926
Barry Warsaw53699e91996-12-10 23:23:01 +00002927static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002928posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002929{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002930 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002931 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002932 if (setsid() < 0)
2933 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002934 Py_INCREF(Py_None);
2935 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002936}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002937#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00002938
Guido van Rossumb6775db1994-08-01 11:34:53 +00002939#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002940static char posix_setpgid__doc__[] =
2941"setpgid(pid, pgrp) -> None\n\
2942Call the system call setpgid().";
2943
Barry Warsaw53699e91996-12-10 23:23:01 +00002944static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002945posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002946{
2947 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002948 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002949 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002950 if (setpgid(pid, pgrp) < 0)
2951 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002952 Py_INCREF(Py_None);
2953 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002954}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002955#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00002956
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002957
Guido van Rossumb6775db1994-08-01 11:34:53 +00002958#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002959static char posix_tcgetpgrp__doc__[] =
2960"tcgetpgrp(fd) -> pgid\n\
2961Return the process group associated with the terminal given by a fd.";
2962
Barry Warsaw53699e91996-12-10 23:23:01 +00002963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002964posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00002965{
2966 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002967 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00002968 return NULL;
2969 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00002970 if (pgid < 0)
2971 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002972 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00002973}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002974#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00002975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002976
Guido van Rossumb6775db1994-08-01 11:34:53 +00002977#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002978static char posix_tcsetpgrp__doc__[] =
2979"tcsetpgrp(fd, pgid) -> None\n\
2980Set the process group associated with the terminal given by a fd.";
2981
Barry Warsaw53699e91996-12-10 23:23:01 +00002982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002983posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00002984{
2985 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002986 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00002987 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002988 if (tcsetpgrp(fd, pgid) < 0)
2989 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00002990 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00002991 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00002992}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002993#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00002994
Guido van Rossum687dd131993-05-17 08:34:16 +00002995/* Functions acting on file descriptors */
2996
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002997static char posix_open__doc__[] =
2998"open(filename, flag [, mode=0777]) -> fd\n\
2999Open a file (for low level IO).";
3000
Barry Warsaw53699e91996-12-10 23:23:01 +00003001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003002posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003003{
3004 char *file;
3005 int flag;
3006 int mode = 0777;
3007 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003008 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3009 return NULL;
3010
Barry Warsaw53699e91996-12-10 23:23:01 +00003011 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003012 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003013 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003014 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003015 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003016 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003017}
3018
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003019
3020static char posix_close__doc__[] =
3021"close(fd) -> None\n\
3022Close a file descriptor (for low level IO).";
3023
Barry Warsaw53699e91996-12-10 23:23:01 +00003024static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003025posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003026{
3027 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003028 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003029 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003030 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003031 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003032 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003033 if (res < 0)
3034 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003035 Py_INCREF(Py_None);
3036 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003037}
3038
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003039
3040static char posix_dup__doc__[] =
3041"dup(fd) -> fd2\n\
3042Return a duplicate of a file descriptor.";
3043
Barry Warsaw53699e91996-12-10 23:23:01 +00003044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003045posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003046{
3047 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003048 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003049 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003050 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003051 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003052 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003053 if (fd < 0)
3054 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003055 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003056}
3057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003058
3059static char posix_dup2__doc__[] =
3060"dup2(fd, fd2) -> None\n\
3061Duplicate file descriptor.";
3062
Barry Warsaw53699e91996-12-10 23:23:01 +00003063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003064posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003065{
3066 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003067 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003068 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003069 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003070 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003071 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003072 if (res < 0)
3073 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003074 Py_INCREF(Py_None);
3075 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003076}
3077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003078
3079static char posix_lseek__doc__[] =
3080"lseek(fd, pos, how) -> newpos\n\
3081Set the current position of a file descriptor.";
3082
Barry Warsaw53699e91996-12-10 23:23:01 +00003083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003084posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003085{
3086 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003087#ifdef MS_WIN64
3088 LONG_LONG pos, res;
3089#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003090 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003091#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003092 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003093 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003094 return NULL;
3095#ifdef SEEK_SET
3096 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3097 switch (how) {
3098 case 0: how = SEEK_SET; break;
3099 case 1: how = SEEK_CUR; break;
3100 case 2: how = SEEK_END; break;
3101 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003102#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003103
3104#if !defined(HAVE_LARGEFILE_SUPPORT)
3105 pos = PyInt_AsLong(posobj);
3106#else
3107 pos = PyLong_Check(posobj) ?
3108 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3109#endif
3110 if (PyErr_Occurred())
3111 return NULL;
3112
Barry Warsaw53699e91996-12-10 23:23:01 +00003113 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003114#ifdef MS_WIN64
3115 res = _lseeki64(fd, pos, how);
3116#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003117 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003118#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003119 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003120 if (res < 0)
3121 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003122
3123#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003124 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003125#else
3126 return PyLong_FromLongLong(res);
3127#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003128}
3129
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003130
3131static char posix_read__doc__[] =
3132"read(fd, buffersize) -> string\n\
3133Read a file descriptor.";
3134
Barry Warsaw53699e91996-12-10 23:23:01 +00003135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003136posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003137{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003138 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003139 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003140 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003141 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003142 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003143 if (buffer == NULL)
3144 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003145 Py_BEGIN_ALLOW_THREADS
3146 n = read(fd, PyString_AsString(buffer), size);
3147 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003148 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003149 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003150 return posix_error();
3151 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003152 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003153 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003154 return buffer;
3155}
3156
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003157
3158static char posix_write__doc__[] =
3159"write(fd, string) -> byteswritten\n\
3160Write a string to a file descriptor.";
3161
Barry Warsaw53699e91996-12-10 23:23:01 +00003162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003163posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003164{
3165 int fd, size;
3166 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003167 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003168 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003169 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003170 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003171 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003172 if (size < 0)
3173 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003174 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003175}
3176
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003177
3178static char posix_fstat__doc__[]=
3179"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3180Like stat(), but for an open file descriptor.";
3181
Barry Warsaw53699e91996-12-10 23:23:01 +00003182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003183posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003184{
3185 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003186 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003187 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003188 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003189 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003190 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003191 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003192 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003193 if (res != 0)
3194 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003195
3196 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003197}
3198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003199
3200static char posix_fdopen__doc__[] =
3201"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3202Return an open file object connected to a file descriptor.";
3203
Barry Warsaw53699e91996-12-10 23:23:01 +00003204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003205posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003206{
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003207 extern int fclose(FILE *);
Guido van Rossum687dd131993-05-17 08:34:16 +00003208 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003209 char *mode = "r";
3210 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003211 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003212 PyObject *f;
3213 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003214 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003215
Barry Warsaw53699e91996-12-10 23:23:01 +00003216 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003217 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003218 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003219 if (fp == NULL)
3220 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003221 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003222 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003223 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003224 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003225}
3226
Skip Montanaro1517d842000-07-19 14:34:14 +00003227static char posix_isatty__doc__[] =
3228"isatty(fd) -> Boolean\n\
3229Return true if the file descriptor 'fd' is an open file descriptor\n\
3230connected to a terminal.";
3231
3232static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003233posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003234{
3235 int fd;
3236 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3237 return NULL;
3238 return Py_BuildValue("i", isatty(fd));
3239}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003240
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003241#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003242static char posix_pipe__doc__[] =
3243"pipe() -> (read_end, write_end)\n\
3244Create a pipe.";
3245
Barry Warsaw53699e91996-12-10 23:23:01 +00003246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003247posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003248{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003249#if defined(PYOS_OS2)
3250 HFILE read, write;
3251 APIRET rc;
3252
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003253 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003254 return NULL;
3255
3256 Py_BEGIN_ALLOW_THREADS
3257 rc = DosCreatePipe( &read, &write, 4096);
3258 Py_END_ALLOW_THREADS
3259 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003260 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003261
3262 return Py_BuildValue("(ii)", read, write);
3263#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003264#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003265 int fds[2];
3266 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003267 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003268 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003269 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003270 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003271 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003272 if (res != 0)
3273 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003274 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003275#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003276 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003277 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003278 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003279 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003280 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003281 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003282 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003283 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003284 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003285 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003286 read_fd = _open_osfhandle((intptr_t)read, 0);
3287 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003288 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003289#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003290#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003291}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003292#endif /* HAVE_PIPE */
3293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003294
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003295#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003296static char posix_mkfifo__doc__[] =
3297"mkfifo(file, [, mode=0666]) -> None\n\
3298Create a FIFO (a POSIX named pipe).";
3299
Barry Warsaw53699e91996-12-10 23:23:01 +00003300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003301posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003302{
3303 char *file;
3304 int mode = 0666;
3305 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003306 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003307 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003308 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003309 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003310 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003311 if (res < 0)
3312 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003313 Py_INCREF(Py_None);
3314 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003315}
3316#endif
3317
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003318
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003319#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003320static char posix_ftruncate__doc__[] =
3321"ftruncate(fd, length) -> None\n\
3322Truncate a file to a specified length.";
3323
Barry Warsaw53699e91996-12-10 23:23:01 +00003324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003325posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003326{
3327 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003328 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003329 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003330 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003331
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003332 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003333 return NULL;
3334
3335#if !defined(HAVE_LARGEFILE_SUPPORT)
3336 length = PyInt_AsLong(lenobj);
3337#else
3338 length = PyLong_Check(lenobj) ?
3339 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3340#endif
3341 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003342 return NULL;
3343
Barry Warsaw53699e91996-12-10 23:23:01 +00003344 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003345 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003346 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003347 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003348 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003349 return NULL;
3350 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003351 Py_INCREF(Py_None);
3352 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003353}
3354#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003355
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003356#ifdef NeXT
3357#define HAVE_PUTENV
3358/* Steve Spicklemire got this putenv from NeXTAnswers */
3359static int
3360putenv(char *newval)
3361{
3362 extern char **environ;
3363
3364 static int firstTime = 1;
3365 char **ep;
3366 char *cp;
3367 int esiz;
3368 char *np;
3369
3370 if (!(np = strchr(newval, '=')))
3371 return 1;
3372 *np = '\0';
3373
3374 /* look it up */
3375 for (ep=environ ; *ep ; ep++)
3376 {
3377 /* this should always be true... */
3378 if (cp = strchr(*ep, '='))
3379 {
3380 *cp = '\0';
3381 if (!strcmp(*ep, newval))
3382 {
3383 /* got it! */
3384 *cp = '=';
3385 break;
3386 }
3387 *cp = '=';
3388 }
3389 else
3390 {
3391 *np = '=';
3392 return 1;
3393 }
3394 }
3395
3396 *np = '=';
3397 if (*ep)
3398 {
3399 /* the string was already there:
3400 just replace it with the new one */
3401 *ep = newval;
3402 return 0;
3403 }
3404
3405 /* expand environ by one */
3406 for (esiz=2, ep=environ ; *ep ; ep++)
3407 esiz++;
3408 if (firstTime)
3409 {
3410 char **epp;
3411 char **newenv;
3412 if (!(newenv = malloc(esiz * sizeof(char *))))
3413 return 1;
3414
3415 for (ep=environ, epp=newenv ; *ep ;)
3416 *epp++ = *ep++;
3417 *epp++ = newval;
3418 *epp = (char *) 0;
3419 environ = newenv;
3420 }
3421 else
3422 {
3423 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3424 return 1;
3425 environ[esiz - 2] = newval;
3426 environ[esiz - 1] = (char *) 0;
3427 firstTime = 0;
3428 }
3429
3430 return 0;
3431}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003432#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003433
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003434
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003435#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003436static char posix_putenv__doc__[] =
3437"putenv(key, value) -> None\n\
3438Change or add an environment variable.";
3439
Guido van Rossumbcc20741998-08-04 22:53:56 +00003440#ifdef __BEOS__
3441/* We have putenv(), but not in the headers (as of PR2). - [cjh] */
3442int putenv( const char *str );
3443#endif
3444
Fred Drake762e2061999-08-26 17:23:54 +00003445/* Save putenv() parameters as values here, so we can collect them when they
3446 * get re-set with another call for the same key. */
3447static PyObject *posix_putenv_garbage;
3448
Barry Warsaw53699e91996-12-10 23:23:01 +00003449static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003450posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003451{
3452 char *s1, *s2;
3453 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003454 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003455
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003456 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003457 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003458
3459#if defined(PYOS_OS2)
3460 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3461 APIRET rc;
3462
3463 if (strlen(s2) == 0) /* If New Value is an Empty String */
3464 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3465
3466 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3467 if (rc != NO_ERROR)
3468 return os2_error(rc);
3469
3470 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3471 APIRET rc;
3472
3473 if (strlen(s2) == 0) /* If New Value is an Empty String */
3474 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3475
3476 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3477 if (rc != NO_ERROR)
3478 return os2_error(rc);
3479 } else {
3480#endif
3481
Fred Drake762e2061999-08-26 17:23:54 +00003482 /* XXX This can leak memory -- not easy to fix :-( */
3483 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3484 if (newstr == NULL)
3485 return PyErr_NoMemory();
3486 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003487 (void) sprintf(new, "%s=%s", s1, s2);
3488 if (putenv(new)) {
3489 posix_error();
3490 return NULL;
3491 }
Fred Drake762e2061999-08-26 17:23:54 +00003492 /* Install the first arg and newstr in posix_putenv_garbage;
3493 * this will cause previous value to be collected. This has to
3494 * happen after the real putenv() call because the old value
3495 * was still accessible until then. */
3496 if (PyDict_SetItem(posix_putenv_garbage,
3497 PyTuple_GET_ITEM(args, 0), newstr)) {
3498 /* really not much we can do; just leak */
3499 PyErr_Clear();
3500 }
3501 else {
3502 Py_DECREF(newstr);
3503 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003504
3505#if defined(PYOS_OS2)
3506 }
3507#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003508 Py_INCREF(Py_None);
3509 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003510}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003511#endif /* putenv */
3512
3513#ifdef HAVE_STRERROR
3514static char posix_strerror__doc__[] =
3515"strerror(code) -> string\n\
3516Translate an error code to a message string.";
3517
3518PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003519posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003520{
3521 int code;
3522 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003523 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003524 return NULL;
3525 message = strerror(code);
3526 if (message == NULL) {
3527 PyErr_SetString(PyExc_ValueError,
3528 "strerror code out of range");
3529 return NULL;
3530 }
3531 return PyString_FromString(message);
3532}
3533#endif /* strerror */
3534
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003535
Guido van Rossumc9641791998-08-04 15:26:23 +00003536#ifdef HAVE_SYS_WAIT_H
3537
3538#ifdef WIFSTOPPED
3539static char posix_WIFSTOPPED__doc__[] =
3540"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003541Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003542
3543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003544posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003545{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003546#ifdef UNION_WAIT
3547 union wait status;
3548#define status_i (status.w_status)
3549#else
3550 int status;
3551#define status_i status
3552#endif
3553 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003554
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003555 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003556 {
3557 return NULL;
3558 }
3559
3560 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003561#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003562}
3563#endif /* WIFSTOPPED */
3564
3565#ifdef WIFSIGNALED
3566static char posix_WIFSIGNALED__doc__[] =
3567"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003568Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003569
3570static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003571posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003572{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003573#ifdef UNION_WAIT
3574 union wait status;
3575#define status_i (status.w_status)
3576#else
3577 int status;
3578#define status_i status
3579#endif
3580 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003581
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003582 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003583 {
3584 return NULL;
3585 }
3586
3587 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003588#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003589}
3590#endif /* WIFSIGNALED */
3591
3592#ifdef WIFEXITED
3593static char posix_WIFEXITED__doc__[] =
3594"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003595Return true if the process returning 'status' exited using the exit()\n\
3596system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003597
3598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003599posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003600{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003601#ifdef UNION_WAIT
3602 union wait status;
3603#define status_i (status.w_status)
3604#else
3605 int status;
3606#define status_i status
3607#endif
3608 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003609
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003610 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003611 {
3612 return NULL;
3613 }
3614
3615 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003616#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003617}
3618#endif /* WIFEXITED */
3619
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003620#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003621static char posix_WEXITSTATUS__doc__[] =
3622"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003623Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003624
3625static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003626posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003627{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003628#ifdef UNION_WAIT
3629 union wait status;
3630#define status_i (status.w_status)
3631#else
3632 int status;
3633#define status_i status
3634#endif
3635 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003636
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003637 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003638 {
3639 return NULL;
3640 }
3641
3642 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003643#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003644}
3645#endif /* WEXITSTATUS */
3646
3647#ifdef WTERMSIG
3648static char posix_WTERMSIG__doc__[] =
3649"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003650Return the signal that terminated the process that provided the 'status'\n\
3651value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003652
3653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003654posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003655{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003656#ifdef UNION_WAIT
3657 union wait status;
3658#define status_i (status.w_status)
3659#else
3660 int status;
3661#define status_i status
3662#endif
3663 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003664
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003665 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003666 {
3667 return NULL;
3668 }
3669
3670 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003671#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003672}
3673#endif /* WTERMSIG */
3674
3675#ifdef WSTOPSIG
3676static char posix_WSTOPSIG__doc__[] =
3677"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003678Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003679
3680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003681posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003682{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003683#ifdef UNION_WAIT
3684 union wait status;
3685#define status_i (status.w_status)
3686#else
3687 int status;
3688#define status_i status
3689#endif
3690 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003691
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003692 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003693 {
3694 return NULL;
3695 }
3696
3697 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003698#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003699}
3700#endif /* WSTOPSIG */
3701
3702#endif /* HAVE_SYS_WAIT_H */
3703
3704
Guido van Rossum94f6f721999-01-06 18:42:14 +00003705#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003706#ifdef _SCO_DS
3707/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3708 needed definitions in sys/statvfs.h */
3709#define _SVID3
3710#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003711#include <sys/statvfs.h>
3712
3713static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003714"fstatvfs(fd) -> \n\
3715 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003716Perform an fstatvfs system call on the given fd.";
3717
3718static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003719posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003720{
3721 int fd, res;
3722 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003723 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003724 return NULL;
3725 Py_BEGIN_ALLOW_THREADS
3726 res = fstatvfs(fd, &st);
3727 Py_END_ALLOW_THREADS
3728 if (res != 0)
3729 return posix_error();
3730#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003731 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003732 (long) st.f_bsize,
3733 (long) st.f_frsize,
3734 (long) st.f_blocks,
3735 (long) st.f_bfree,
3736 (long) st.f_bavail,
3737 (long) st.f_files,
3738 (long) st.f_ffree,
3739 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003740 (long) st.f_flag,
3741 (long) st.f_namemax);
3742#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003743 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003744 (long) st.f_bsize,
3745 (long) st.f_frsize,
3746 (LONG_LONG) st.f_blocks,
3747 (LONG_LONG) st.f_bfree,
3748 (LONG_LONG) st.f_bavail,
3749 (LONG_LONG) st.f_files,
3750 (LONG_LONG) st.f_ffree,
3751 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003752 (long) st.f_flag,
3753 (long) st.f_namemax);
3754#endif
3755}
3756#endif /* HAVE_FSTATVFS */
3757
3758
3759#if defined(HAVE_STATVFS)
3760#include <sys/statvfs.h>
3761
3762static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003763"statvfs(path) -> \n\
3764 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003765Perform a statvfs system call on the given path.";
3766
3767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003768posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003769{
3770 char *path;
3771 int res;
3772 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003773 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003774 return NULL;
3775 Py_BEGIN_ALLOW_THREADS
3776 res = statvfs(path, &st);
3777 Py_END_ALLOW_THREADS
3778 if (res != 0)
3779 return posix_error_with_filename(path);
3780#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003781 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003782 (long) st.f_bsize,
3783 (long) st.f_frsize,
3784 (long) st.f_blocks,
3785 (long) st.f_bfree,
3786 (long) st.f_bavail,
3787 (long) st.f_files,
3788 (long) st.f_ffree,
3789 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003790 (long) st.f_flag,
3791 (long) st.f_namemax);
3792#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003793 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003794 (long) st.f_bsize,
3795 (long) st.f_frsize,
3796 (LONG_LONG) st.f_blocks,
3797 (LONG_LONG) st.f_bfree,
3798 (LONG_LONG) st.f_bavail,
3799 (LONG_LONG) st.f_files,
3800 (LONG_LONG) st.f_ffree,
3801 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003802 (long) st.f_flag,
3803 (long) st.f_namemax);
3804#endif
3805}
3806#endif /* HAVE_STATVFS */
3807
3808
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003809#ifdef HAVE_TEMPNAM
3810static char posix_tempnam__doc__[] = "\
3811tempnam([dir[, prefix]]) -> string\n\
3812Return a unique name for a temporary file.\n\
3813The directory and a short may be specified as strings; they may be omitted\n\
3814or None if not needed.";
3815
3816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003817posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003818{
3819 PyObject *result = NULL;
3820 char *dir = NULL;
3821 char *pfx = NULL;
3822 char *name;
3823
3824 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
3825 return NULL;
3826 name = tempnam(dir, pfx);
3827 if (name == NULL)
3828 return PyErr_NoMemory();
3829 result = PyString_FromString(name);
3830 free(name);
3831 return result;
3832}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003833#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003834
3835
3836#ifdef HAVE_TMPFILE
3837static char posix_tmpfile__doc__[] = "\
3838tmpfile() -> file object\n\
3839Create a temporary file with no directory entries.";
3840
3841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003842posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003843{
3844 FILE *fp;
3845
3846 if (!PyArg_ParseTuple(args, ":tmpfile"))
3847 return NULL;
3848 fp = tmpfile();
3849 if (fp == NULL)
3850 return posix_error();
3851 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
3852}
3853#endif
3854
3855
3856#ifdef HAVE_TMPNAM
3857static char posix_tmpnam__doc__[] = "\
3858tmpnam() -> string\n\
3859Return a unique name for a temporary file.";
3860
3861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003862posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003863{
3864 char buffer[L_tmpnam];
3865 char *name;
3866
3867 if (!PyArg_ParseTuple(args, ":tmpnam"))
3868 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00003869#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003870 name = tmpnam_r(buffer);
3871#else
3872 name = tmpnam(buffer);
3873#endif
3874 if (name == NULL) {
3875 PyErr_SetObject(PyExc_OSError,
3876 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00003877#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003878 "unexpected NULL from tmpnam_r"
3879#else
3880 "unexpected NULL from tmpnam"
3881#endif
3882 ));
3883 return NULL;
3884 }
3885 return PyString_FromString(buffer);
3886}
3887#endif
3888
3889
Fred Drakec9680921999-12-13 16:37:25 +00003890/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
3891 * It maps strings representing configuration variable names to
3892 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00003893 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00003894 * rarely-used constants. There are three separate tables that use
3895 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00003896 *
3897 * This code is always included, even if none of the interfaces that
3898 * need it are included. The #if hackery needed to avoid it would be
3899 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00003900 */
3901struct constdef {
3902 char *name;
3903 long value;
3904};
3905
Fred Drake12c6e2d1999-12-14 21:25:03 +00003906static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003907conv_confname(PyObject *arg, int *valuep, struct constdef *table,
3908 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003909{
3910 if (PyInt_Check(arg)) {
3911 *valuep = PyInt_AS_LONG(arg);
3912 return 1;
3913 }
3914 if (PyString_Check(arg)) {
3915 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00003916 size_t lo = 0;
3917 size_t mid;
3918 size_t hi = tablesize;
3919 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003920 char *confname = PyString_AS_STRING(arg);
3921 while (lo < hi) {
3922 mid = (lo + hi) / 2;
3923 cmp = strcmp(confname, table[mid].name);
3924 if (cmp < 0)
3925 hi = mid;
3926 else if (cmp > 0)
3927 lo = mid + 1;
3928 else {
3929 *valuep = table[mid].value;
3930 return 1;
3931 }
3932 }
3933 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
3934 }
3935 else
3936 PyErr_SetString(PyExc_TypeError,
3937 "configuration names must be strings or integers");
3938 return 0;
3939}
3940
3941
3942#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
3943static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00003944#ifdef _PC_ABI_AIO_XFER_MAX
3945 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
3946#endif
3947#ifdef _PC_ABI_ASYNC_IO
3948 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
3949#endif
Fred Drakec9680921999-12-13 16:37:25 +00003950#ifdef _PC_ASYNC_IO
3951 {"PC_ASYNC_IO", _PC_ASYNC_IO},
3952#endif
3953#ifdef _PC_CHOWN_RESTRICTED
3954 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
3955#endif
3956#ifdef _PC_FILESIZEBITS
3957 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
3958#endif
3959#ifdef _PC_LAST
3960 {"PC_LAST", _PC_LAST},
3961#endif
3962#ifdef _PC_LINK_MAX
3963 {"PC_LINK_MAX", _PC_LINK_MAX},
3964#endif
3965#ifdef _PC_MAX_CANON
3966 {"PC_MAX_CANON", _PC_MAX_CANON},
3967#endif
3968#ifdef _PC_MAX_INPUT
3969 {"PC_MAX_INPUT", _PC_MAX_INPUT},
3970#endif
3971#ifdef _PC_NAME_MAX
3972 {"PC_NAME_MAX", _PC_NAME_MAX},
3973#endif
3974#ifdef _PC_NO_TRUNC
3975 {"PC_NO_TRUNC", _PC_NO_TRUNC},
3976#endif
3977#ifdef _PC_PATH_MAX
3978 {"PC_PATH_MAX", _PC_PATH_MAX},
3979#endif
3980#ifdef _PC_PIPE_BUF
3981 {"PC_PIPE_BUF", _PC_PIPE_BUF},
3982#endif
3983#ifdef _PC_PRIO_IO
3984 {"PC_PRIO_IO", _PC_PRIO_IO},
3985#endif
3986#ifdef _PC_SOCK_MAXBUF
3987 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
3988#endif
3989#ifdef _PC_SYNC_IO
3990 {"PC_SYNC_IO", _PC_SYNC_IO},
3991#endif
3992#ifdef _PC_VDISABLE
3993 {"PC_VDISABLE", _PC_VDISABLE},
3994#endif
3995};
3996
Fred Drakec9680921999-12-13 16:37:25 +00003997static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003998conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00003999{
4000 return conv_confname(arg, valuep, posix_constants_pathconf,
4001 sizeof(posix_constants_pathconf)
4002 / sizeof(struct constdef));
4003}
4004#endif
4005
4006#ifdef HAVE_FPATHCONF
4007static char posix_fpathconf__doc__[] = "\
4008fpathconf(fd, name) -> integer\n\
4009Return the configuration limit name for the file descriptor fd.\n\
4010If there is no limit, return -1.";
4011
4012static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004013posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004014{
4015 PyObject *result = NULL;
4016 int name, fd;
4017
Fred Drake12c6e2d1999-12-14 21:25:03 +00004018 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4019 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004020 long limit;
4021
4022 errno = 0;
4023 limit = fpathconf(fd, name);
4024 if (limit == -1 && errno != 0)
4025 posix_error();
4026 else
4027 result = PyInt_FromLong(limit);
4028 }
4029 return result;
4030}
4031#endif
4032
4033
4034#ifdef HAVE_PATHCONF
4035static char posix_pathconf__doc__[] = "\
4036pathconf(path, name) -> integer\n\
4037Return the configuration limit name for the file or directory path.\n\
4038If there is no limit, return -1.";
4039
4040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004041posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004042{
4043 PyObject *result = NULL;
4044 int name;
4045 char *path;
4046
4047 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4048 conv_path_confname, &name)) {
4049 long limit;
4050
4051 errno = 0;
4052 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004053 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004054 if (errno == EINVAL)
4055 /* could be a path or name problem */
4056 posix_error();
4057 else
4058 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004059 }
Fred Drakec9680921999-12-13 16:37:25 +00004060 else
4061 result = PyInt_FromLong(limit);
4062 }
4063 return result;
4064}
4065#endif
4066
4067#ifdef HAVE_CONFSTR
4068static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004069#ifdef _CS_ARCHITECTURE
4070 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4071#endif
4072#ifdef _CS_HOSTNAME
4073 {"CS_HOSTNAME", _CS_HOSTNAME},
4074#endif
4075#ifdef _CS_HW_PROVIDER
4076 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4077#endif
4078#ifdef _CS_HW_SERIAL
4079 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4080#endif
4081#ifdef _CS_INITTAB_NAME
4082 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4083#endif
Fred Drakec9680921999-12-13 16:37:25 +00004084#ifdef _CS_LFS64_CFLAGS
4085 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4086#endif
4087#ifdef _CS_LFS64_LDFLAGS
4088 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4089#endif
4090#ifdef _CS_LFS64_LIBS
4091 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4092#endif
4093#ifdef _CS_LFS64_LINTFLAGS
4094 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4095#endif
4096#ifdef _CS_LFS_CFLAGS
4097 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4098#endif
4099#ifdef _CS_LFS_LDFLAGS
4100 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4101#endif
4102#ifdef _CS_LFS_LIBS
4103 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4104#endif
4105#ifdef _CS_LFS_LINTFLAGS
4106 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4107#endif
Fred Draked86ed291999-12-15 15:34:33 +00004108#ifdef _CS_MACHINE
4109 {"CS_MACHINE", _CS_MACHINE},
4110#endif
Fred Drakec9680921999-12-13 16:37:25 +00004111#ifdef _CS_PATH
4112 {"CS_PATH", _CS_PATH},
4113#endif
Fred Draked86ed291999-12-15 15:34:33 +00004114#ifdef _CS_RELEASE
4115 {"CS_RELEASE", _CS_RELEASE},
4116#endif
4117#ifdef _CS_SRPC_DOMAIN
4118 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4119#endif
4120#ifdef _CS_SYSNAME
4121 {"CS_SYSNAME", _CS_SYSNAME},
4122#endif
4123#ifdef _CS_VERSION
4124 {"CS_VERSION", _CS_VERSION},
4125#endif
Fred Drakec9680921999-12-13 16:37:25 +00004126#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4127 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4128#endif
4129#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4130 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4131#endif
4132#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4133 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4134#endif
4135#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4136 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4137#endif
4138#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4139 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4140#endif
4141#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4142 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4143#endif
4144#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4145 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4146#endif
4147#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4148 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4149#endif
4150#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4151 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4152#endif
4153#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4154 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4155#endif
4156#ifdef _CS_XBS5_LP64_OFF64_LIBS
4157 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4158#endif
4159#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4160 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4161#endif
4162#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4163 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4164#endif
4165#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4166 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4167#endif
4168#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4169 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4170#endif
4171#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4172 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4173#endif
Fred Draked86ed291999-12-15 15:34:33 +00004174#ifdef _MIPS_CS_AVAIL_PROCESSORS
4175 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4176#endif
4177#ifdef _MIPS_CS_BASE
4178 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4179#endif
4180#ifdef _MIPS_CS_HOSTID
4181 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4182#endif
4183#ifdef _MIPS_CS_HW_NAME
4184 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4185#endif
4186#ifdef _MIPS_CS_NUM_PROCESSORS
4187 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4188#endif
4189#ifdef _MIPS_CS_OSREL_MAJ
4190 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4191#endif
4192#ifdef _MIPS_CS_OSREL_MIN
4193 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4194#endif
4195#ifdef _MIPS_CS_OSREL_PATCH
4196 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4197#endif
4198#ifdef _MIPS_CS_OS_NAME
4199 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4200#endif
4201#ifdef _MIPS_CS_OS_PROVIDER
4202 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4203#endif
4204#ifdef _MIPS_CS_PROCESSORS
4205 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4206#endif
4207#ifdef _MIPS_CS_SERIAL
4208 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4209#endif
4210#ifdef _MIPS_CS_VENDOR
4211 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4212#endif
Fred Drakec9680921999-12-13 16:37:25 +00004213};
4214
4215static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004216conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004217{
4218 return conv_confname(arg, valuep, posix_constants_confstr,
4219 sizeof(posix_constants_confstr)
4220 / sizeof(struct constdef));
4221}
4222
4223static char posix_confstr__doc__[] = "\
4224confstr(name) -> string\n\
4225Return a string-valued system configuration variable.";
4226
4227static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004228posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004229{
4230 PyObject *result = NULL;
4231 int name;
4232 char buffer[64];
4233
4234 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4235 int len = confstr(name, buffer, sizeof(buffer));
4236
Fred Drakec9680921999-12-13 16:37:25 +00004237 errno = 0;
4238 if (len == 0) {
4239 if (errno != 0)
4240 posix_error();
4241 else
4242 result = PyString_FromString("");
4243 }
4244 else {
4245 if (len >= sizeof(buffer)) {
4246 result = PyString_FromStringAndSize(NULL, len);
4247 if (result != NULL)
4248 confstr(name, PyString_AS_STRING(result), len+1);
4249 }
4250 else
4251 result = PyString_FromString(buffer);
4252 }
4253 }
4254 return result;
4255}
4256#endif
4257
4258
4259#ifdef HAVE_SYSCONF
4260static struct constdef posix_constants_sysconf[] = {
4261#ifdef _SC_2_CHAR_TERM
4262 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4263#endif
4264#ifdef _SC_2_C_BIND
4265 {"SC_2_C_BIND", _SC_2_C_BIND},
4266#endif
4267#ifdef _SC_2_C_DEV
4268 {"SC_2_C_DEV", _SC_2_C_DEV},
4269#endif
4270#ifdef _SC_2_C_VERSION
4271 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4272#endif
4273#ifdef _SC_2_FORT_DEV
4274 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4275#endif
4276#ifdef _SC_2_FORT_RUN
4277 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4278#endif
4279#ifdef _SC_2_LOCALEDEF
4280 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4281#endif
4282#ifdef _SC_2_SW_DEV
4283 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4284#endif
4285#ifdef _SC_2_UPE
4286 {"SC_2_UPE", _SC_2_UPE},
4287#endif
4288#ifdef _SC_2_VERSION
4289 {"SC_2_VERSION", _SC_2_VERSION},
4290#endif
Fred Draked86ed291999-12-15 15:34:33 +00004291#ifdef _SC_ABI_ASYNCHRONOUS_IO
4292 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4293#endif
4294#ifdef _SC_ACL
4295 {"SC_ACL", _SC_ACL},
4296#endif
Fred Drakec9680921999-12-13 16:37:25 +00004297#ifdef _SC_AIO_LISTIO_MAX
4298 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4299#endif
Fred Drakec9680921999-12-13 16:37:25 +00004300#ifdef _SC_AIO_MAX
4301 {"SC_AIO_MAX", _SC_AIO_MAX},
4302#endif
4303#ifdef _SC_AIO_PRIO_DELTA_MAX
4304 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4305#endif
4306#ifdef _SC_ARG_MAX
4307 {"SC_ARG_MAX", _SC_ARG_MAX},
4308#endif
4309#ifdef _SC_ASYNCHRONOUS_IO
4310 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4311#endif
4312#ifdef _SC_ATEXIT_MAX
4313 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4314#endif
Fred Draked86ed291999-12-15 15:34:33 +00004315#ifdef _SC_AUDIT
4316 {"SC_AUDIT", _SC_AUDIT},
4317#endif
Fred Drakec9680921999-12-13 16:37:25 +00004318#ifdef _SC_AVPHYS_PAGES
4319 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4320#endif
4321#ifdef _SC_BC_BASE_MAX
4322 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4323#endif
4324#ifdef _SC_BC_DIM_MAX
4325 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4326#endif
4327#ifdef _SC_BC_SCALE_MAX
4328 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4329#endif
4330#ifdef _SC_BC_STRING_MAX
4331 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4332#endif
Fred Draked86ed291999-12-15 15:34:33 +00004333#ifdef _SC_CAP
4334 {"SC_CAP", _SC_CAP},
4335#endif
Fred Drakec9680921999-12-13 16:37:25 +00004336#ifdef _SC_CHARCLASS_NAME_MAX
4337 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4338#endif
4339#ifdef _SC_CHAR_BIT
4340 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4341#endif
4342#ifdef _SC_CHAR_MAX
4343 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4344#endif
4345#ifdef _SC_CHAR_MIN
4346 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4347#endif
4348#ifdef _SC_CHILD_MAX
4349 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4350#endif
4351#ifdef _SC_CLK_TCK
4352 {"SC_CLK_TCK", _SC_CLK_TCK},
4353#endif
4354#ifdef _SC_COHER_BLKSZ
4355 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4356#endif
4357#ifdef _SC_COLL_WEIGHTS_MAX
4358 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4359#endif
4360#ifdef _SC_DCACHE_ASSOC
4361 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4362#endif
4363#ifdef _SC_DCACHE_BLKSZ
4364 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4365#endif
4366#ifdef _SC_DCACHE_LINESZ
4367 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4368#endif
4369#ifdef _SC_DCACHE_SZ
4370 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4371#endif
4372#ifdef _SC_DCACHE_TBLKSZ
4373 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4374#endif
4375#ifdef _SC_DELAYTIMER_MAX
4376 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4377#endif
4378#ifdef _SC_EQUIV_CLASS_MAX
4379 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4380#endif
4381#ifdef _SC_EXPR_NEST_MAX
4382 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4383#endif
4384#ifdef _SC_FSYNC
4385 {"SC_FSYNC", _SC_FSYNC},
4386#endif
4387#ifdef _SC_GETGR_R_SIZE_MAX
4388 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4389#endif
4390#ifdef _SC_GETPW_R_SIZE_MAX
4391 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4392#endif
4393#ifdef _SC_ICACHE_ASSOC
4394 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4395#endif
4396#ifdef _SC_ICACHE_BLKSZ
4397 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4398#endif
4399#ifdef _SC_ICACHE_LINESZ
4400 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4401#endif
4402#ifdef _SC_ICACHE_SZ
4403 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4404#endif
Fred Draked86ed291999-12-15 15:34:33 +00004405#ifdef _SC_INF
4406 {"SC_INF", _SC_INF},
4407#endif
Fred Drakec9680921999-12-13 16:37:25 +00004408#ifdef _SC_INT_MAX
4409 {"SC_INT_MAX", _SC_INT_MAX},
4410#endif
4411#ifdef _SC_INT_MIN
4412 {"SC_INT_MIN", _SC_INT_MIN},
4413#endif
4414#ifdef _SC_IOV_MAX
4415 {"SC_IOV_MAX", _SC_IOV_MAX},
4416#endif
Fred Draked86ed291999-12-15 15:34:33 +00004417#ifdef _SC_IP_SECOPTS
4418 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4419#endif
Fred Drakec9680921999-12-13 16:37:25 +00004420#ifdef _SC_JOB_CONTROL
4421 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4422#endif
Fred Draked86ed291999-12-15 15:34:33 +00004423#ifdef _SC_KERN_POINTERS
4424 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4425#endif
4426#ifdef _SC_KERN_SIM
4427 {"SC_KERN_SIM", _SC_KERN_SIM},
4428#endif
Fred Drakec9680921999-12-13 16:37:25 +00004429#ifdef _SC_LINE_MAX
4430 {"SC_LINE_MAX", _SC_LINE_MAX},
4431#endif
4432#ifdef _SC_LOGIN_NAME_MAX
4433 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4434#endif
4435#ifdef _SC_LOGNAME_MAX
4436 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4437#endif
4438#ifdef _SC_LONG_BIT
4439 {"SC_LONG_BIT", _SC_LONG_BIT},
4440#endif
Fred Draked86ed291999-12-15 15:34:33 +00004441#ifdef _SC_MAC
4442 {"SC_MAC", _SC_MAC},
4443#endif
Fred Drakec9680921999-12-13 16:37:25 +00004444#ifdef _SC_MAPPED_FILES
4445 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4446#endif
4447#ifdef _SC_MAXPID
4448 {"SC_MAXPID", _SC_MAXPID},
4449#endif
4450#ifdef _SC_MB_LEN_MAX
4451 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4452#endif
4453#ifdef _SC_MEMLOCK
4454 {"SC_MEMLOCK", _SC_MEMLOCK},
4455#endif
4456#ifdef _SC_MEMLOCK_RANGE
4457 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4458#endif
4459#ifdef _SC_MEMORY_PROTECTION
4460 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4461#endif
4462#ifdef _SC_MESSAGE_PASSING
4463 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4464#endif
Fred Draked86ed291999-12-15 15:34:33 +00004465#ifdef _SC_MMAP_FIXED_ALIGNMENT
4466 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4467#endif
Fred Drakec9680921999-12-13 16:37:25 +00004468#ifdef _SC_MQ_OPEN_MAX
4469 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4470#endif
4471#ifdef _SC_MQ_PRIO_MAX
4472 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4473#endif
Fred Draked86ed291999-12-15 15:34:33 +00004474#ifdef _SC_NACLS_MAX
4475 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4476#endif
Fred Drakec9680921999-12-13 16:37:25 +00004477#ifdef _SC_NGROUPS_MAX
4478 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4479#endif
4480#ifdef _SC_NL_ARGMAX
4481 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4482#endif
4483#ifdef _SC_NL_LANGMAX
4484 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4485#endif
4486#ifdef _SC_NL_MSGMAX
4487 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4488#endif
4489#ifdef _SC_NL_NMAX
4490 {"SC_NL_NMAX", _SC_NL_NMAX},
4491#endif
4492#ifdef _SC_NL_SETMAX
4493 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4494#endif
4495#ifdef _SC_NL_TEXTMAX
4496 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4497#endif
4498#ifdef _SC_NPROCESSORS_CONF
4499 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4500#endif
4501#ifdef _SC_NPROCESSORS_ONLN
4502 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4503#endif
Fred Draked86ed291999-12-15 15:34:33 +00004504#ifdef _SC_NPROC_CONF
4505 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4506#endif
4507#ifdef _SC_NPROC_ONLN
4508 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4509#endif
Fred Drakec9680921999-12-13 16:37:25 +00004510#ifdef _SC_NZERO
4511 {"SC_NZERO", _SC_NZERO},
4512#endif
4513#ifdef _SC_OPEN_MAX
4514 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4515#endif
4516#ifdef _SC_PAGESIZE
4517 {"SC_PAGESIZE", _SC_PAGESIZE},
4518#endif
4519#ifdef _SC_PAGE_SIZE
4520 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4521#endif
4522#ifdef _SC_PASS_MAX
4523 {"SC_PASS_MAX", _SC_PASS_MAX},
4524#endif
4525#ifdef _SC_PHYS_PAGES
4526 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4527#endif
4528#ifdef _SC_PII
4529 {"SC_PII", _SC_PII},
4530#endif
4531#ifdef _SC_PII_INTERNET
4532 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4533#endif
4534#ifdef _SC_PII_INTERNET_DGRAM
4535 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4536#endif
4537#ifdef _SC_PII_INTERNET_STREAM
4538 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4539#endif
4540#ifdef _SC_PII_OSI
4541 {"SC_PII_OSI", _SC_PII_OSI},
4542#endif
4543#ifdef _SC_PII_OSI_CLTS
4544 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4545#endif
4546#ifdef _SC_PII_OSI_COTS
4547 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4548#endif
4549#ifdef _SC_PII_OSI_M
4550 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4551#endif
4552#ifdef _SC_PII_SOCKET
4553 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4554#endif
4555#ifdef _SC_PII_XTI
4556 {"SC_PII_XTI", _SC_PII_XTI},
4557#endif
4558#ifdef _SC_POLL
4559 {"SC_POLL", _SC_POLL},
4560#endif
4561#ifdef _SC_PRIORITIZED_IO
4562 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4563#endif
4564#ifdef _SC_PRIORITY_SCHEDULING
4565 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4566#endif
4567#ifdef _SC_REALTIME_SIGNALS
4568 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4569#endif
4570#ifdef _SC_RE_DUP_MAX
4571 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4572#endif
4573#ifdef _SC_RTSIG_MAX
4574 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4575#endif
4576#ifdef _SC_SAVED_IDS
4577 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4578#endif
4579#ifdef _SC_SCHAR_MAX
4580 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4581#endif
4582#ifdef _SC_SCHAR_MIN
4583 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4584#endif
4585#ifdef _SC_SELECT
4586 {"SC_SELECT", _SC_SELECT},
4587#endif
4588#ifdef _SC_SEMAPHORES
4589 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4590#endif
4591#ifdef _SC_SEM_NSEMS_MAX
4592 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4593#endif
4594#ifdef _SC_SEM_VALUE_MAX
4595 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4596#endif
4597#ifdef _SC_SHARED_MEMORY_OBJECTS
4598 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4599#endif
4600#ifdef _SC_SHRT_MAX
4601 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4602#endif
4603#ifdef _SC_SHRT_MIN
4604 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4605#endif
4606#ifdef _SC_SIGQUEUE_MAX
4607 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4608#endif
4609#ifdef _SC_SIGRT_MAX
4610 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4611#endif
4612#ifdef _SC_SIGRT_MIN
4613 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4614#endif
Fred Draked86ed291999-12-15 15:34:33 +00004615#ifdef _SC_SOFTPOWER
4616 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4617#endif
Fred Drakec9680921999-12-13 16:37:25 +00004618#ifdef _SC_SPLIT_CACHE
4619 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4620#endif
4621#ifdef _SC_SSIZE_MAX
4622 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4623#endif
4624#ifdef _SC_STACK_PROT
4625 {"SC_STACK_PROT", _SC_STACK_PROT},
4626#endif
4627#ifdef _SC_STREAM_MAX
4628 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4629#endif
4630#ifdef _SC_SYNCHRONIZED_IO
4631 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4632#endif
4633#ifdef _SC_THREADS
4634 {"SC_THREADS", _SC_THREADS},
4635#endif
4636#ifdef _SC_THREAD_ATTR_STACKADDR
4637 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4638#endif
4639#ifdef _SC_THREAD_ATTR_STACKSIZE
4640 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4641#endif
4642#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4643 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4644#endif
4645#ifdef _SC_THREAD_KEYS_MAX
4646 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4647#endif
4648#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4649 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4650#endif
4651#ifdef _SC_THREAD_PRIO_INHERIT
4652 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4653#endif
4654#ifdef _SC_THREAD_PRIO_PROTECT
4655 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4656#endif
4657#ifdef _SC_THREAD_PROCESS_SHARED
4658 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4659#endif
4660#ifdef _SC_THREAD_SAFE_FUNCTIONS
4661 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4662#endif
4663#ifdef _SC_THREAD_STACK_MIN
4664 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4665#endif
4666#ifdef _SC_THREAD_THREADS_MAX
4667 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4668#endif
4669#ifdef _SC_TIMERS
4670 {"SC_TIMERS", _SC_TIMERS},
4671#endif
4672#ifdef _SC_TIMER_MAX
4673 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4674#endif
4675#ifdef _SC_TTY_NAME_MAX
4676 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4677#endif
4678#ifdef _SC_TZNAME_MAX
4679 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4680#endif
4681#ifdef _SC_T_IOV_MAX
4682 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4683#endif
4684#ifdef _SC_UCHAR_MAX
4685 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4686#endif
4687#ifdef _SC_UINT_MAX
4688 {"SC_UINT_MAX", _SC_UINT_MAX},
4689#endif
4690#ifdef _SC_UIO_MAXIOV
4691 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4692#endif
4693#ifdef _SC_ULONG_MAX
4694 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4695#endif
4696#ifdef _SC_USHRT_MAX
4697 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4698#endif
4699#ifdef _SC_VERSION
4700 {"SC_VERSION", _SC_VERSION},
4701#endif
4702#ifdef _SC_WORD_BIT
4703 {"SC_WORD_BIT", _SC_WORD_BIT},
4704#endif
4705#ifdef _SC_XBS5_ILP32_OFF32
4706 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4707#endif
4708#ifdef _SC_XBS5_ILP32_OFFBIG
4709 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4710#endif
4711#ifdef _SC_XBS5_LP64_OFF64
4712 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4713#endif
4714#ifdef _SC_XBS5_LPBIG_OFFBIG
4715 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
4716#endif
4717#ifdef _SC_XOPEN_CRYPT
4718 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
4719#endif
4720#ifdef _SC_XOPEN_ENH_I18N
4721 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
4722#endif
4723#ifdef _SC_XOPEN_LEGACY
4724 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
4725#endif
4726#ifdef _SC_XOPEN_REALTIME
4727 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
4728#endif
4729#ifdef _SC_XOPEN_REALTIME_THREADS
4730 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
4731#endif
4732#ifdef _SC_XOPEN_SHM
4733 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
4734#endif
4735#ifdef _SC_XOPEN_UNIX
4736 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
4737#endif
4738#ifdef _SC_XOPEN_VERSION
4739 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
4740#endif
4741#ifdef _SC_XOPEN_XCU_VERSION
4742 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
4743#endif
4744#ifdef _SC_XOPEN_XPG2
4745 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
4746#endif
4747#ifdef _SC_XOPEN_XPG3
4748 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
4749#endif
4750#ifdef _SC_XOPEN_XPG4
4751 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
4752#endif
4753};
4754
4755static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004756conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004757{
4758 return conv_confname(arg, valuep, posix_constants_sysconf,
4759 sizeof(posix_constants_sysconf)
4760 / sizeof(struct constdef));
4761}
4762
4763static char posix_sysconf__doc__[] = "\
4764sysconf(name) -> integer\n\
4765Return an integer-valued system configuration variable.";
4766
4767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004768posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004769{
4770 PyObject *result = NULL;
4771 int name;
4772
4773 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
4774 int value;
4775
4776 errno = 0;
4777 value = sysconf(name);
4778 if (value == -1 && errno != 0)
4779 posix_error();
4780 else
4781 result = PyInt_FromLong(value);
4782 }
4783 return result;
4784}
4785#endif
4786
4787
Fred Drakebec628d1999-12-15 18:31:10 +00004788/* This code is used to ensure that the tables of configuration value names
4789 * are in sorted order as required by conv_confname(), and also to build the
4790 * the exported dictionaries that are used to publish information about the
4791 * names available on the host platform.
4792 *
4793 * Sorting the table at runtime ensures that the table is properly ordered
4794 * when used, even for platforms we're not able to test on. It also makes
4795 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00004796 */
Fred Drakebec628d1999-12-15 18:31:10 +00004797
4798static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004799cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00004800{
4801 const struct constdef *c1 =
4802 (const struct constdef *) v1;
4803 const struct constdef *c2 =
4804 (const struct constdef *) v2;
4805
4806 return strcmp(c1->name, c2->name);
4807}
4808
4809static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004810setup_confname_table(struct constdef *table, size_t tablesize,
4811 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004812{
Fred Drakebec628d1999-12-15 18:31:10 +00004813 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00004814 size_t i;
4815 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00004816
4817 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
4818 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00004819 if (d == NULL)
4820 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004821
Barry Warsaw3155db32000-04-13 15:20:40 +00004822 for (i=0; i < tablesize; ++i) {
4823 PyObject *o = PyInt_FromLong(table[i].value);
4824 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
4825 Py_XDECREF(o);
4826 Py_DECREF(d);
4827 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004828 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004829 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00004830 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004831 status = PyDict_SetItemString(moddict, tablename, d);
4832 Py_DECREF(d);
4833 return status;
Fred Draked86ed291999-12-15 15:34:33 +00004834}
4835
Fred Drakebec628d1999-12-15 18:31:10 +00004836/* Return -1 on failure, 0 on success. */
4837static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004838setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004839{
4840#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00004841 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00004842 sizeof(posix_constants_pathconf)
4843 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004844 "pathconf_names", moddict))
4845 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004846#endif
4847#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00004848 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00004849 sizeof(posix_constants_confstr)
4850 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004851 "confstr_names", moddict))
4852 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004853#endif
4854#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00004855 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00004856 sizeof(posix_constants_sysconf)
4857 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004858 "sysconf_names", moddict))
4859 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004860#endif
Fred Drakebec628d1999-12-15 18:31:10 +00004861 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00004862}
Fred Draked86ed291999-12-15 15:34:33 +00004863
4864
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004865static char posix_abort__doc__[] = "\
4866abort() -> does not return!\n\
4867Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
4868in the hardest way possible on the hosting operating system.";
4869
4870static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004871posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004872{
4873 if (!PyArg_ParseTuple(args, ":abort"))
4874 return NULL;
4875 abort();
4876 /*NOTREACHED*/
4877 Py_FatalError("abort() called from Python code didn't abort!");
4878 return NULL;
4879}
Fred Drakebec628d1999-12-15 18:31:10 +00004880
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004881
4882static PyMethodDef posix_methods[] = {
4883 {"access", posix_access, METH_VARARGS, posix_access__doc__},
4884#ifdef HAVE_TTYNAME
4885 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
4886#endif
4887 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
4888 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004889#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004890 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004891#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004892#ifdef HAVE_CTERMID
4893 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
4894#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00004895#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004896 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00004897#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004898#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004899 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004900#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004901 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
4902 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
4903 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004904#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004905 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004906#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004907#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004908 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004909#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004910 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
4911 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
4912 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004913#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004914 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004915#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004916#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004917 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004918#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004919 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004920#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004921 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004922#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004923 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
4924 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
4925 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004926#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004927 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004928#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004929 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004930#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004931 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
4932 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004933#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00004934#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004935 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
4936 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00004937#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004938#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004939 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004940#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004941#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004942 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00004943#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004944#ifdef HAVE_FORKPTY
4945 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
4946#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004947#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004948 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004949#endif /* HAVE_GETEGID */
4950#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004951 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004952#endif /* HAVE_GETEUID */
4953#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004954 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004955#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00004956#ifdef HAVE_GETGROUPS
4957 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
4958#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004959 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004960#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004961 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004962#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004963#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004964 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004965#endif /* HAVE_GETPPID */
4966#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004967 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004968#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004969#ifdef HAVE_GETLOGIN
4970 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
4971#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00004972#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004973 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004974#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00004975#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004976 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00004977#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004978#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004979 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004980#ifdef MS_WIN32
4981 {"popen2", win32_popen2, METH_VARARGS},
4982 {"popen3", win32_popen3, METH_VARARGS},
4983 {"popen4", win32_popen4, METH_VARARGS},
4984#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004985#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004986#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004987 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004988#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004989#ifdef HAVE_SETEUID
4990 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
4991#endif /* HAVE_SETEUID */
4992#ifdef HAVE_SETEGID
4993 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
4994#endif /* HAVE_SETEGID */
4995#ifdef HAVE_SETREUID
4996 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
4997#endif /* HAVE_SETREUID */
4998#ifdef HAVE_SETREGID
4999 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5000#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005001#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005002 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005003#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005004#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005005 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005006#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005007#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005008 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005009#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005010#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005011 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005012#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005013#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005014 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005015#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005016#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005017 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005018#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005019#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005020 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005021#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005022#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005023 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005024#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005025 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5026 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5027 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5028 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5029 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5030 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5031 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5032 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5033 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005034 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005035#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005036 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005037#endif
5038#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005039 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005040#endif
5041#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005042 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005043#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005044#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005045 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005046#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005047#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005048 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005049#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005050#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005051 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005052#endif
5053#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005054 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005055#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005056#ifdef HAVE_SYS_WAIT_H
5057#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005058 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005059#endif /* WIFSTOPPED */
5060#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005061 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005062#endif /* WIFSIGNALED */
5063#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005064 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005065#endif /* WIFEXITED */
5066#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005067 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005068#endif /* WEXITSTATUS */
5069#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005070 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005071#endif /* WTERMSIG */
5072#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005073 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005074#endif /* WSTOPSIG */
5075#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005076#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005077 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005078#endif
5079#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005080 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005081#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005082#ifdef HAVE_TMPNAM
5083 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5084#endif
5085#ifdef HAVE_TEMPNAM
5086 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5087#endif
5088#ifdef HAVE_TMPNAM
5089 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5090#endif
Fred Drakec9680921999-12-13 16:37:25 +00005091#ifdef HAVE_CONFSTR
5092 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5093#endif
5094#ifdef HAVE_SYSCONF
5095 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5096#endif
5097#ifdef HAVE_FPATHCONF
5098 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5099#endif
5100#ifdef HAVE_PATHCONF
5101 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5102#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005103 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005104 {NULL, NULL} /* Sentinel */
5105};
5106
5107
Barry Warsaw4a342091996-12-19 23:50:02 +00005108static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005109ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005110{
5111 PyObject* v = PyInt_FromLong(value);
5112 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5113 return -1; /* triggers fatal error */
5114
5115 Py_DECREF(v);
5116 return 0;
5117}
5118
Guido van Rossumd48f2521997-12-05 22:19:34 +00005119#if defined(PYOS_OS2)
5120/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5121static int insertvalues(PyObject *d)
5122{
5123 APIRET rc;
5124 ULONG values[QSV_MAX+1];
5125 PyObject *v;
5126 char *ver, tmp[10];
5127
5128 Py_BEGIN_ALLOW_THREADS
5129 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5130 Py_END_ALLOW_THREADS
5131
5132 if (rc != NO_ERROR) {
5133 os2_error(rc);
5134 return -1;
5135 }
5136
5137 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5138 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5139 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5140 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5141 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5142 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5143 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5144
5145 switch (values[QSV_VERSION_MINOR]) {
5146 case 0: ver = "2.00"; break;
5147 case 10: ver = "2.10"; break;
5148 case 11: ver = "2.11"; break;
5149 case 30: ver = "3.00"; break;
5150 case 40: ver = "4.00"; break;
5151 case 50: ver = "5.00"; break;
5152 default:
5153 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5154 values[QSV_VERSION_MINOR]);
5155 ver = &tmp[0];
5156 }
5157
5158 /* Add Indicator of the Version of the Operating System */
5159 v = PyString_FromString(ver);
5160 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5161 return -1;
5162 Py_DECREF(v);
5163
5164 /* Add Indicator of Which Drive was Used to Boot the System */
5165 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5166 tmp[1] = ':';
5167 tmp[2] = '\0';
5168
5169 v = PyString_FromString(tmp);
5170 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5171 return -1;
5172 Py_DECREF(v);
5173
5174 return 0;
5175}
5176#endif
5177
Barry Warsaw4a342091996-12-19 23:50:02 +00005178static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005179all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005180{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005181#ifdef F_OK
5182 if (ins(d, "F_OK", (long)F_OK)) return -1;
5183#endif
5184#ifdef R_OK
5185 if (ins(d, "R_OK", (long)R_OK)) return -1;
5186#endif
5187#ifdef W_OK
5188 if (ins(d, "W_OK", (long)W_OK)) return -1;
5189#endif
5190#ifdef X_OK
5191 if (ins(d, "X_OK", (long)X_OK)) return -1;
5192#endif
Fred Drakec9680921999-12-13 16:37:25 +00005193#ifdef NGROUPS_MAX
5194 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5195#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005196#ifdef TMP_MAX
5197 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5198#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005199#ifdef WNOHANG
5200 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5201#endif
5202#ifdef O_RDONLY
5203 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5204#endif
5205#ifdef O_WRONLY
5206 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5207#endif
5208#ifdef O_RDWR
5209 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5210#endif
5211#ifdef O_NDELAY
5212 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5213#endif
5214#ifdef O_NONBLOCK
5215 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5216#endif
5217#ifdef O_APPEND
5218 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5219#endif
5220#ifdef O_DSYNC
5221 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5222#endif
5223#ifdef O_RSYNC
5224 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5225#endif
5226#ifdef O_SYNC
5227 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5228#endif
5229#ifdef O_NOCTTY
5230 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5231#endif
5232#ifdef O_CREAT
5233 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5234#endif
5235#ifdef O_EXCL
5236 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5237#endif
5238#ifdef O_TRUNC
5239 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5240#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005241#ifdef O_BINARY
5242 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5243#endif
5244#ifdef O_TEXT
5245 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5246#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005247
Guido van Rossum246bc171999-02-01 23:54:31 +00005248#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005249 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5250 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5251 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5252 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5253 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005254#endif
5255
Guido van Rossumd48f2521997-12-05 22:19:34 +00005256#if defined(PYOS_OS2)
5257 if (insertvalues(d)) return -1;
5258#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005259 return 0;
5260}
5261
5262
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005263#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005264#define INITFUNC initnt
5265#define MODNAME "nt"
5266#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005267#if defined(PYOS_OS2)
5268#define INITFUNC initos2
5269#define MODNAME "os2"
5270#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005271#define INITFUNC initposix
5272#define MODNAME "posix"
5273#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005274#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005275
Guido van Rossum3886bb61998-12-04 18:50:17 +00005276DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005277INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005278{
Barry Warsaw53699e91996-12-10 23:23:01 +00005279 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005280
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005281 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005282 posix_methods,
5283 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005284 (PyObject *)NULL,
5285 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005286 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005287
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005288 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005289 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005290 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005291 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005292 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005293
Barry Warsaw4a342091996-12-19 23:50:02 +00005294 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005295 return;
5296
Fred Drakebec628d1999-12-15 18:31:10 +00005297 if (setup_confname_tables(d))
5298 return;
5299
Barry Warsawca74da41999-02-09 19:31:45 +00005300 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005301
Guido van Rossumb3d39562000-01-31 18:41:26 +00005302#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00005303 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005304#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005305}