blob: d87983710ac6d09ee0db7e5dd8a4658ab7d3a1bc [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 */
133extern int rename();
134extern int pclose();
135extern int lstat();
136extern int symlink();
Guido van Rossum8c67e4e1999-04-07 15:49:41 +0000137extern int fsync();
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 *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287convertenviron()
288{
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 *
347posix_error()
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
Barry Warsaw53699e91996-12-10 23:23:01 +0000498static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000499posix_strint(PyObject *args, char *format, int (*func)(const char *, int))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000501 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502 int i;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000503 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000504 if (!PyArg_ParseTuple(args, format, &path, &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000505 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000506 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000507 res = (*func)(path, i);
Barry Warsaw53699e91996-12-10 23:23:01 +0000508 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000509 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000510 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +0000511 Py_INCREF(Py_None);
512 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513}
514
Fred Drake699f3522000-06-29 21:12:41 +0000515
516/* pack a system stat C structure into the Python stat tuple
517 (used by posix_stat() and posix_fstat()) */
518static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000519_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000520{
521 PyObject *v = PyTuple_New(10);
522 if (v == NULL)
523 return NULL;
524
525 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
526#ifdef HAVE_LARGEFILE_SUPPORT
527 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
528#else
529 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
530#endif
531#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
532 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
533#else
534 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
535#endif
536 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
537 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
538 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
539#ifdef HAVE_LARGEFILE_SUPPORT
540 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
541#else
542 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
543#endif
544#if SIZEOF_TIME_T > SIZEOF_LONG
545 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
546 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
547 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
548#else
549 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
550 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
551 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
552#endif
553
554 if (PyErr_Occurred()) {
555 Py_DECREF(v);
556 return NULL;
557 }
558
559 return v;
560}
561
562
Barry Warsaw53699e91996-12-10 23:23:01 +0000563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000564posix_do_stat(PyObject *self, PyObject *args, char *format,
565 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000566{
Fred Drake699f3522000-06-29 21:12:41 +0000567 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000568 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000569 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000570
571#ifdef MS_WIN32
572 int pathlen;
573 char pathcopy[MAX_PATH];
574#endif /* MS_WIN32 */
575
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000576 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000577 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000578
579#ifdef MS_WIN32
580 pathlen = strlen(path);
581 /* the library call can blow up if the file name is too long! */
582 if (pathlen > MAX_PATH) {
583 errno = ENAMETOOLONG;
584 return posix_error();
585 }
586
587 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000588 /* exception for specific or current drive root */
589 if (!((pathlen == 1) ||
590 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000591 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000592 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000593 {
594 strncpy(pathcopy, path, pathlen);
595 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
596 path = pathcopy;
597 }
598 }
599#endif /* MS_WIN32 */
600
Barry Warsaw53699e91996-12-10 23:23:01 +0000601 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000602 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000603 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000604 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000605 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000606
607 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000608}
609
610
611/* POSIX methods */
612
Guido van Rossum94f6f721999-01-06 18:42:14 +0000613static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000614"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000615Test for access to a file.";
616
617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000618posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000619{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000620 char *path;
621 int mode;
622 int res;
623
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000624 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000625 return NULL;
626 Py_BEGIN_ALLOW_THREADS
627 res = access(path, mode);
628 Py_END_ALLOW_THREADS
629 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000630}
631
Guido van Rossumd371ff11999-01-25 16:12:23 +0000632#ifndef F_OK
633#define F_OK 0
634#endif
635#ifndef R_OK
636#define R_OK 4
637#endif
638#ifndef W_OK
639#define W_OK 2
640#endif
641#ifndef X_OK
642#define X_OK 1
643#endif
644
645#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000646static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000647"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000648Return the name of the terminal device connected to 'fd'.";
649
650static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000651posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000652{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000653 int id;
654 char *ret;
655
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000656 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000657 return NULL;
658
Guido van Rossum94f6f721999-01-06 18:42:14 +0000659 ret = ttyname(id);
660 if (ret == NULL)
661 return(posix_error());
662 return(PyString_FromString(ret));
663}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000664#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000665
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000666#ifdef HAVE_CTERMID
667static char posix_ctermid__doc__[] =
668"ctermid() -> String\n\
669Return the name of the controlling terminal for this process.";
670
671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000672posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000673{
674 char *ret;
675 char buffer[L_ctermid];
676
677 if (!PyArg_ParseTuple(args, ":ctermid"))
678 return NULL;
679
Greg Wardb48bc172000-03-01 21:51:56 +0000680#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000681 ret = ctermid_r(buffer);
682#else
683 ret = ctermid(buffer);
684#endif
685 if (ret == NULL)
686 return(posix_error());
687 return(PyString_FromString(buffer));
688}
689#endif
690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000691static char posix_chdir__doc__[] =
692"chdir(path) -> None\n\
693Change the current working directory to the specified path.";
694
Barry Warsaw53699e91996-12-10 23:23:01 +0000695static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000696posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000697{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000698 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000699}
700
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000701
702static char posix_chmod__doc__[] =
703"chmod(path, mode) -> None\n\
704Change the access permissions of a file.";
705
Barry Warsaw53699e91996-12-10 23:23:01 +0000706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000707posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000708{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000709 char *path;
710 int i;
711 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000712 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000713 return NULL;
714 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000715 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000716 Py_END_ALLOW_THREADS
717 if (res < 0)
718 return posix_error_with_filename(path);
719 Py_INCREF(Py_None);
720 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000721}
722
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000723
Guido van Rossum21142a01999-01-08 21:05:37 +0000724#ifdef HAVE_FSYNC
725static char posix_fsync__doc__[] =
726"fsync(fildes) -> None\n\
727force write of file with filedescriptor to disk.";
728
729static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000730posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000731{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000732 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000733}
734#endif /* HAVE_FSYNC */
735
736#ifdef HAVE_FDATASYNC
737static char posix_fdatasync__doc__[] =
738"fdatasync(fildes) -> None\n\
739force write of file with filedescriptor to disk.\n\
740 does not force update of metadata.";
741
Guido van Rossum5d00b6d1999-01-08 21:28:05 +0000742extern int fdatasync(int); /* Prototype just in case */
743
Guido van Rossum21142a01999-01-08 21:05:37 +0000744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000745posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000746{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000747 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000748}
749#endif /* HAVE_FDATASYNC */
750
751
Fredrik Lundh10723342000-07-10 16:38:09 +0000752#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000753static char posix_chown__doc__[] =
754"chown(path, uid, gid) -> None\n\
755Change the owner and group id of path to the numeric uid and gid.";
756
Barry Warsaw53699e91996-12-10 23:23:01 +0000757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000758posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000759{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000760 char *path;
761 int uid, gid;
762 int res;
763 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
764 return NULL;
765 Py_BEGIN_ALLOW_THREADS
766 res = chown(path, (uid_t) uid, (gid_t) gid);
767 Py_END_ALLOW_THREADS
768 if (res < 0)
769 return posix_error_with_filename(path);
770 Py_INCREF(Py_None);
771 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000772}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000773#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000775
Guido van Rossum36bc6801995-06-14 22:54:23 +0000776#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000777static char posix_getcwd__doc__[] =
778"getcwd() -> path\n\
779Return a string representing the current working directory.";
780
Barry Warsaw53699e91996-12-10 23:23:01 +0000781static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000782posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000783{
784 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000785 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000786 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000788 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000789 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000790 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000791 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000792 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000793 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000794}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000795#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000796
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000797
Guido van Rossumb6775db1994-08-01 11:34:53 +0000798#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000799static char posix_link__doc__[] =
800"link(src, dst) -> None\n\
801Create a hard link to a file.";
802
Barry Warsaw53699e91996-12-10 23:23:01 +0000803static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000804posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000806 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000807}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000808#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000809
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000810
811static char posix_listdir__doc__[] =
812"listdir(path) -> list_of_strings\n\
813Return a list containing the names of the entries in the directory.\n\
814\n\
815 path: path of directory to list\n\
816\n\
817The list is in arbitrary order. It does not include the special\n\
818entries '.' and '..' even if they are present in the directory.";
819
Barry Warsaw53699e91996-12-10 23:23:01 +0000820static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000821posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000822{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000823 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000824 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000825#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000826
Guido van Rossumb6775db1994-08-01 11:34:53 +0000827 char *name;
828 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000829 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000830 HANDLE hFindFile;
831 WIN32_FIND_DATA FileData;
832 char namebuf[MAX_PATH+5];
833
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000834 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000835 return NULL;
836 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000837 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000838 return NULL;
839 }
840 strcpy(namebuf, name);
841 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
842 namebuf[len++] = '/';
843 strcpy(namebuf + len, "*.*");
844
Barry Warsaw53699e91996-12-10 23:23:01 +0000845 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000846 return NULL;
847
848 hFindFile = FindFirstFile(namebuf, &FileData);
849 if (hFindFile == INVALID_HANDLE_VALUE) {
850 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000851 if (errno == ERROR_FILE_NOT_FOUND)
852 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000853 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000854 }
855 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000856 if (FileData.cFileName[0] == '.' &&
857 (FileData.cFileName[1] == '\0' ||
858 FileData.cFileName[1] == '.' &&
859 FileData.cFileName[2] == '\0'))
860 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000861 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000862 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000863 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000864 d = NULL;
865 break;
866 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000867 if (PyList_Append(d, v) != 0) {
868 Py_DECREF(v);
869 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000870 d = NULL;
871 break;
872 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000873 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000874 } while (FindNextFile(hFindFile, &FileData) == TRUE);
875
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000876 if (FindClose(hFindFile) == FALSE)
877 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000878
879 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000880
Guido van Rossum8d665e61996-06-26 18:22:49 +0000881#else /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000882#ifdef _MSC_VER /* 16-bit Windows */
883
884#ifndef MAX_PATH
885#define MAX_PATH 250
886#endif
887 char *name, *pt;
888 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000889 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000890 char namebuf[MAX_PATH+5];
891 struct _find_t ep;
892
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000893 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000894 return NULL;
895 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000896 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000897 return NULL;
898 }
899 strcpy(namebuf, name);
900 for (pt = namebuf; *pt; pt++)
901 if (*pt == '/')
902 *pt = '\\';
903 if (namebuf[len-1] != '\\')
904 namebuf[len++] = '\\';
905 strcpy(namebuf + len, "*.*");
906
Barry Warsaw53699e91996-12-10 23:23:01 +0000907 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000908 return NULL;
909
910 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000911 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
912 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000913 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000914 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000915 }
916 do {
917 if (ep.name[0] == '.' &&
918 (ep.name[1] == '\0' ||
919 ep.name[1] == '.' &&
920 ep.name[2] == '\0'))
921 continue;
922 strcpy(namebuf, ep.name);
923 for (pt = namebuf; *pt; pt++)
924 if (isupper(*pt))
925 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000926 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000927 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000928 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000929 d = NULL;
930 break;
931 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000932 if (PyList_Append(d, v) != 0) {
933 Py_DECREF(v);
934 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000935 d = NULL;
936 break;
937 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000938 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000939 } while (_dos_findnext(&ep) == 0);
940
941 return d;
942
943#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000944#if defined(PYOS_OS2)
945
946#ifndef MAX_PATH
947#define MAX_PATH CCHMAXPATH
948#endif
949 char *name, *pt;
950 int len;
951 PyObject *d, *v;
952 char namebuf[MAX_PATH+5];
953 HDIR hdir = 1;
954 ULONG srchcnt = 1;
955 FILEFINDBUF3 ep;
956 APIRET rc;
957
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000958 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000959 return NULL;
960 if (len >= MAX_PATH) {
961 PyErr_SetString(PyExc_ValueError, "path too long");
962 return NULL;
963 }
964 strcpy(namebuf, name);
965 for (pt = namebuf; *pt; pt++)
966 if (*pt == '/')
967 *pt = '\\';
968 if (namebuf[len-1] != '\\')
969 namebuf[len++] = '\\';
970 strcpy(namebuf + len, "*.*");
971
972 if ((d = PyList_New(0)) == NULL)
973 return NULL;
974
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000975 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
976 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000977 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000978 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
979 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
980 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000981
982 if (rc != NO_ERROR) {
983 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000984 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000985 }
986
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000987 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000988 do {
989 if (ep.achName[0] == '.'
990 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000991 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000992
993 strcpy(namebuf, ep.achName);
994
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000995 /* Leave Case of Name Alone -- In Native Form */
996 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000997
998 v = PyString_FromString(namebuf);
999 if (v == NULL) {
1000 Py_DECREF(d);
1001 d = NULL;
1002 break;
1003 }
1004 if (PyList_Append(d, v) != 0) {
1005 Py_DECREF(v);
1006 Py_DECREF(d);
1007 d = NULL;
1008 break;
1009 }
1010 Py_DECREF(v);
1011 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1012 }
1013
1014 return d;
1015#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001016
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001017 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001018 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001019 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001020 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001021 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001022 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001023 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001024 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001025 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001026 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001027 closedir(dirp);
1028 return NULL;
1029 }
1030 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001031 if (ep->d_name[0] == '.' &&
1032 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001033 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001034 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001035 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001036 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001037 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001038 d = NULL;
1039 break;
1040 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001041 if (PyList_Append(d, v) != 0) {
1042 Py_DECREF(v);
1043 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001044 d = NULL;
1045 break;
1046 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001047 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001048 }
1049 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001050
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001051 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001052
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001053#endif /* !PYOS_OS2 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001054#endif /* !_MSC_VER */
Guido van Rossum8d665e61996-06-26 18:22:49 +00001055#endif /* !MS_WIN32 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001056}
1057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001058static char posix_mkdir__doc__[] =
1059"mkdir(path [, mode=0777]) -> None\n\
1060Create a directory.";
1061
Barry Warsaw53699e91996-12-10 23:23:01 +00001062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001063posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001064{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001065 int res;
1066 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001067 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001068 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001069 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001070 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001071#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001072 res = mkdir(path);
1073#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001074 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001075#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001076 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001077 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001078 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001079 Py_INCREF(Py_None);
1080 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001081}
1082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001083
Guido van Rossumb6775db1994-08-01 11:34:53 +00001084#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001085static char posix_nice__doc__[] =
1086"nice(inc) -> new_priority\n\
1087Decrease the priority of process and return new priority.";
1088
Barry Warsaw53699e91996-12-10 23:23:01 +00001089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001090posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001091{
1092 int increment, value;
1093
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001094 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001095 return NULL;
1096 value = nice(increment);
1097 if (value == -1)
1098 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001099 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001100}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001101#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001102
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001103
1104static char posix_rename__doc__[] =
1105"rename(old, new) -> None\n\
1106Rename a file or directory.";
1107
Barry Warsaw53699e91996-12-10 23:23:01 +00001108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001109posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001110{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001111 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001112}
1113
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001114
1115static char posix_rmdir__doc__[] =
1116"rmdir(path) -> None\n\
1117Remove a directory.";
1118
Barry Warsaw53699e91996-12-10 23:23:01 +00001119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001120posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001121{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001122 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001123}
1124
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001125
1126static char posix_stat__doc__[] =
1127"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1128Perform a stat system call on the given path.";
1129
Barry Warsaw53699e91996-12-10 23:23:01 +00001130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001131posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132{
Fred Drake699f3522000-06-29 21:12:41 +00001133 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001134}
1135
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001136
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001137#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001138static char posix_system__doc__[] =
1139"system(command) -> exit_status\n\
1140Execute the command (a string) in a subshell.";
1141
Barry Warsaw53699e91996-12-10 23:23:01 +00001142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001143posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001144{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001145 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001146 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001147 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001148 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001149 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001150 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001151 Py_END_ALLOW_THREADS
1152 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001154#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001156
1157static char posix_umask__doc__[] =
1158"umask(new_mask) -> old_mask\n\
1159Set the current numeric umask and return the previous umask.";
1160
Barry Warsaw53699e91996-12-10 23:23:01 +00001161static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001162posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001163{
1164 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001165 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001166 return NULL;
1167 i = umask(i);
1168 if (i < 0)
1169 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001170 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171}
1172
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001173
1174static char posix_unlink__doc__[] =
1175"unlink(path) -> None\n\
1176Remove a file (same as remove(path)).";
1177
1178static char posix_remove__doc__[] =
1179"remove(path) -> None\n\
1180Remove a file (same as unlink(path)).";
1181
Barry Warsaw53699e91996-12-10 23:23:01 +00001182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001183posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001185 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001186}
1187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001188
Guido van Rossumb6775db1994-08-01 11:34:53 +00001189#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001190static char posix_uname__doc__[] =
1191"uname() -> (sysname, nodename, release, version, machine)\n\
1192Return a tuple identifying the current operating system.";
1193
Barry Warsaw53699e91996-12-10 23:23:01 +00001194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001195posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001196{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001197 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001198 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001199 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001200 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001201 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001202 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001203 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001204 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001205 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001206 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001207 u.sysname,
1208 u.nodename,
1209 u.release,
1210 u.version,
1211 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001212}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001213#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001214
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001215
1216static char posix_utime__doc__[] =
1217"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001218utime(path, None) -> None\n\
1219Set the access and modified time of the file to the given values. If the\n\
1220second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001221
Barry Warsaw53699e91996-12-10 23:23:01 +00001222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001223posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001224{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001225 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001226 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001227 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001228 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001229
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001230/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001231#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001232 struct utimbuf buf;
1233#define ATIME buf.actime
1234#define MTIME buf.modtime
1235#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001236#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001237 time_t buf[2];
1238#define ATIME buf[0]
1239#define MTIME buf[1]
1240#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001241#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001242
Barry Warsaw3cef8562000-05-01 16:17:24 +00001243 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001244 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001245 if (arg == Py_None) {
1246 /* optional time values not given */
1247 Py_BEGIN_ALLOW_THREADS
1248 res = utime(path, NULL);
1249 Py_END_ALLOW_THREADS
1250 }
1251 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1252 PyErr_SetString(PyExc_TypeError,
1253 "Second argument must be a 2-tuple of numbers.");
1254 return NULL;
1255 }
1256 else {
1257 ATIME = atime;
1258 MTIME = mtime;
1259 Py_BEGIN_ALLOW_THREADS
1260 res = utime(path, UTIME_ARG);
1261 Py_END_ALLOW_THREADS
1262 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001263 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001264 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001265 Py_INCREF(Py_None);
1266 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001267#undef UTIME_ARG
1268#undef ATIME
1269#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001270}
1271
Guido van Rossum85e3b011991-06-03 12:42:10 +00001272
Guido van Rossum3b066191991-06-04 19:40:25 +00001273/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001275static char posix__exit__doc__[] =
1276"_exit(status)\n\
1277Exit to the system with specified status, without normal exit processing.";
1278
Barry Warsaw53699e91996-12-10 23:23:01 +00001279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001280posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001281{
1282 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001283 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001284 return NULL;
1285 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001286 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001287}
1288
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001289
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001290#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001291static char posix_execv__doc__[] =
1292"execv(path, args)\n\
1293Execute an executable path with arguments, replacing current process.\n\
1294\n\
1295 path: path of executable file\n\
1296 args: tuple or list of strings";
1297
Barry Warsaw53699e91996-12-10 23:23:01 +00001298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001299posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001300{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001301 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001302 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001303 char **argvlist;
1304 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001305 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001306
Guido van Rossum89b33251993-10-22 14:26:06 +00001307 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001308 argv is a list or tuple of strings. */
1309
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001310 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001311 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001312 if (PyList_Check(argv)) {
1313 argc = PyList_Size(argv);
1314 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001315 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001316 else if (PyTuple_Check(argv)) {
1317 argc = PyTuple_Size(argv);
1318 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001319 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001320 else {
Guido van Rossum50422b42000-04-26 20:34:28 +00001321 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1322 return NULL;
1323 }
1324
1325 if (argc == 0) {
1326 PyErr_SetString(PyExc_ValueError, "empty argument list");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001327 return NULL;
1328 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001329
Barry Warsaw53699e91996-12-10 23:23:01 +00001330 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001331 if (argvlist == NULL)
1332 return NULL;
1333 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001334 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1335 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001336 PyErr_SetString(PyExc_TypeError,
1337 "all arguments must be strings");
1338 return NULL;
1339
Guido van Rossum85e3b011991-06-03 12:42:10 +00001340 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001341 }
1342 argvlist[argc] = NULL;
1343
Guido van Rossumb6775db1994-08-01 11:34:53 +00001344#ifdef BAD_EXEC_PROTOTYPES
1345 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001346#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001347 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001348#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001349
Guido van Rossum85e3b011991-06-03 12:42:10 +00001350 /* If we get here it's definitely an error */
1351
Barry Warsaw53699e91996-12-10 23:23:01 +00001352 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001353 return posix_error();
1354}
1355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001356
1357static char posix_execve__doc__[] =
1358"execve(path, args, env)\n\
1359Execute a path with arguments and environment, replacing current process.\n\
1360\n\
1361 path: path of executable file\n\
1362 args: tuple or list of arguments\n\
1363 env: dictonary of strings mapping to strings";
1364
Barry Warsaw53699e91996-12-10 23:23:01 +00001365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001366posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001367{
1368 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001369 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001370 char **argvlist;
1371 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001372 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001373 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001374 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001375
1376 /* execve has three arguments: (path, argv, env), where
1377 argv is a list or tuple of strings and env is a dictionary
1378 like posix.environ. */
1379
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001380 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001381 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001382 if (PyList_Check(argv)) {
1383 argc = PyList_Size(argv);
1384 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001385 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001386 else if (PyTuple_Check(argv)) {
1387 argc = PyTuple_Size(argv);
1388 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001389 }
1390 else {
Barry Warsaw53699e91996-12-10 23:23:01 +00001391 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001392 return NULL;
1393 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001394 if (!PyMapping_Check(env)) {
1395 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001396 return NULL;
1397 }
1398
Guido van Rossum50422b42000-04-26 20:34:28 +00001399 if (argc == 0) {
1400 PyErr_SetString(PyExc_ValueError,
1401 "empty argument list");
1402 return NULL;
1403 }
1404
Barry Warsaw53699e91996-12-10 23:23:01 +00001405 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001406 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001407 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001408 return NULL;
1409 }
1410 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001411 if (!PyArg_Parse((*getitem)(argv, i),
Barry Warsaw43d68b81996-12-19 22:10:44 +00001412 "s;argv must be list of strings",
1413 &argvlist[i]))
1414 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001415 goto fail_1;
1416 }
1417 }
1418 argvlist[argc] = NULL;
1419
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001420 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001421 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001422 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001423 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001424 goto fail_1;
1425 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001426 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001427 keys = PyMapping_Keys(env);
1428 vals = PyMapping_Values(env);
1429 if (!keys || !vals)
1430 goto fail_2;
1431
1432 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001433 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001434
1435 key = PyList_GetItem(keys, pos);
1436 val = PyList_GetItem(vals, pos);
1437 if (!key || !val)
1438 goto fail_2;
1439
Barry Warsaw53699e91996-12-10 23:23:01 +00001440 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
Barry Warsaw43d68b81996-12-19 22:10:44 +00001441 !PyArg_Parse(val, "s;non-string value in env", &v))
1442 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001443 goto fail_2;
1444 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001445
1446#if defined(PYOS_OS2)
1447 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1448 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1449#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001450 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001451 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001452 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001453 goto fail_2;
1454 }
1455 sprintf(p, "%s=%s", k, v);
1456 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001457#if defined(PYOS_OS2)
1458 }
1459#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001460 }
1461 envlist[envc] = 0;
1462
Guido van Rossumb6775db1994-08-01 11:34:53 +00001463
1464#ifdef BAD_EXEC_PROTOTYPES
1465 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001466#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001467 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001468#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001469
1470 /* If we get here it's definitely an error */
1471
1472 (void) posix_error();
1473
1474 fail_2:
1475 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001476 PyMem_DEL(envlist[envc]);
1477 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001478 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001479 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001480 Py_XDECREF(vals);
1481 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001482 return NULL;
1483}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001484#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001485
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001486
Guido van Rossuma1065681999-01-25 23:20:23 +00001487#ifdef HAVE_SPAWNV
1488static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001489"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001490Execute an executable path with arguments, replacing current process.\n\
1491\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001492 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001493 path: path of executable file\n\
1494 args: tuple or list of strings";
1495
1496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001497posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001498{
1499 char *path;
1500 PyObject *argv;
1501 char **argvlist;
1502 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001503 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001504 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001505
1506 /* spawnv has three arguments: (mode, path, argv), where
1507 argv is a list or tuple of strings. */
1508
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001509 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001510 return NULL;
1511 if (PyList_Check(argv)) {
1512 argc = PyList_Size(argv);
1513 getitem = PyList_GetItem;
1514 }
1515 else if (PyTuple_Check(argv)) {
1516 argc = PyTuple_Size(argv);
1517 getitem = PyTuple_GetItem;
1518 }
1519 else {
Fred Drake137507e2000-06-01 02:02:46 +00001520 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001521 return NULL;
1522 }
1523
1524 argvlist = PyMem_NEW(char *, argc+1);
1525 if (argvlist == NULL)
1526 return NULL;
1527 for (i = 0; i < argc; i++) {
1528 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1529 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001530 PyErr_SetString(PyExc_TypeError,
1531 "all arguments must be strings");
1532 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001533 }
1534 }
1535 argvlist[argc] = NULL;
1536
Guido van Rossum246bc171999-02-01 23:54:31 +00001537 if (mode == _OLD_P_OVERLAY)
1538 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001539 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001540
1541 PyMem_DEL(argvlist);
1542
Fred Drake699f3522000-06-29 21:12:41 +00001543 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001544 return posix_error();
1545 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001546#if SIZEOF_LONG == SIZEOF_VOID_P
1547 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001548#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001549 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001550#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001551}
1552
1553
1554static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001555"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001556Execute a path with arguments and environment, replacing current process.\n\
1557\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001558 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001559 path: path of executable file\n\
1560 args: tuple or list of arguments\n\
1561 env: dictonary of strings mapping to strings";
1562
1563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001564posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001565{
1566 char *path;
1567 PyObject *argv, *env;
1568 char **argvlist;
1569 char **envlist;
1570 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1571 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001572 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001573 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001574
1575 /* spawnve has four arguments: (mode, path, argv, env), where
1576 argv is a list or tuple of strings and env is a dictionary
1577 like posix.environ. */
1578
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001579 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001580 return NULL;
1581 if (PyList_Check(argv)) {
1582 argc = PyList_Size(argv);
1583 getitem = PyList_GetItem;
1584 }
1585 else if (PyTuple_Check(argv)) {
1586 argc = PyTuple_Size(argv);
1587 getitem = PyTuple_GetItem;
1588 }
1589 else {
1590 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1591 return NULL;
1592 }
1593 if (!PyMapping_Check(env)) {
1594 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1595 return NULL;
1596 }
1597
1598 argvlist = PyMem_NEW(char *, argc+1);
1599 if (argvlist == NULL) {
1600 PyErr_NoMemory();
1601 return NULL;
1602 }
1603 for (i = 0; i < argc; i++) {
1604 if (!PyArg_Parse((*getitem)(argv, i),
1605 "s;argv must be list of strings",
1606 &argvlist[i]))
1607 {
1608 goto fail_1;
1609 }
1610 }
1611 argvlist[argc] = NULL;
1612
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001613 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001614 envlist = PyMem_NEW(char *, i + 1);
1615 if (envlist == NULL) {
1616 PyErr_NoMemory();
1617 goto fail_1;
1618 }
1619 envc = 0;
1620 keys = PyMapping_Keys(env);
1621 vals = PyMapping_Values(env);
1622 if (!keys || !vals)
1623 goto fail_2;
1624
1625 for (pos = 0; pos < i; pos++) {
1626 char *p, *k, *v;
1627
1628 key = PyList_GetItem(keys, pos);
1629 val = PyList_GetItem(vals, pos);
1630 if (!key || !val)
1631 goto fail_2;
1632
1633 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1634 !PyArg_Parse(val, "s;non-string value in env", &v))
1635 {
1636 goto fail_2;
1637 }
1638 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1639 if (p == NULL) {
1640 PyErr_NoMemory();
1641 goto fail_2;
1642 }
1643 sprintf(p, "%s=%s", k, v);
1644 envlist[envc++] = p;
1645 }
1646 envlist[envc] = 0;
1647
Guido van Rossum246bc171999-02-01 23:54:31 +00001648 if (mode == _OLD_P_OVERLAY)
1649 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001650 spawnval = _spawnve(mode, path, argvlist, envlist);
1651 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001652 (void) posix_error();
1653 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001654#if SIZEOF_LONG == SIZEOF_VOID_P
1655 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001656#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001657 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001658#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001659
1660 fail_2:
1661 while (--envc >= 0)
1662 PyMem_DEL(envlist[envc]);
1663 PyMem_DEL(envlist);
1664 fail_1:
1665 PyMem_DEL(argvlist);
1666 Py_XDECREF(vals);
1667 Py_XDECREF(keys);
1668 return res;
1669}
1670#endif /* HAVE_SPAWNV */
1671
1672
Guido van Rossumad0ee831995-03-01 10:34:45 +00001673#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001674static char posix_fork__doc__[] =
1675"fork() -> pid\n\
1676Fork a child process.\n\
1677\n\
1678Return 0 to child process and PID of child to parent process.";
1679
Barry Warsaw53699e91996-12-10 23:23:01 +00001680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001681posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001682{
1683 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001684 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001685 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001686 pid = fork();
1687 if (pid == -1)
1688 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001689 if (pid == 0)
1690 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001691 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001692}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001693#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001694
Fred Drake8cef4cf2000-06-28 16:40:38 +00001695#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1696#ifdef HAVE_PTY_H
1697#include <pty.h>
1698#else
1699#ifdef HAVE_LIBUTIL_H
1700#include <libutil.h>
1701#else
1702/* BSDI does not supply a prototype for the 'openpty' and 'forkpty'
1703 functions, eventhough they are included in libutil. */
1704#include <termios.h>
1705extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
1706extern int forkpty(int *, char *, struct termios *, struct winsize *);
1707#endif /* HAVE_LIBUTIL_H */
1708#endif /* HAVE_PTY_H */
1709#endif /* defined(HAVE_OPENPTY) or defined(HAVE_FORKPTY) */
1710
1711#ifdef HAVE_OPENPTY
1712static char posix_openpty__doc__[] =
1713"openpty() -> (master_fd, slave_fd)\n\
1714Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1715
1716static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001717posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001718{
1719 int master_fd, slave_fd;
1720 if (!PyArg_ParseTuple(args, ":openpty"))
1721 return NULL;
1722 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1723 return posix_error();
1724 return Py_BuildValue("(ii)", master_fd, slave_fd);
1725}
1726#endif
1727
1728#ifdef HAVE_FORKPTY
1729static char posix_forkpty__doc__[] =
1730"forkpty() -> (pid, master_fd)\n\
1731Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1732Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1733To both, return fd of newly opened pseudo-terminal.\n";
1734
1735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001736posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001737{
1738 int master_fd, pid;
1739
1740 if (!PyArg_ParseTuple(args, ":forkpty"))
1741 return NULL;
1742 pid = forkpty(&master_fd, NULL, NULL, NULL);
1743 if (pid == -1)
1744 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001745 if (pid == 0)
1746 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001747 return Py_BuildValue("(ii)", pid, master_fd);
1748}
1749#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001750
Guido van Rossumad0ee831995-03-01 10:34:45 +00001751#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001752static char posix_getegid__doc__[] =
1753"getegid() -> egid\n\
1754Return the current process's effective group id.";
1755
Barry Warsaw53699e91996-12-10 23:23:01 +00001756static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001757posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001758{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001759 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001760 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001761 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001762}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001763#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001765
Guido van Rossumad0ee831995-03-01 10:34:45 +00001766#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001767static char posix_geteuid__doc__[] =
1768"geteuid() -> euid\n\
1769Return the current process's effective user id.";
1770
Barry Warsaw53699e91996-12-10 23:23:01 +00001771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001772posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001773{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001774 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001775 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001776 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001777}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001778#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001780
Guido van Rossumad0ee831995-03-01 10:34:45 +00001781#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001782static char posix_getgid__doc__[] =
1783"getgid() -> gid\n\
1784Return the current process's group id.";
1785
Barry Warsaw53699e91996-12-10 23:23:01 +00001786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001787posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001788{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001789 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001790 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001791 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001792}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001793#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001795
1796static char posix_getpid__doc__[] =
1797"getpid() -> pid\n\
1798Return the current process id";
1799
Barry Warsaw53699e91996-12-10 23:23:01 +00001800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001801posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001802{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001803 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001804 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001805 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001806}
1807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001808
Fred Drakec9680921999-12-13 16:37:25 +00001809#ifdef HAVE_GETGROUPS
1810static char posix_getgroups__doc__[] = "\
1811getgroups() -> list of group IDs\n\
1812Return list of supplemental group IDs for the process.";
1813
1814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001815posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001816{
1817 PyObject *result = NULL;
1818
1819 if (PyArg_ParseTuple(args, ":getgroups")) {
1820#ifdef NGROUPS_MAX
1821#define MAX_GROUPS NGROUPS_MAX
1822#else
1823 /* defined to be 16 on Solaris7, so this should be a small number */
1824#define MAX_GROUPS 64
1825#endif
1826 gid_t grouplist[MAX_GROUPS];
1827 int n;
1828
1829 n = getgroups(MAX_GROUPS, grouplist);
1830 if (n < 0)
1831 posix_error();
1832 else {
1833 result = PyList_New(n);
1834 if (result != NULL) {
1835 PyObject *o;
1836 int i;
1837 for (i = 0; i < n; ++i) {
1838 o = PyInt_FromLong((long)grouplist[i]);
1839 if (o == NULL) {
1840 Py_DECREF(result);
1841 result = NULL;
1842 break;
1843 }
1844 PyList_SET_ITEM(result, i, o);
1845 }
1846 }
1847 }
1848 }
1849 return result;
1850}
1851#endif
1852
Guido van Rossumb6775db1994-08-01 11:34:53 +00001853#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001854static char posix_getpgrp__doc__[] =
1855"getpgrp() -> pgrp\n\
1856Return the current process group id.";
1857
Barry Warsaw53699e91996-12-10 23:23:01 +00001858static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001859posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001860{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001861 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001862 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001863#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001864 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001865#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001866 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001867#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001868}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001869#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001871
Guido van Rossumb6775db1994-08-01 11:34:53 +00001872#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001873static char posix_setpgrp__doc__[] =
1874"setpgrp() -> None\n\
1875Make this process a session leader.";
1876
Barry Warsaw53699e91996-12-10 23:23:01 +00001877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001878posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001879{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001880 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001881 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001882#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001883 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001884#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001885 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001886#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001887 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001888 Py_INCREF(Py_None);
1889 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001890}
1891
Guido van Rossumb6775db1994-08-01 11:34:53 +00001892#endif /* HAVE_SETPGRP */
1893
Guido van Rossumad0ee831995-03-01 10:34:45 +00001894#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001895static char posix_getppid__doc__[] =
1896"getppid() -> ppid\n\
1897Return the parent's process id.";
1898
Barry Warsaw53699e91996-12-10 23:23:01 +00001899static PyObject *
Guido van Rossum85e3b011991-06-03 12:42:10 +00001900posix_getppid(self, args)
Barry Warsaw53699e91996-12-10 23:23:01 +00001901 PyObject *self;
1902 PyObject *args;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001903{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001904 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001905 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001906 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001907}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001908#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001909
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001910
Fred Drake12c6e2d1999-12-14 21:25:03 +00001911#ifdef HAVE_GETLOGIN
1912static char posix_getlogin__doc__[] = "\
1913getlogin() -> string\n\
1914Return the actual login name.";
1915
1916static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001917posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001918{
1919 PyObject *result = NULL;
1920
1921 if (PyArg_ParseTuple(args, ":getlogin")) {
1922 char *name = getlogin();
1923
1924 if (name == NULL)
1925 posix_error();
1926 else
1927 result = PyString_FromString(name);
1928 }
1929 return result;
1930}
1931#endif
1932
Guido van Rossumad0ee831995-03-01 10:34:45 +00001933#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001934static char posix_getuid__doc__[] =
1935"getuid() -> uid\n\
1936Return the current process's user id.";
1937
Barry Warsaw53699e91996-12-10 23:23:01 +00001938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001939posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001940{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001941 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001942 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001943 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001944}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001945#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001947
Guido van Rossumad0ee831995-03-01 10:34:45 +00001948#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001949static char posix_kill__doc__[] =
1950"kill(pid, sig) -> None\n\
1951Kill a process with a signal.";
1952
Barry Warsaw53699e91996-12-10 23:23:01 +00001953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001954posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001955{
1956 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001957 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001958 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001959#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001960 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1961 APIRET rc;
1962 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001963 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001964
1965 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1966 APIRET rc;
1967 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001968 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001969
1970 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001971 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001972#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001973 if (kill(pid, sig) == -1)
1974 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001975#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001976 Py_INCREF(Py_None);
1977 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001978}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001979#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001980
Guido van Rossumc0125471996-06-28 18:55:32 +00001981#ifdef HAVE_PLOCK
1982
1983#ifdef HAVE_SYS_LOCK_H
1984#include <sys/lock.h>
1985#endif
1986
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001987static char posix_plock__doc__[] =
1988"plock(op) -> None\n\
1989Lock program segments into memory.";
1990
Barry Warsaw53699e91996-12-10 23:23:01 +00001991static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001992posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001993{
1994 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001995 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001996 return NULL;
1997 if (plock(op) == -1)
1998 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001999 Py_INCREF(Py_None);
2000 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002001}
2002#endif
2003
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002004
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002005#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002006static char posix_popen__doc__[] =
2007"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2008Open a pipe to/from a command returning a file object.";
2009
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002010#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002011static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002012async_system(const char *command)
2013{
2014 char *p, errormsg[256], args[1024];
2015 RESULTCODES rcodes;
2016 APIRET rc;
2017 char *shell = getenv("COMSPEC");
2018 if (!shell)
2019 shell = "cmd";
2020
2021 strcpy(args, shell);
2022 p = &args[ strlen(args)+1 ];
2023 strcpy(p, "/c ");
2024 strcat(p, command);
2025 p += strlen(p) + 1;
2026 *p = '\0';
2027
2028 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002029 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002030 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002031 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002032 &rcodes, shell);
2033 return rc;
2034}
2035
Guido van Rossumd48f2521997-12-05 22:19:34 +00002036static FILE *
2037popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002038{
2039 HFILE rhan, whan;
2040 FILE *retfd = NULL;
2041 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2042
Guido van Rossumd48f2521997-12-05 22:19:34 +00002043 if (rc != NO_ERROR) {
2044 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002045 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002046 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002047
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002048 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2049 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002050
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002051 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2052 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002053
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002054 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2055 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002056
2057 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002058 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002059 }
2060
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002061 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2062 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002063
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002064 close(oldfd); /* And Close Saved STDOUT Handle */
2065 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002066
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002067 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2068 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002069
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002070 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2071 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002072
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002073 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2074 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002075
2076 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002077 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002078 }
2079
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002080 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2081 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002082
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002083 close(oldfd); /* And Close Saved STDIN Handle */
2084 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002085
Guido van Rossumd48f2521997-12-05 22:19:34 +00002086 } else {
2087 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002088 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002089 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002090}
2091
2092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002093posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002094{
2095 char *name;
2096 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002097 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002098 FILE *fp;
2099 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002100 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002101 return NULL;
2102 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002103 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002104 Py_END_ALLOW_THREADS
2105 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002106 return os2_error(err);
2107
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002108 f = PyFile_FromFile(fp, name, mode, fclose);
2109 if (f != NULL)
2110 PyFile_SetBufSize(f, bufsize);
2111 return f;
2112}
2113
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002114#elif defined(MS_WIN32)
2115
2116/*
2117 * Portable 'popen' replacement for Win32.
2118 *
2119 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2120 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
2121 */
2122
2123#include <malloc.h>
2124#include <io.h>
2125#include <fcntl.h>
2126
2127/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2128#define POPEN_1 1
2129#define POPEN_2 2
2130#define POPEN_3 3
2131#define POPEN_4 4
2132
2133static PyObject *_PyPopen(char *, int, int);
2134
2135/* popen that works from a GUI.
2136 *
2137 * The result of this function is a pipe (file) connected to the
2138 * processes stdin or stdout, depending on the requested mode.
2139 */
2140
2141static PyObject *
2142posix_popen(PyObject *self, PyObject *args)
2143{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002144 PyObject *f, *s;
2145 int tm = 0;
2146
2147 char *cmdstring;
2148 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002149 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002150 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002151 return NULL;
2152
2153 s = PyTuple_New(0);
2154
2155 if (*mode == 'r')
2156 tm = _O_RDONLY;
2157 else if (*mode != 'w') {
2158 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'");
2159 return NULL;
2160 } else
2161 tm = _O_WRONLY;
2162
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002163 if (bufsize != -1) {
2164 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2165 return NULL;
2166 }
2167
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002168 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002169 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002170 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002171 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002172 else
2173 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2174
2175 return f;
2176}
2177
2178/* Variation on win32pipe.popen
2179 *
2180 * The result of this function is a pipe (file) connected to the
2181 * process's stdin, and a pipe connected to the process's stdout.
2182 */
2183
2184static PyObject *
2185win32_popen2(PyObject *self, PyObject *args)
2186{
2187 PyObject *f;
2188 int tm=0;
2189
2190 char *cmdstring;
2191 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002192 int bufsize = -1;
2193 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002194 return NULL;
2195
2196 if (*mode == 't')
2197 tm = _O_TEXT;
2198 else if (*mode != 'b') {
2199 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2200 return NULL;
2201 } else
2202 tm = _O_BINARY;
2203
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002204 if (bufsize != -1) {
2205 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2206 return NULL;
2207 }
2208
2209 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002210
2211 return f;
2212}
2213
2214/*
2215 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002216 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002217 * The result of this function is 3 pipes - the process's stdin,
2218 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002219 */
2220
2221static PyObject *
2222win32_popen3(PyObject *self, PyObject *args)
2223{
2224 PyObject *f;
2225 int tm = 0;
2226
2227 char *cmdstring;
2228 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002229 int bufsize = -1;
2230 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002231 return NULL;
2232
2233 if (*mode == 't')
2234 tm = _O_TEXT;
2235 else if (*mode != 'b') {
2236 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2237 return NULL;
2238 } else
2239 tm = _O_BINARY;
2240
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002241 if (bufsize != -1) {
2242 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2243 return NULL;
2244 }
2245
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002246 f = _PyPopen(cmdstring, tm, POPEN_3);
2247
2248 return f;
2249}
2250
2251/*
2252 * Variation on win32pipe.popen
2253 *
2254 * The result of this function is 2 pipes - the processes stdin,
2255 * and stdout+stderr combined as a single pipe.
2256 */
2257
2258static PyObject *
2259win32_popen4(PyObject *self, PyObject *args)
2260{
2261 PyObject *f;
2262 int tm = 0;
2263
2264 char *cmdstring;
2265 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002266 int bufsize = -1;
2267 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002268 return NULL;
2269
2270 if (*mode == 't')
2271 tm = _O_TEXT;
2272 else if (*mode != 'b') {
2273 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2274 return NULL;
2275 } else
2276 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002277
2278 if (bufsize != -1) {
2279 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2280 return NULL;
2281 }
2282
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002283 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002284
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002285 return f;
2286}
2287
2288static int
2289_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002290 HANDLE hStdin,
2291 HANDLE hStdout,
2292 HANDLE hStderr)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002293{
2294 PROCESS_INFORMATION piProcInfo;
2295 STARTUPINFO siStartInfo;
2296 char *s1,*s2, *s3 = " /c ";
2297 const char *szConsoleSpawn = "w9xpopen.exe \"";
2298 int i;
2299 int x;
2300
2301 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2302 s1 = (char *)_alloca(i);
2303 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2304 return x;
2305 if (GetVersion() < 0x80000000) {
2306 /*
2307 * NT/2000
2308 */
2309 x = i + strlen(s3) + strlen(cmdstring) + 1;
2310 s2 = (char *)_alloca(x);
2311 ZeroMemory(s2, x);
2312 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2313 }
2314 else {
2315 /*
2316 * Oh gag, we're on Win9x. Use the workaround listed in
2317 * KB: Q150956
2318 */
2319 char modulepath[256];
2320 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2321 for (i = x = 0; modulepath[i]; i++)
2322 if (modulepath[i] == '\\')
2323 x = i+1;
2324 modulepath[x] = '\0';
2325 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2326 strlen(modulepath) +
2327 strlen(szConsoleSpawn) + 1;
2328 s2 = (char *)_alloca(x);
2329 ZeroMemory(s2, x);
2330 sprintf(
2331 s2,
2332 "%s%s%s%s%s\"",
2333 modulepath,
2334 szConsoleSpawn,
2335 s1,
2336 s3,
2337 cmdstring);
2338 }
2339 }
2340
2341 /* Could be an else here to try cmd.exe / command.com in the path
2342 Now we'll just error out.. */
2343 else
2344 return -1;
2345
2346 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2347 siStartInfo.cb = sizeof(STARTUPINFO);
2348 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2349 siStartInfo.hStdInput = hStdin;
2350 siStartInfo.hStdOutput = hStdout;
2351 siStartInfo.hStdError = hStderr;
2352 siStartInfo.wShowWindow = SW_HIDE;
2353
2354 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002355 s2,
2356 NULL,
2357 NULL,
2358 TRUE,
2359 CREATE_NEW_CONSOLE,
2360 NULL,
2361 NULL,
2362 &siStartInfo,
2363 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002364 /* Close the handles now so anyone waiting is woken. */
2365 CloseHandle(piProcInfo.hProcess);
2366 CloseHandle(piProcInfo.hThread);
2367 return TRUE;
2368 }
2369 return FALSE;
2370}
2371
2372/* The following code is based off of KB: Q190351 */
2373
2374static PyObject *
2375_PyPopen(char *cmdstring, int mode, int n)
2376{
2377 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2378 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
2379 hChildStderrRdDup; /* hChildStdoutWrDup; */
2380
2381 SECURITY_ATTRIBUTES saAttr;
2382 BOOL fSuccess;
2383 int fd1, fd2, fd3;
2384 FILE *f1, *f2, *f3;
2385 PyObject *f;
2386
2387 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2388 saAttr.bInheritHandle = TRUE;
2389 saAttr.lpSecurityDescriptor = NULL;
2390
2391 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2392 return win32_error("CreatePipe", NULL);
2393
2394 /* Create new output read handle and the input write handle. Set
2395 * the inheritance properties to FALSE. Otherwise, the child inherits
2396 * the these handles; resulting in non-closeable handles to the pipes
2397 * being created. */
2398 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002399 GetCurrentProcess(), &hChildStdinWrDup, 0,
2400 FALSE,
2401 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002402 if (!fSuccess)
2403 return win32_error("DuplicateHandle", NULL);
2404
2405 /* Close the inheritable version of ChildStdin
2406 that we're using. */
2407 CloseHandle(hChildStdinWr);
2408
2409 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2410 return win32_error("CreatePipe", NULL);
2411
2412 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002413 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2414 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002415 if (!fSuccess)
2416 return win32_error("DuplicateHandle", NULL);
2417
2418 /* Close the inheritable version of ChildStdout
2419 that we're using. */
2420 CloseHandle(hChildStdoutRd);
2421
2422 if (n != POPEN_4) {
2423 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2424 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002425 fSuccess = DuplicateHandle(GetCurrentProcess(),
2426 hChildStderrRd,
2427 GetCurrentProcess(),
2428 &hChildStderrRdDup, 0,
2429 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002430 if (!fSuccess)
2431 return win32_error("DuplicateHandle", NULL);
2432 /* Close the inheritable version of ChildStdErr that we're using. */
2433 CloseHandle(hChildStderrRd);
2434 }
2435
2436 switch (n) {
2437 case POPEN_1:
2438 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2439 case _O_WRONLY | _O_TEXT:
2440 /* Case for writing to child Stdin in text mode. */
2441 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2442 f1 = _fdopen(fd1, "w");
2443 f = PyFile_FromFile(f1, cmdstring, "w", fclose);
2444 PyFile_SetBufSize(f, 0);
2445 /* We don't care about these pipes anymore, so close them. */
2446 CloseHandle(hChildStdoutRdDup);
2447 CloseHandle(hChildStderrRdDup);
2448 break;
2449
2450 case _O_RDONLY | _O_TEXT:
2451 /* Case for reading from child Stdout in text mode. */
2452 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2453 f1 = _fdopen(fd1, "r");
2454 f = PyFile_FromFile(f1, cmdstring, "r", fclose);
2455 PyFile_SetBufSize(f, 0);
2456 /* We don't care about these pipes anymore, so close them. */
2457 CloseHandle(hChildStdinWrDup);
2458 CloseHandle(hChildStderrRdDup);
2459 break;
2460
2461 case _O_RDONLY | _O_BINARY:
2462 /* Case for readinig from child Stdout in binary mode. */
2463 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2464 f1 = _fdopen(fd1, "rb");
2465 f = PyFile_FromFile(f1, cmdstring, "rb", fclose);
2466 PyFile_SetBufSize(f, 0);
2467 /* We don't care about these pipes anymore, so close them. */
2468 CloseHandle(hChildStdinWrDup);
2469 CloseHandle(hChildStderrRdDup);
2470 break;
2471
2472 case _O_WRONLY | _O_BINARY:
2473 /* Case for writing to child Stdin in binary mode. */
2474 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2475 f1 = _fdopen(fd1, "wb");
2476 f = PyFile_FromFile(f1, cmdstring, "wb", fclose);
2477 PyFile_SetBufSize(f, 0);
2478 /* We don't care about these pipes anymore, so close them. */
2479 CloseHandle(hChildStdoutRdDup);
2480 CloseHandle(hChildStderrRdDup);
2481 break;
2482 }
2483 break;
2484
2485 case POPEN_2:
2486 case POPEN_4:
2487 {
2488 char *m1, *m2;
2489 PyObject *p1, *p2;
2490
2491 if (mode && _O_TEXT) {
2492 m1 = "r";
2493 m2 = "w";
2494 } else {
2495 m1 = "rb";
2496 m2 = "wb";
2497 }
2498
2499 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2500 f1 = _fdopen(fd1, m2);
2501 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2502 f2 = _fdopen(fd2, m1);
2503 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose);
2504 PyFile_SetBufSize(p1, 0);
2505 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2506 PyFile_SetBufSize(p2, 0);
2507
2508 if (n != 4)
2509 CloseHandle(hChildStderrRdDup);
2510
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002511 f = Py_BuildValue("OO",p1,p2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002512 break;
2513 }
2514
2515 case POPEN_3:
2516 {
2517 char *m1, *m2;
2518 PyObject *p1, *p2, *p3;
2519
2520 if (mode && _O_TEXT) {
2521 m1 = "r";
2522 m2 = "w";
2523 } else {
2524 m1 = "rb";
2525 m2 = "wb";
2526 }
2527
2528 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2529 f1 = _fdopen(fd1, m2);
2530 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2531 f2 = _fdopen(fd2, m1);
2532 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2533 f3 = _fdopen(fd3, m1);
2534 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose);
2535 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2536 p3 = PyFile_FromFile(f3, cmdstring, m1, fclose);
2537 PyFile_SetBufSize(p1, 0);
2538 PyFile_SetBufSize(p2, 0);
2539 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002540 f = Py_BuildValue("OOO",p1,p2,p3);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002541 break;
2542 }
2543 }
2544
2545 if (n == POPEN_4) {
2546 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002547 hChildStdinRd,
2548 hChildStdoutWr,
2549 hChildStdoutWr))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002550 return win32_error("CreateProcess", NULL);
2551 }
2552 else {
2553 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002554 hChildStdinRd,
2555 hChildStdoutWr,
2556 hChildStderrWr))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002557 return win32_error("CreateProcess", NULL);
2558 }
2559
2560 /* Child is launched. Close the parents copy of those pipe
2561 * handles that only the child should have open. You need to
2562 * make sure that no handles to the write end of the output pipe
2563 * are maintained in this process or else the pipe will not close
2564 * when the child process exits and the ReadFile will hang. */
2565
2566 if (!CloseHandle(hChildStdinRd))
2567 return win32_error("CloseHandle", NULL);
2568
2569 if (!CloseHandle(hChildStdoutWr))
2570 return win32_error("CloseHandle", NULL);
2571
2572 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2573 return win32_error("CloseHandle", NULL);
2574
2575 return f;
2576}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002577#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002579posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002580{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002581 char *name;
2582 char *mode = "r";
2583 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002584 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002585 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002586 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002587 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002588 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002589 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002590 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002591 if (fp == NULL)
2592 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002593 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002594 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002595 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002596 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002597}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002598#endif
2599
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002600#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002602
Guido van Rossumb6775db1994-08-01 11:34:53 +00002603#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002604static char posix_setuid__doc__[] =
2605"setuid(uid) -> None\n\
2606Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002607static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002608posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002609{
2610 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002611 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002612 return NULL;
2613 if (setuid(uid) < 0)
2614 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002615 Py_INCREF(Py_None);
2616 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002617}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002618#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002619
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002620
Guido van Rossumb6775db1994-08-01 11:34:53 +00002621#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002622static char posix_setgid__doc__[] =
2623"setgid(gid) -> None\n\
2624Set the current process's group id.";
2625
Barry Warsaw53699e91996-12-10 23:23:01 +00002626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002627posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002628{
2629 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002630 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002631 return NULL;
2632 if (setgid(gid) < 0)
2633 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002634 Py_INCREF(Py_None);
2635 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002636}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002637#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002638
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002639
Guido van Rossumb6775db1994-08-01 11:34:53 +00002640#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002641static char posix_waitpid__doc__[] =
2642"waitpid(pid, options) -> (pid, status)\n\
2643Wait for completion of a give child process.";
2644
Barry Warsaw53699e91996-12-10 23:23:01 +00002645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002646posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002647{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002648 int pid, options;
2649#ifdef UNION_WAIT
2650 union wait status;
2651#define status_i (status.w_status)
2652#else
2653 int status;
2654#define status_i status
2655#endif
2656 status_i = 0;
2657
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002658 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00002659 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002660 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002661#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002662 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002663#else
2664 pid = waitpid(pid, &status, options);
2665#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002666 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00002667 if (pid == -1)
2668 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00002669 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002670 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00002671}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002672#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00002673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002674
Guido van Rossumad0ee831995-03-01 10:34:45 +00002675#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002676static char posix_wait__doc__[] =
2677"wait() -> (pid, status)\n\
2678Wait for completion of a child process.";
2679
Barry Warsaw53699e91996-12-10 23:23:01 +00002680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002681posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00002682{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002683 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002684#ifdef UNION_WAIT
2685 union wait status;
2686#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002687#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002688 int status;
2689#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002690#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002691 if (!PyArg_ParseTuple(args, ":wait"))
2692 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002693 status_i = 0;
2694 Py_BEGIN_ALLOW_THREADS
2695 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00002696 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00002697 if (pid == -1)
2698 return posix_error();
2699 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002700 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002701#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00002702}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002703#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002704
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002705
2706static char posix_lstat__doc__[] =
2707"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
2708Like stat(path), but do not follow symbolic links.";
2709
Barry Warsaw53699e91996-12-10 23:23:01 +00002710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002711posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002712{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002713#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002714 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002715#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00002716 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002717#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002718}
2719
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002720
Guido van Rossumb6775db1994-08-01 11:34:53 +00002721#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002722static char posix_readlink__doc__[] =
2723"readlink(path) -> path\n\
2724Return a string representing the path to which the symbolic link points.";
2725
Barry Warsaw53699e91996-12-10 23:23:01 +00002726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002727posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002728{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002729 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002730 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002731 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002732 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002733 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002734 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002735 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00002736 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002737 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002738 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002739 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002740}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002741#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002742
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002743
Guido van Rossumb6775db1994-08-01 11:34:53 +00002744#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002745static char posix_symlink__doc__[] =
2746"symlink(src, dst) -> None\n\
2747Create a symbolic link.";
2748
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002750posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002751{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002752 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002753}
2754#endif /* HAVE_SYMLINK */
2755
2756
2757#ifdef HAVE_TIMES
2758#ifndef HZ
2759#define HZ 60 /* Universal constant :-) */
2760#endif /* HZ */
2761
Guido van Rossumd48f2521997-12-05 22:19:34 +00002762#if defined(PYCC_VACPP) && defined(PYOS_OS2)
2763static long
2764system_uptime()
2765{
2766 ULONG value = 0;
2767
2768 Py_BEGIN_ALLOW_THREADS
2769 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
2770 Py_END_ALLOW_THREADS
2771
2772 return value;
2773}
2774
2775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002776posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002777{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002778 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00002779 return NULL;
2780
2781 /* Currently Only Uptime is Provided -- Others Later */
2782 return Py_BuildValue("ddddd",
2783 (double)0 /* t.tms_utime / HZ */,
2784 (double)0 /* t.tms_stime / HZ */,
2785 (double)0 /* t.tms_cutime / HZ */,
2786 (double)0 /* t.tms_cstime / HZ */,
2787 (double)system_uptime() / 1000);
2788}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002789#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002791posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00002792{
2793 struct tms t;
2794 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002795 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00002796 return NULL;
2797 errno = 0;
2798 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00002799 if (c == (clock_t) -1)
2800 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002801 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002802 (double)t.tms_utime / HZ,
2803 (double)t.tms_stime / HZ,
2804 (double)t.tms_cutime / HZ,
2805 (double)t.tms_cstime / HZ,
2806 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00002807}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002808#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002809#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002810
2811
Guido van Rossum87755a21996-09-07 00:59:43 +00002812#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002813#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00002814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002815posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002816{
2817 FILETIME create, exit, kernel, user;
2818 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002819 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002820 return NULL;
2821 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002822 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
2823 /* The fields of a FILETIME structure are the hi and lo part
2824 of a 64-bit value expressed in 100 nanosecond units.
2825 1e7 is one second in such units; 1e-7 the inverse.
2826 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
2827 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002828 return Py_BuildValue(
2829 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002830 (double)(kernel.dwHighDateTime*429.4967296 +
2831 kernel.dwLowDateTime*1e-7),
2832 (double)(user.dwHighDateTime*429.4967296 +
2833 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00002834 (double)0,
2835 (double)0,
2836 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002837}
Guido van Rossum8d665e61996-06-26 18:22:49 +00002838#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002839
2840#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00002841static char posix_times__doc__[] =
2842"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
2843Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002844#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00002845
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002846
Guido van Rossumb6775db1994-08-01 11:34:53 +00002847#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002848static char posix_setsid__doc__[] =
2849"setsid() -> None\n\
2850Call the system call setsid().";
2851
Barry Warsaw53699e91996-12-10 23:23:01 +00002852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002853posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002854{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002855 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002856 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002857 if (setsid() < 0)
2858 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002859 Py_INCREF(Py_None);
2860 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002861}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002862#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00002863
Guido van Rossumb6775db1994-08-01 11:34:53 +00002864#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002865static char posix_setpgid__doc__[] =
2866"setpgid(pid, pgrp) -> None\n\
2867Call the system call setpgid().";
2868
Barry Warsaw53699e91996-12-10 23:23:01 +00002869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002870posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002871{
2872 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002873 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002874 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002875 if (setpgid(pid, pgrp) < 0)
2876 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002877 Py_INCREF(Py_None);
2878 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002879}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002880#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00002881
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002882
Guido van Rossumb6775db1994-08-01 11:34:53 +00002883#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002884static char posix_tcgetpgrp__doc__[] =
2885"tcgetpgrp(fd) -> pgid\n\
2886Return the process group associated with the terminal given by a fd.";
2887
Barry Warsaw53699e91996-12-10 23:23:01 +00002888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002889posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00002890{
2891 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002892 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00002893 return NULL;
2894 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00002895 if (pgid < 0)
2896 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002897 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00002898}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002899#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00002900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002901
Guido van Rossumb6775db1994-08-01 11:34:53 +00002902#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002903static char posix_tcsetpgrp__doc__[] =
2904"tcsetpgrp(fd, pgid) -> None\n\
2905Set the process group associated with the terminal given by a fd.";
2906
Barry Warsaw53699e91996-12-10 23:23:01 +00002907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002908posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00002909{
2910 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002911 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00002912 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002913 if (tcsetpgrp(fd, pgid) < 0)
2914 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00002915 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00002916 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00002917}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002918#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00002919
Guido van Rossum687dd131993-05-17 08:34:16 +00002920/* Functions acting on file descriptors */
2921
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002922static char posix_open__doc__[] =
2923"open(filename, flag [, mode=0777]) -> fd\n\
2924Open a file (for low level IO).";
2925
Barry Warsaw53699e91996-12-10 23:23:01 +00002926static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002927posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002928{
2929 char *file;
2930 int flag;
2931 int mode = 0777;
2932 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00002933 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
2934 return NULL;
2935
Barry Warsaw53699e91996-12-10 23:23:01 +00002936 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002937 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002938 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002939 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002940 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00002941 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00002942}
2943
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002944
2945static char posix_close__doc__[] =
2946"close(fd) -> None\n\
2947Close a file descriptor (for low level IO).";
2948
Barry Warsaw53699e91996-12-10 23:23:01 +00002949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002950posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002951{
2952 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002953 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00002954 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002955 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002956 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00002957 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002958 if (res < 0)
2959 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002960 Py_INCREF(Py_None);
2961 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00002962}
2963
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002964
2965static char posix_dup__doc__[] =
2966"dup(fd) -> fd2\n\
2967Return a duplicate of a file descriptor.";
2968
Barry Warsaw53699e91996-12-10 23:23:01 +00002969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002970posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002971{
2972 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002973 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00002974 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002975 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002976 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00002977 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002978 if (fd < 0)
2979 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002980 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00002981}
2982
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002983
2984static char posix_dup2__doc__[] =
2985"dup2(fd, fd2) -> None\n\
2986Duplicate file descriptor.";
2987
Barry Warsaw53699e91996-12-10 23:23:01 +00002988static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002989posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002990{
2991 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002992 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00002993 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002994 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002995 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00002996 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002997 if (res < 0)
2998 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002999 Py_INCREF(Py_None);
3000 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003001}
3002
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003003
3004static char posix_lseek__doc__[] =
3005"lseek(fd, pos, how) -> newpos\n\
3006Set the current position of a file descriptor.";
3007
Barry Warsaw53699e91996-12-10 23:23:01 +00003008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003009posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003010{
3011 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003012#ifdef MS_WIN64
3013 LONG_LONG pos, res;
3014#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003015 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003016#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003017 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003018 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003019 return NULL;
3020#ifdef SEEK_SET
3021 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3022 switch (how) {
3023 case 0: how = SEEK_SET; break;
3024 case 1: how = SEEK_CUR; break;
3025 case 2: how = SEEK_END; break;
3026 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003027#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003028
3029#if !defined(HAVE_LARGEFILE_SUPPORT)
3030 pos = PyInt_AsLong(posobj);
3031#else
3032 pos = PyLong_Check(posobj) ?
3033 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3034#endif
3035 if (PyErr_Occurred())
3036 return NULL;
3037
Barry Warsaw53699e91996-12-10 23:23:01 +00003038 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003039#ifdef MS_WIN64
3040 res = _lseeki64(fd, pos, how);
3041#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003042 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003043#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003044 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003045 if (res < 0)
3046 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003047
3048#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003049 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003050#else
3051 return PyLong_FromLongLong(res);
3052#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003053}
3054
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003055
3056static char posix_read__doc__[] =
3057"read(fd, buffersize) -> string\n\
3058Read a file descriptor.";
3059
Barry Warsaw53699e91996-12-10 23:23:01 +00003060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003061posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003062{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003063 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003064 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003065 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003066 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003067 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003068 if (buffer == NULL)
3069 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003070 Py_BEGIN_ALLOW_THREADS
3071 n = read(fd, PyString_AsString(buffer), size);
3072 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003073 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003074 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003075 return posix_error();
3076 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003077 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003078 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003079 return buffer;
3080}
3081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003082
3083static char posix_write__doc__[] =
3084"write(fd, string) -> byteswritten\n\
3085Write a string to a file descriptor.";
3086
Barry Warsaw53699e91996-12-10 23:23:01 +00003087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003088posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003089{
3090 int fd, size;
3091 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003092 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003093 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003094 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003095 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003096 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003097 if (size < 0)
3098 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003099 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003100}
3101
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003102
3103static char posix_fstat__doc__[]=
3104"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3105Like stat(), but for an open file descriptor.";
3106
Barry Warsaw53699e91996-12-10 23:23:01 +00003107static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003108posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003109{
3110 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003111 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003112 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003113 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003114 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003115 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003116 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003117 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003118 if (res != 0)
3119 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003120
3121 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003122}
3123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003124
3125static char posix_fdopen__doc__[] =
3126"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3127Return an open file object connected to a file descriptor.";
3128
Barry Warsaw53699e91996-12-10 23:23:01 +00003129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003130posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003131{
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003132 extern int fclose(FILE *);
Guido van Rossum687dd131993-05-17 08:34:16 +00003133 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003134 char *mode = "r";
3135 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003136 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003137 PyObject *f;
3138 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003139 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003140
Barry Warsaw53699e91996-12-10 23:23:01 +00003141 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003142 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003143 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003144 if (fp == NULL)
3145 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003146 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003147 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003148 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003149 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003150}
3151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003152
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003153#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003154static char posix_pipe__doc__[] =
3155"pipe() -> (read_end, write_end)\n\
3156Create a pipe.";
3157
Barry Warsaw53699e91996-12-10 23:23:01 +00003158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003159posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003160{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003161#if defined(PYOS_OS2)
3162 HFILE read, write;
3163 APIRET rc;
3164
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003165 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003166 return NULL;
3167
3168 Py_BEGIN_ALLOW_THREADS
3169 rc = DosCreatePipe( &read, &write, 4096);
3170 Py_END_ALLOW_THREADS
3171 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003172 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003173
3174 return Py_BuildValue("(ii)", read, write);
3175#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003176#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003177 int fds[2];
3178 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003179 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003180 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003181 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003182 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003183 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003184 if (res != 0)
3185 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003186 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003187#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003188 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003189 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003190 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003191 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003192 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003193 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003194 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003195 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003196 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003197 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003198 read_fd = _open_osfhandle((intptr_t)read, 0);
3199 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003200 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003201#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003202#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003203}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003204#endif /* HAVE_PIPE */
3205
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003206
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003207#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003208static char posix_mkfifo__doc__[] =
3209"mkfifo(file, [, mode=0666]) -> None\n\
3210Create a FIFO (a POSIX named pipe).";
3211
Barry Warsaw53699e91996-12-10 23:23:01 +00003212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003213posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003214{
3215 char *file;
3216 int mode = 0666;
3217 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003218 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003219 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003220 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003221 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003222 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003223 if (res < 0)
3224 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003225 Py_INCREF(Py_None);
3226 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003227}
3228#endif
3229
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003230
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003231#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003232static char posix_ftruncate__doc__[] =
3233"ftruncate(fd, length) -> None\n\
3234Truncate a file to a specified length.";
3235
Barry Warsaw53699e91996-12-10 23:23:01 +00003236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003237posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003238{
3239 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003240 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003241 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003242 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003243
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003244 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003245 return NULL;
3246
3247#if !defined(HAVE_LARGEFILE_SUPPORT)
3248 length = PyInt_AsLong(lenobj);
3249#else
3250 length = PyLong_Check(lenobj) ?
3251 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3252#endif
3253 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003254 return NULL;
3255
Barry Warsaw53699e91996-12-10 23:23:01 +00003256 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003257 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003258 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003259 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003260 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003261 return NULL;
3262 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003263 Py_INCREF(Py_None);
3264 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003265}
3266#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003267
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003268#ifdef NeXT
3269#define HAVE_PUTENV
3270/* Steve Spicklemire got this putenv from NeXTAnswers */
3271static int
3272putenv(char *newval)
3273{
3274 extern char **environ;
3275
3276 static int firstTime = 1;
3277 char **ep;
3278 char *cp;
3279 int esiz;
3280 char *np;
3281
3282 if (!(np = strchr(newval, '=')))
3283 return 1;
3284 *np = '\0';
3285
3286 /* look it up */
3287 for (ep=environ ; *ep ; ep++)
3288 {
3289 /* this should always be true... */
3290 if (cp = strchr(*ep, '='))
3291 {
3292 *cp = '\0';
3293 if (!strcmp(*ep, newval))
3294 {
3295 /* got it! */
3296 *cp = '=';
3297 break;
3298 }
3299 *cp = '=';
3300 }
3301 else
3302 {
3303 *np = '=';
3304 return 1;
3305 }
3306 }
3307
3308 *np = '=';
3309 if (*ep)
3310 {
3311 /* the string was already there:
3312 just replace it with the new one */
3313 *ep = newval;
3314 return 0;
3315 }
3316
3317 /* expand environ by one */
3318 for (esiz=2, ep=environ ; *ep ; ep++)
3319 esiz++;
3320 if (firstTime)
3321 {
3322 char **epp;
3323 char **newenv;
3324 if (!(newenv = malloc(esiz * sizeof(char *))))
3325 return 1;
3326
3327 for (ep=environ, epp=newenv ; *ep ;)
3328 *epp++ = *ep++;
3329 *epp++ = newval;
3330 *epp = (char *) 0;
3331 environ = newenv;
3332 }
3333 else
3334 {
3335 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3336 return 1;
3337 environ[esiz - 2] = newval;
3338 environ[esiz - 1] = (char *) 0;
3339 firstTime = 0;
3340 }
3341
3342 return 0;
3343}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003344#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003346
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003347#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003348static char posix_putenv__doc__[] =
3349"putenv(key, value) -> None\n\
3350Change or add an environment variable.";
3351
Guido van Rossumbcc20741998-08-04 22:53:56 +00003352#ifdef __BEOS__
3353/* We have putenv(), but not in the headers (as of PR2). - [cjh] */
3354int putenv( const char *str );
3355#endif
3356
Fred Drake762e2061999-08-26 17:23:54 +00003357/* Save putenv() parameters as values here, so we can collect them when they
3358 * get re-set with another call for the same key. */
3359static PyObject *posix_putenv_garbage;
3360
Barry Warsaw53699e91996-12-10 23:23:01 +00003361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003362posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003363{
3364 char *s1, *s2;
3365 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003366 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003367
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003368 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003369 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003370
3371#if defined(PYOS_OS2)
3372 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3373 APIRET rc;
3374
3375 if (strlen(s2) == 0) /* If New Value is an Empty String */
3376 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3377
3378 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3379 if (rc != NO_ERROR)
3380 return os2_error(rc);
3381
3382 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3383 APIRET rc;
3384
3385 if (strlen(s2) == 0) /* If New Value is an Empty String */
3386 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3387
3388 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3389 if (rc != NO_ERROR)
3390 return os2_error(rc);
3391 } else {
3392#endif
3393
Fred Drake762e2061999-08-26 17:23:54 +00003394 /* XXX This can leak memory -- not easy to fix :-( */
3395 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3396 if (newstr == NULL)
3397 return PyErr_NoMemory();
3398 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003399 (void) sprintf(new, "%s=%s", s1, s2);
3400 if (putenv(new)) {
3401 posix_error();
3402 return NULL;
3403 }
Fred Drake762e2061999-08-26 17:23:54 +00003404 /* Install the first arg and newstr in posix_putenv_garbage;
3405 * this will cause previous value to be collected. This has to
3406 * happen after the real putenv() call because the old value
3407 * was still accessible until then. */
3408 if (PyDict_SetItem(posix_putenv_garbage,
3409 PyTuple_GET_ITEM(args, 0), newstr)) {
3410 /* really not much we can do; just leak */
3411 PyErr_Clear();
3412 }
3413 else {
3414 Py_DECREF(newstr);
3415 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003416
3417#if defined(PYOS_OS2)
3418 }
3419#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003420 Py_INCREF(Py_None);
3421 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003422}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003423#endif /* putenv */
3424
3425#ifdef HAVE_STRERROR
3426static char posix_strerror__doc__[] =
3427"strerror(code) -> string\n\
3428Translate an error code to a message string.";
3429
3430PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003431posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003432{
3433 int code;
3434 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003435 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003436 return NULL;
3437 message = strerror(code);
3438 if (message == NULL) {
3439 PyErr_SetString(PyExc_ValueError,
3440 "strerror code out of range");
3441 return NULL;
3442 }
3443 return PyString_FromString(message);
3444}
3445#endif /* strerror */
3446
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003447
Guido van Rossumc9641791998-08-04 15:26:23 +00003448#ifdef HAVE_SYS_WAIT_H
3449
3450#ifdef WIFSTOPPED
3451static char posix_WIFSTOPPED__doc__[] =
3452"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003453Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003454
3455static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003456posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003457{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003458#ifdef UNION_WAIT
3459 union wait status;
3460#define status_i (status.w_status)
3461#else
3462 int status;
3463#define status_i status
3464#endif
3465 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003466
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003467 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003468 {
3469 return NULL;
3470 }
3471
3472 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003473#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003474}
3475#endif /* WIFSTOPPED */
3476
3477#ifdef WIFSIGNALED
3478static char posix_WIFSIGNALED__doc__[] =
3479"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003480Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003481
3482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003483posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003484{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003485#ifdef UNION_WAIT
3486 union wait status;
3487#define status_i (status.w_status)
3488#else
3489 int status;
3490#define status_i status
3491#endif
3492 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003493
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003494 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003495 {
3496 return NULL;
3497 }
3498
3499 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003500#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003501}
3502#endif /* WIFSIGNALED */
3503
3504#ifdef WIFEXITED
3505static char posix_WIFEXITED__doc__[] =
3506"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003507Return true if the process returning 'status' exited using the exit()\n\
3508system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003509
3510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003511posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003512{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003513#ifdef UNION_WAIT
3514 union wait status;
3515#define status_i (status.w_status)
3516#else
3517 int status;
3518#define status_i status
3519#endif
3520 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003521
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003522 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003523 {
3524 return NULL;
3525 }
3526
3527 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003528#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003529}
3530#endif /* WIFEXITED */
3531
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003532#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003533static char posix_WEXITSTATUS__doc__[] =
3534"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003535Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003536
3537static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003538posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003539{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003540#ifdef UNION_WAIT
3541 union wait status;
3542#define status_i (status.w_status)
3543#else
3544 int status;
3545#define status_i status
3546#endif
3547 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003548
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003549 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003550 {
3551 return NULL;
3552 }
3553
3554 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003555#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003556}
3557#endif /* WEXITSTATUS */
3558
3559#ifdef WTERMSIG
3560static char posix_WTERMSIG__doc__[] =
3561"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003562Return the signal that terminated the process that provided the 'status'\n\
3563value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003564
3565static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003566posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003567{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003568#ifdef UNION_WAIT
3569 union wait status;
3570#define status_i (status.w_status)
3571#else
3572 int status;
3573#define status_i status
3574#endif
3575 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003576
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003577 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003578 {
3579 return NULL;
3580 }
3581
3582 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003583#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003584}
3585#endif /* WTERMSIG */
3586
3587#ifdef WSTOPSIG
3588static char posix_WSTOPSIG__doc__[] =
3589"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003590Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003591
3592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003593posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003594{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003595#ifdef UNION_WAIT
3596 union wait status;
3597#define status_i (status.w_status)
3598#else
3599 int status;
3600#define status_i status
3601#endif
3602 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003603
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003604 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003605 {
3606 return NULL;
3607 }
3608
3609 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003610#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003611}
3612#endif /* WSTOPSIG */
3613
3614#endif /* HAVE_SYS_WAIT_H */
3615
3616
Guido van Rossum94f6f721999-01-06 18:42:14 +00003617#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003618#ifdef _SCO_DS
3619/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3620 needed definitions in sys/statvfs.h */
3621#define _SVID3
3622#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003623#include <sys/statvfs.h>
3624
3625static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003626"fstatvfs(fd) -> \n\
3627 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003628Perform an fstatvfs system call on the given fd.";
3629
3630static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003631posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003632{
3633 int fd, res;
3634 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003635 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003636 return NULL;
3637 Py_BEGIN_ALLOW_THREADS
3638 res = fstatvfs(fd, &st);
3639 Py_END_ALLOW_THREADS
3640 if (res != 0)
3641 return posix_error();
3642#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003643 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003644 (long) st.f_bsize,
3645 (long) st.f_frsize,
3646 (long) st.f_blocks,
3647 (long) st.f_bfree,
3648 (long) st.f_bavail,
3649 (long) st.f_files,
3650 (long) st.f_ffree,
3651 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003652 (long) st.f_flag,
3653 (long) st.f_namemax);
3654#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003655 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003656 (long) st.f_bsize,
3657 (long) st.f_frsize,
3658 (LONG_LONG) st.f_blocks,
3659 (LONG_LONG) st.f_bfree,
3660 (LONG_LONG) st.f_bavail,
3661 (LONG_LONG) st.f_files,
3662 (LONG_LONG) st.f_ffree,
3663 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003664 (long) st.f_flag,
3665 (long) st.f_namemax);
3666#endif
3667}
3668#endif /* HAVE_FSTATVFS */
3669
3670
3671#if defined(HAVE_STATVFS)
3672#include <sys/statvfs.h>
3673
3674static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003675"statvfs(path) -> \n\
3676 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003677Perform a statvfs system call on the given path.";
3678
3679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003680posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003681{
3682 char *path;
3683 int res;
3684 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003685 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003686 return NULL;
3687 Py_BEGIN_ALLOW_THREADS
3688 res = statvfs(path, &st);
3689 Py_END_ALLOW_THREADS
3690 if (res != 0)
3691 return posix_error_with_filename(path);
3692#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003693 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003694 (long) st.f_bsize,
3695 (long) st.f_frsize,
3696 (long) st.f_blocks,
3697 (long) st.f_bfree,
3698 (long) st.f_bavail,
3699 (long) st.f_files,
3700 (long) st.f_ffree,
3701 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003702 (long) st.f_flag,
3703 (long) st.f_namemax);
3704#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003705 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003706 (long) st.f_bsize,
3707 (long) st.f_frsize,
3708 (LONG_LONG) st.f_blocks,
3709 (LONG_LONG) st.f_bfree,
3710 (LONG_LONG) st.f_bavail,
3711 (LONG_LONG) st.f_files,
3712 (LONG_LONG) st.f_ffree,
3713 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003714 (long) st.f_flag,
3715 (long) st.f_namemax);
3716#endif
3717}
3718#endif /* HAVE_STATVFS */
3719
3720
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003721#ifdef HAVE_TEMPNAM
3722static char posix_tempnam__doc__[] = "\
3723tempnam([dir[, prefix]]) -> string\n\
3724Return a unique name for a temporary file.\n\
3725The directory and a short may be specified as strings; they may be omitted\n\
3726or None if not needed.";
3727
3728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003729posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003730{
3731 PyObject *result = NULL;
3732 char *dir = NULL;
3733 char *pfx = NULL;
3734 char *name;
3735
3736 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
3737 return NULL;
3738 name = tempnam(dir, pfx);
3739 if (name == NULL)
3740 return PyErr_NoMemory();
3741 result = PyString_FromString(name);
3742 free(name);
3743 return result;
3744}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003745#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003746
3747
3748#ifdef HAVE_TMPFILE
3749static char posix_tmpfile__doc__[] = "\
3750tmpfile() -> file object\n\
3751Create a temporary file with no directory entries.";
3752
3753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003754posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003755{
3756 FILE *fp;
3757
3758 if (!PyArg_ParseTuple(args, ":tmpfile"))
3759 return NULL;
3760 fp = tmpfile();
3761 if (fp == NULL)
3762 return posix_error();
3763 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
3764}
3765#endif
3766
3767
3768#ifdef HAVE_TMPNAM
3769static char posix_tmpnam__doc__[] = "\
3770tmpnam() -> string\n\
3771Return a unique name for a temporary file.";
3772
3773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003774posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003775{
3776 char buffer[L_tmpnam];
3777 char *name;
3778
3779 if (!PyArg_ParseTuple(args, ":tmpnam"))
3780 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00003781#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003782 name = tmpnam_r(buffer);
3783#else
3784 name = tmpnam(buffer);
3785#endif
3786 if (name == NULL) {
3787 PyErr_SetObject(PyExc_OSError,
3788 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00003789#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003790 "unexpected NULL from tmpnam_r"
3791#else
3792 "unexpected NULL from tmpnam"
3793#endif
3794 ));
3795 return NULL;
3796 }
3797 return PyString_FromString(buffer);
3798}
3799#endif
3800
3801
Fred Drakec9680921999-12-13 16:37:25 +00003802/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
3803 * It maps strings representing configuration variable names to
3804 * integer values, allowing those functions to be called with the
3805 * magic names instead of poluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00003806 * rarely-used constants. There are three separate tables that use
3807 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00003808 *
3809 * This code is always included, even if none of the interfaces that
3810 * need it are included. The #if hackery needed to avoid it would be
3811 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00003812 */
3813struct constdef {
3814 char *name;
3815 long value;
3816};
3817
Fred Drake12c6e2d1999-12-14 21:25:03 +00003818static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003819conv_confname(PyObject *arg, int *valuep, struct constdef *table,
3820 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003821{
3822 if (PyInt_Check(arg)) {
3823 *valuep = PyInt_AS_LONG(arg);
3824 return 1;
3825 }
3826 if (PyString_Check(arg)) {
3827 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00003828 size_t lo = 0;
3829 size_t mid;
3830 size_t hi = tablesize;
3831 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003832 char *confname = PyString_AS_STRING(arg);
3833 while (lo < hi) {
3834 mid = (lo + hi) / 2;
3835 cmp = strcmp(confname, table[mid].name);
3836 if (cmp < 0)
3837 hi = mid;
3838 else if (cmp > 0)
3839 lo = mid + 1;
3840 else {
3841 *valuep = table[mid].value;
3842 return 1;
3843 }
3844 }
3845 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
3846 }
3847 else
3848 PyErr_SetString(PyExc_TypeError,
3849 "configuration names must be strings or integers");
3850 return 0;
3851}
3852
3853
3854#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
3855static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00003856#ifdef _PC_ABI_AIO_XFER_MAX
3857 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
3858#endif
3859#ifdef _PC_ABI_ASYNC_IO
3860 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
3861#endif
Fred Drakec9680921999-12-13 16:37:25 +00003862#ifdef _PC_ASYNC_IO
3863 {"PC_ASYNC_IO", _PC_ASYNC_IO},
3864#endif
3865#ifdef _PC_CHOWN_RESTRICTED
3866 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
3867#endif
3868#ifdef _PC_FILESIZEBITS
3869 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
3870#endif
3871#ifdef _PC_LAST
3872 {"PC_LAST", _PC_LAST},
3873#endif
3874#ifdef _PC_LINK_MAX
3875 {"PC_LINK_MAX", _PC_LINK_MAX},
3876#endif
3877#ifdef _PC_MAX_CANON
3878 {"PC_MAX_CANON", _PC_MAX_CANON},
3879#endif
3880#ifdef _PC_MAX_INPUT
3881 {"PC_MAX_INPUT", _PC_MAX_INPUT},
3882#endif
3883#ifdef _PC_NAME_MAX
3884 {"PC_NAME_MAX", _PC_NAME_MAX},
3885#endif
3886#ifdef _PC_NO_TRUNC
3887 {"PC_NO_TRUNC", _PC_NO_TRUNC},
3888#endif
3889#ifdef _PC_PATH_MAX
3890 {"PC_PATH_MAX", _PC_PATH_MAX},
3891#endif
3892#ifdef _PC_PIPE_BUF
3893 {"PC_PIPE_BUF", _PC_PIPE_BUF},
3894#endif
3895#ifdef _PC_PRIO_IO
3896 {"PC_PRIO_IO", _PC_PRIO_IO},
3897#endif
3898#ifdef _PC_SOCK_MAXBUF
3899 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
3900#endif
3901#ifdef _PC_SYNC_IO
3902 {"PC_SYNC_IO", _PC_SYNC_IO},
3903#endif
3904#ifdef _PC_VDISABLE
3905 {"PC_VDISABLE", _PC_VDISABLE},
3906#endif
3907};
3908
Fred Drakec9680921999-12-13 16:37:25 +00003909static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003910conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00003911{
3912 return conv_confname(arg, valuep, posix_constants_pathconf,
3913 sizeof(posix_constants_pathconf)
3914 / sizeof(struct constdef));
3915}
3916#endif
3917
3918#ifdef HAVE_FPATHCONF
3919static char posix_fpathconf__doc__[] = "\
3920fpathconf(fd, name) -> integer\n\
3921Return the configuration limit name for the file descriptor fd.\n\
3922If there is no limit, return -1.";
3923
3924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003925posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00003926{
3927 PyObject *result = NULL;
3928 int name, fd;
3929
Fred Drake12c6e2d1999-12-14 21:25:03 +00003930 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
3931 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00003932 long limit;
3933
3934 errno = 0;
3935 limit = fpathconf(fd, name);
3936 if (limit == -1 && errno != 0)
3937 posix_error();
3938 else
3939 result = PyInt_FromLong(limit);
3940 }
3941 return result;
3942}
3943#endif
3944
3945
3946#ifdef HAVE_PATHCONF
3947static char posix_pathconf__doc__[] = "\
3948pathconf(path, name) -> integer\n\
3949Return the configuration limit name for the file or directory path.\n\
3950If there is no limit, return -1.";
3951
3952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003953posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00003954{
3955 PyObject *result = NULL;
3956 int name;
3957 char *path;
3958
3959 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
3960 conv_path_confname, &name)) {
3961 long limit;
3962
3963 errno = 0;
3964 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00003965 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00003966 if (errno == EINVAL)
3967 /* could be a path or name problem */
3968 posix_error();
3969 else
3970 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00003971 }
Fred Drakec9680921999-12-13 16:37:25 +00003972 else
3973 result = PyInt_FromLong(limit);
3974 }
3975 return result;
3976}
3977#endif
3978
3979#ifdef HAVE_CONFSTR
3980static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00003981#ifdef _CS_ARCHITECTURE
3982 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
3983#endif
3984#ifdef _CS_HOSTNAME
3985 {"CS_HOSTNAME", _CS_HOSTNAME},
3986#endif
3987#ifdef _CS_HW_PROVIDER
3988 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
3989#endif
3990#ifdef _CS_HW_SERIAL
3991 {"CS_HW_SERIAL", _CS_HW_SERIAL},
3992#endif
3993#ifdef _CS_INITTAB_NAME
3994 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
3995#endif
Fred Drakec9680921999-12-13 16:37:25 +00003996#ifdef _CS_LFS64_CFLAGS
3997 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
3998#endif
3999#ifdef _CS_LFS64_LDFLAGS
4000 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4001#endif
4002#ifdef _CS_LFS64_LIBS
4003 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4004#endif
4005#ifdef _CS_LFS64_LINTFLAGS
4006 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4007#endif
4008#ifdef _CS_LFS_CFLAGS
4009 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4010#endif
4011#ifdef _CS_LFS_LDFLAGS
4012 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4013#endif
4014#ifdef _CS_LFS_LIBS
4015 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4016#endif
4017#ifdef _CS_LFS_LINTFLAGS
4018 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4019#endif
Fred Draked86ed291999-12-15 15:34:33 +00004020#ifdef _CS_MACHINE
4021 {"CS_MACHINE", _CS_MACHINE},
4022#endif
Fred Drakec9680921999-12-13 16:37:25 +00004023#ifdef _CS_PATH
4024 {"CS_PATH", _CS_PATH},
4025#endif
Fred Draked86ed291999-12-15 15:34:33 +00004026#ifdef _CS_RELEASE
4027 {"CS_RELEASE", _CS_RELEASE},
4028#endif
4029#ifdef _CS_SRPC_DOMAIN
4030 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4031#endif
4032#ifdef _CS_SYSNAME
4033 {"CS_SYSNAME", _CS_SYSNAME},
4034#endif
4035#ifdef _CS_VERSION
4036 {"CS_VERSION", _CS_VERSION},
4037#endif
Fred Drakec9680921999-12-13 16:37:25 +00004038#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4039 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4040#endif
4041#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4042 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4043#endif
4044#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4045 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4046#endif
4047#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4048 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4049#endif
4050#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4051 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4052#endif
4053#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4054 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4055#endif
4056#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4057 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4058#endif
4059#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4060 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4061#endif
4062#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4063 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4064#endif
4065#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4066 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4067#endif
4068#ifdef _CS_XBS5_LP64_OFF64_LIBS
4069 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4070#endif
4071#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4072 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4073#endif
4074#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4075 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4076#endif
4077#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4078 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4079#endif
4080#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4081 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4082#endif
4083#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4084 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4085#endif
Fred Draked86ed291999-12-15 15:34:33 +00004086#ifdef _MIPS_CS_AVAIL_PROCESSORS
4087 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4088#endif
4089#ifdef _MIPS_CS_BASE
4090 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4091#endif
4092#ifdef _MIPS_CS_HOSTID
4093 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4094#endif
4095#ifdef _MIPS_CS_HW_NAME
4096 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4097#endif
4098#ifdef _MIPS_CS_NUM_PROCESSORS
4099 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4100#endif
4101#ifdef _MIPS_CS_OSREL_MAJ
4102 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4103#endif
4104#ifdef _MIPS_CS_OSREL_MIN
4105 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4106#endif
4107#ifdef _MIPS_CS_OSREL_PATCH
4108 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4109#endif
4110#ifdef _MIPS_CS_OS_NAME
4111 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4112#endif
4113#ifdef _MIPS_CS_OS_PROVIDER
4114 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4115#endif
4116#ifdef _MIPS_CS_PROCESSORS
4117 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4118#endif
4119#ifdef _MIPS_CS_SERIAL
4120 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4121#endif
4122#ifdef _MIPS_CS_VENDOR
4123 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4124#endif
Fred Drakec9680921999-12-13 16:37:25 +00004125};
4126
4127static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004128conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004129{
4130 return conv_confname(arg, valuep, posix_constants_confstr,
4131 sizeof(posix_constants_confstr)
4132 / sizeof(struct constdef));
4133}
4134
4135static char posix_confstr__doc__[] = "\
4136confstr(name) -> string\n\
4137Return a string-valued system configuration variable.";
4138
4139static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004140posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004141{
4142 PyObject *result = NULL;
4143 int name;
4144 char buffer[64];
4145
4146 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4147 int len = confstr(name, buffer, sizeof(buffer));
4148
Fred Drakec9680921999-12-13 16:37:25 +00004149 errno = 0;
4150 if (len == 0) {
4151 if (errno != 0)
4152 posix_error();
4153 else
4154 result = PyString_FromString("");
4155 }
4156 else {
4157 if (len >= sizeof(buffer)) {
4158 result = PyString_FromStringAndSize(NULL, len);
4159 if (result != NULL)
4160 confstr(name, PyString_AS_STRING(result), len+1);
4161 }
4162 else
4163 result = PyString_FromString(buffer);
4164 }
4165 }
4166 return result;
4167}
4168#endif
4169
4170
4171#ifdef HAVE_SYSCONF
4172static struct constdef posix_constants_sysconf[] = {
4173#ifdef _SC_2_CHAR_TERM
4174 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4175#endif
4176#ifdef _SC_2_C_BIND
4177 {"SC_2_C_BIND", _SC_2_C_BIND},
4178#endif
4179#ifdef _SC_2_C_DEV
4180 {"SC_2_C_DEV", _SC_2_C_DEV},
4181#endif
4182#ifdef _SC_2_C_VERSION
4183 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4184#endif
4185#ifdef _SC_2_FORT_DEV
4186 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4187#endif
4188#ifdef _SC_2_FORT_RUN
4189 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4190#endif
4191#ifdef _SC_2_LOCALEDEF
4192 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4193#endif
4194#ifdef _SC_2_SW_DEV
4195 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4196#endif
4197#ifdef _SC_2_UPE
4198 {"SC_2_UPE", _SC_2_UPE},
4199#endif
4200#ifdef _SC_2_VERSION
4201 {"SC_2_VERSION", _SC_2_VERSION},
4202#endif
Fred Draked86ed291999-12-15 15:34:33 +00004203#ifdef _SC_ABI_ASYNCHRONOUS_IO
4204 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4205#endif
4206#ifdef _SC_ACL
4207 {"SC_ACL", _SC_ACL},
4208#endif
Fred Drakec9680921999-12-13 16:37:25 +00004209#ifdef _SC_AIO_LISTIO_MAX
4210 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4211#endif
Fred Drakec9680921999-12-13 16:37:25 +00004212#ifdef _SC_AIO_MAX
4213 {"SC_AIO_MAX", _SC_AIO_MAX},
4214#endif
4215#ifdef _SC_AIO_PRIO_DELTA_MAX
4216 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4217#endif
4218#ifdef _SC_ARG_MAX
4219 {"SC_ARG_MAX", _SC_ARG_MAX},
4220#endif
4221#ifdef _SC_ASYNCHRONOUS_IO
4222 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4223#endif
4224#ifdef _SC_ATEXIT_MAX
4225 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4226#endif
Fred Draked86ed291999-12-15 15:34:33 +00004227#ifdef _SC_AUDIT
4228 {"SC_AUDIT", _SC_AUDIT},
4229#endif
Fred Drakec9680921999-12-13 16:37:25 +00004230#ifdef _SC_AVPHYS_PAGES
4231 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4232#endif
4233#ifdef _SC_BC_BASE_MAX
4234 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4235#endif
4236#ifdef _SC_BC_DIM_MAX
4237 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4238#endif
4239#ifdef _SC_BC_SCALE_MAX
4240 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4241#endif
4242#ifdef _SC_BC_STRING_MAX
4243 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4244#endif
Fred Draked86ed291999-12-15 15:34:33 +00004245#ifdef _SC_CAP
4246 {"SC_CAP", _SC_CAP},
4247#endif
Fred Drakec9680921999-12-13 16:37:25 +00004248#ifdef _SC_CHARCLASS_NAME_MAX
4249 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4250#endif
4251#ifdef _SC_CHAR_BIT
4252 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4253#endif
4254#ifdef _SC_CHAR_MAX
4255 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4256#endif
4257#ifdef _SC_CHAR_MIN
4258 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4259#endif
4260#ifdef _SC_CHILD_MAX
4261 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4262#endif
4263#ifdef _SC_CLK_TCK
4264 {"SC_CLK_TCK", _SC_CLK_TCK},
4265#endif
4266#ifdef _SC_COHER_BLKSZ
4267 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4268#endif
4269#ifdef _SC_COLL_WEIGHTS_MAX
4270 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4271#endif
4272#ifdef _SC_DCACHE_ASSOC
4273 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4274#endif
4275#ifdef _SC_DCACHE_BLKSZ
4276 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4277#endif
4278#ifdef _SC_DCACHE_LINESZ
4279 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4280#endif
4281#ifdef _SC_DCACHE_SZ
4282 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4283#endif
4284#ifdef _SC_DCACHE_TBLKSZ
4285 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4286#endif
4287#ifdef _SC_DELAYTIMER_MAX
4288 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4289#endif
4290#ifdef _SC_EQUIV_CLASS_MAX
4291 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4292#endif
4293#ifdef _SC_EXPR_NEST_MAX
4294 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4295#endif
4296#ifdef _SC_FSYNC
4297 {"SC_FSYNC", _SC_FSYNC},
4298#endif
4299#ifdef _SC_GETGR_R_SIZE_MAX
4300 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4301#endif
4302#ifdef _SC_GETPW_R_SIZE_MAX
4303 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4304#endif
4305#ifdef _SC_ICACHE_ASSOC
4306 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4307#endif
4308#ifdef _SC_ICACHE_BLKSZ
4309 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4310#endif
4311#ifdef _SC_ICACHE_LINESZ
4312 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4313#endif
4314#ifdef _SC_ICACHE_SZ
4315 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4316#endif
Fred Draked86ed291999-12-15 15:34:33 +00004317#ifdef _SC_INF
4318 {"SC_INF", _SC_INF},
4319#endif
Fred Drakec9680921999-12-13 16:37:25 +00004320#ifdef _SC_INT_MAX
4321 {"SC_INT_MAX", _SC_INT_MAX},
4322#endif
4323#ifdef _SC_INT_MIN
4324 {"SC_INT_MIN", _SC_INT_MIN},
4325#endif
4326#ifdef _SC_IOV_MAX
4327 {"SC_IOV_MAX", _SC_IOV_MAX},
4328#endif
Fred Draked86ed291999-12-15 15:34:33 +00004329#ifdef _SC_IP_SECOPTS
4330 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4331#endif
Fred Drakec9680921999-12-13 16:37:25 +00004332#ifdef _SC_JOB_CONTROL
4333 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4334#endif
Fred Draked86ed291999-12-15 15:34:33 +00004335#ifdef _SC_KERN_POINTERS
4336 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4337#endif
4338#ifdef _SC_KERN_SIM
4339 {"SC_KERN_SIM", _SC_KERN_SIM},
4340#endif
Fred Drakec9680921999-12-13 16:37:25 +00004341#ifdef _SC_LINE_MAX
4342 {"SC_LINE_MAX", _SC_LINE_MAX},
4343#endif
4344#ifdef _SC_LOGIN_NAME_MAX
4345 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4346#endif
4347#ifdef _SC_LOGNAME_MAX
4348 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4349#endif
4350#ifdef _SC_LONG_BIT
4351 {"SC_LONG_BIT", _SC_LONG_BIT},
4352#endif
Fred Draked86ed291999-12-15 15:34:33 +00004353#ifdef _SC_MAC
4354 {"SC_MAC", _SC_MAC},
4355#endif
Fred Drakec9680921999-12-13 16:37:25 +00004356#ifdef _SC_MAPPED_FILES
4357 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4358#endif
4359#ifdef _SC_MAXPID
4360 {"SC_MAXPID", _SC_MAXPID},
4361#endif
4362#ifdef _SC_MB_LEN_MAX
4363 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4364#endif
4365#ifdef _SC_MEMLOCK
4366 {"SC_MEMLOCK", _SC_MEMLOCK},
4367#endif
4368#ifdef _SC_MEMLOCK_RANGE
4369 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4370#endif
4371#ifdef _SC_MEMORY_PROTECTION
4372 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4373#endif
4374#ifdef _SC_MESSAGE_PASSING
4375 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4376#endif
Fred Draked86ed291999-12-15 15:34:33 +00004377#ifdef _SC_MMAP_FIXED_ALIGNMENT
4378 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4379#endif
Fred Drakec9680921999-12-13 16:37:25 +00004380#ifdef _SC_MQ_OPEN_MAX
4381 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4382#endif
4383#ifdef _SC_MQ_PRIO_MAX
4384 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4385#endif
Fred Draked86ed291999-12-15 15:34:33 +00004386#ifdef _SC_NACLS_MAX
4387 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4388#endif
Fred Drakec9680921999-12-13 16:37:25 +00004389#ifdef _SC_NGROUPS_MAX
4390 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4391#endif
4392#ifdef _SC_NL_ARGMAX
4393 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4394#endif
4395#ifdef _SC_NL_LANGMAX
4396 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4397#endif
4398#ifdef _SC_NL_MSGMAX
4399 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4400#endif
4401#ifdef _SC_NL_NMAX
4402 {"SC_NL_NMAX", _SC_NL_NMAX},
4403#endif
4404#ifdef _SC_NL_SETMAX
4405 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4406#endif
4407#ifdef _SC_NL_TEXTMAX
4408 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4409#endif
4410#ifdef _SC_NPROCESSORS_CONF
4411 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4412#endif
4413#ifdef _SC_NPROCESSORS_ONLN
4414 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4415#endif
Fred Draked86ed291999-12-15 15:34:33 +00004416#ifdef _SC_NPROC_CONF
4417 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4418#endif
4419#ifdef _SC_NPROC_ONLN
4420 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4421#endif
Fred Drakec9680921999-12-13 16:37:25 +00004422#ifdef _SC_NZERO
4423 {"SC_NZERO", _SC_NZERO},
4424#endif
4425#ifdef _SC_OPEN_MAX
4426 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4427#endif
4428#ifdef _SC_PAGESIZE
4429 {"SC_PAGESIZE", _SC_PAGESIZE},
4430#endif
4431#ifdef _SC_PAGE_SIZE
4432 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4433#endif
4434#ifdef _SC_PASS_MAX
4435 {"SC_PASS_MAX", _SC_PASS_MAX},
4436#endif
4437#ifdef _SC_PHYS_PAGES
4438 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4439#endif
4440#ifdef _SC_PII
4441 {"SC_PII", _SC_PII},
4442#endif
4443#ifdef _SC_PII_INTERNET
4444 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4445#endif
4446#ifdef _SC_PII_INTERNET_DGRAM
4447 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4448#endif
4449#ifdef _SC_PII_INTERNET_STREAM
4450 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4451#endif
4452#ifdef _SC_PII_OSI
4453 {"SC_PII_OSI", _SC_PII_OSI},
4454#endif
4455#ifdef _SC_PII_OSI_CLTS
4456 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4457#endif
4458#ifdef _SC_PII_OSI_COTS
4459 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4460#endif
4461#ifdef _SC_PII_OSI_M
4462 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4463#endif
4464#ifdef _SC_PII_SOCKET
4465 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4466#endif
4467#ifdef _SC_PII_XTI
4468 {"SC_PII_XTI", _SC_PII_XTI},
4469#endif
4470#ifdef _SC_POLL
4471 {"SC_POLL", _SC_POLL},
4472#endif
4473#ifdef _SC_PRIORITIZED_IO
4474 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4475#endif
4476#ifdef _SC_PRIORITY_SCHEDULING
4477 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4478#endif
4479#ifdef _SC_REALTIME_SIGNALS
4480 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4481#endif
4482#ifdef _SC_RE_DUP_MAX
4483 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4484#endif
4485#ifdef _SC_RTSIG_MAX
4486 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4487#endif
4488#ifdef _SC_SAVED_IDS
4489 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4490#endif
4491#ifdef _SC_SCHAR_MAX
4492 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4493#endif
4494#ifdef _SC_SCHAR_MIN
4495 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4496#endif
4497#ifdef _SC_SELECT
4498 {"SC_SELECT", _SC_SELECT},
4499#endif
4500#ifdef _SC_SEMAPHORES
4501 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4502#endif
4503#ifdef _SC_SEM_NSEMS_MAX
4504 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4505#endif
4506#ifdef _SC_SEM_VALUE_MAX
4507 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4508#endif
4509#ifdef _SC_SHARED_MEMORY_OBJECTS
4510 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4511#endif
4512#ifdef _SC_SHRT_MAX
4513 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4514#endif
4515#ifdef _SC_SHRT_MIN
4516 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4517#endif
4518#ifdef _SC_SIGQUEUE_MAX
4519 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4520#endif
4521#ifdef _SC_SIGRT_MAX
4522 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4523#endif
4524#ifdef _SC_SIGRT_MIN
4525 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4526#endif
Fred Draked86ed291999-12-15 15:34:33 +00004527#ifdef _SC_SOFTPOWER
4528 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4529#endif
Fred Drakec9680921999-12-13 16:37:25 +00004530#ifdef _SC_SPLIT_CACHE
4531 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4532#endif
4533#ifdef _SC_SSIZE_MAX
4534 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4535#endif
4536#ifdef _SC_STACK_PROT
4537 {"SC_STACK_PROT", _SC_STACK_PROT},
4538#endif
4539#ifdef _SC_STREAM_MAX
4540 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4541#endif
4542#ifdef _SC_SYNCHRONIZED_IO
4543 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4544#endif
4545#ifdef _SC_THREADS
4546 {"SC_THREADS", _SC_THREADS},
4547#endif
4548#ifdef _SC_THREAD_ATTR_STACKADDR
4549 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4550#endif
4551#ifdef _SC_THREAD_ATTR_STACKSIZE
4552 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4553#endif
4554#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4555 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4556#endif
4557#ifdef _SC_THREAD_KEYS_MAX
4558 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4559#endif
4560#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4561 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4562#endif
4563#ifdef _SC_THREAD_PRIO_INHERIT
4564 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4565#endif
4566#ifdef _SC_THREAD_PRIO_PROTECT
4567 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4568#endif
4569#ifdef _SC_THREAD_PROCESS_SHARED
4570 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4571#endif
4572#ifdef _SC_THREAD_SAFE_FUNCTIONS
4573 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4574#endif
4575#ifdef _SC_THREAD_STACK_MIN
4576 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4577#endif
4578#ifdef _SC_THREAD_THREADS_MAX
4579 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4580#endif
4581#ifdef _SC_TIMERS
4582 {"SC_TIMERS", _SC_TIMERS},
4583#endif
4584#ifdef _SC_TIMER_MAX
4585 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4586#endif
4587#ifdef _SC_TTY_NAME_MAX
4588 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4589#endif
4590#ifdef _SC_TZNAME_MAX
4591 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4592#endif
4593#ifdef _SC_T_IOV_MAX
4594 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4595#endif
4596#ifdef _SC_UCHAR_MAX
4597 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4598#endif
4599#ifdef _SC_UINT_MAX
4600 {"SC_UINT_MAX", _SC_UINT_MAX},
4601#endif
4602#ifdef _SC_UIO_MAXIOV
4603 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4604#endif
4605#ifdef _SC_ULONG_MAX
4606 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4607#endif
4608#ifdef _SC_USHRT_MAX
4609 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4610#endif
4611#ifdef _SC_VERSION
4612 {"SC_VERSION", _SC_VERSION},
4613#endif
4614#ifdef _SC_WORD_BIT
4615 {"SC_WORD_BIT", _SC_WORD_BIT},
4616#endif
4617#ifdef _SC_XBS5_ILP32_OFF32
4618 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4619#endif
4620#ifdef _SC_XBS5_ILP32_OFFBIG
4621 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4622#endif
4623#ifdef _SC_XBS5_LP64_OFF64
4624 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4625#endif
4626#ifdef _SC_XBS5_LPBIG_OFFBIG
4627 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
4628#endif
4629#ifdef _SC_XOPEN_CRYPT
4630 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
4631#endif
4632#ifdef _SC_XOPEN_ENH_I18N
4633 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
4634#endif
4635#ifdef _SC_XOPEN_LEGACY
4636 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
4637#endif
4638#ifdef _SC_XOPEN_REALTIME
4639 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
4640#endif
4641#ifdef _SC_XOPEN_REALTIME_THREADS
4642 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
4643#endif
4644#ifdef _SC_XOPEN_SHM
4645 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
4646#endif
4647#ifdef _SC_XOPEN_UNIX
4648 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
4649#endif
4650#ifdef _SC_XOPEN_VERSION
4651 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
4652#endif
4653#ifdef _SC_XOPEN_XCU_VERSION
4654 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
4655#endif
4656#ifdef _SC_XOPEN_XPG2
4657 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
4658#endif
4659#ifdef _SC_XOPEN_XPG3
4660 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
4661#endif
4662#ifdef _SC_XOPEN_XPG4
4663 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
4664#endif
4665};
4666
4667static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004668conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004669{
4670 return conv_confname(arg, valuep, posix_constants_sysconf,
4671 sizeof(posix_constants_sysconf)
4672 / sizeof(struct constdef));
4673}
4674
4675static char posix_sysconf__doc__[] = "\
4676sysconf(name) -> integer\n\
4677Return an integer-valued system configuration variable.";
4678
4679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004680posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004681{
4682 PyObject *result = NULL;
4683 int name;
4684
4685 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
4686 int value;
4687
4688 errno = 0;
4689 value = sysconf(name);
4690 if (value == -1 && errno != 0)
4691 posix_error();
4692 else
4693 result = PyInt_FromLong(value);
4694 }
4695 return result;
4696}
4697#endif
4698
4699
Fred Drakebec628d1999-12-15 18:31:10 +00004700/* This code is used to ensure that the tables of configuration value names
4701 * are in sorted order as required by conv_confname(), and also to build the
4702 * the exported dictionaries that are used to publish information about the
4703 * names available on the host platform.
4704 *
4705 * Sorting the table at runtime ensures that the table is properly ordered
4706 * when used, even for platforms we're not able to test on. It also makes
4707 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00004708 */
Fred Drakebec628d1999-12-15 18:31:10 +00004709
4710static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004711cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00004712{
4713 const struct constdef *c1 =
4714 (const struct constdef *) v1;
4715 const struct constdef *c2 =
4716 (const struct constdef *) v2;
4717
4718 return strcmp(c1->name, c2->name);
4719}
4720
4721static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004722setup_confname_table(struct constdef *table, size_t tablesize,
4723 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004724{
Fred Drakebec628d1999-12-15 18:31:10 +00004725 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00004726 size_t i;
4727 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00004728
4729 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
4730 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00004731 if (d == NULL)
4732 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004733
Barry Warsaw3155db32000-04-13 15:20:40 +00004734 for (i=0; i < tablesize; ++i) {
4735 PyObject *o = PyInt_FromLong(table[i].value);
4736 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
4737 Py_XDECREF(o);
4738 Py_DECREF(d);
4739 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004740 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004741 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00004742 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004743 status = PyDict_SetItemString(moddict, tablename, d);
4744 Py_DECREF(d);
4745 return status;
Fred Draked86ed291999-12-15 15:34:33 +00004746}
4747
Fred Drakebec628d1999-12-15 18:31:10 +00004748/* Return -1 on failure, 0 on success. */
4749static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004750setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004751{
4752#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00004753 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00004754 sizeof(posix_constants_pathconf)
4755 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004756 "pathconf_names", moddict))
4757 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004758#endif
4759#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00004760 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00004761 sizeof(posix_constants_confstr)
4762 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004763 "confstr_names", moddict))
4764 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004765#endif
4766#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00004767 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00004768 sizeof(posix_constants_sysconf)
4769 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004770 "sysconf_names", moddict))
4771 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004772#endif
Fred Drakebec628d1999-12-15 18:31:10 +00004773 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00004774}
Fred Draked86ed291999-12-15 15:34:33 +00004775
4776
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004777static char posix_abort__doc__[] = "\
4778abort() -> does not return!\n\
4779Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
4780in the hardest way possible on the hosting operating system.";
4781
4782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004783posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004784{
4785 if (!PyArg_ParseTuple(args, ":abort"))
4786 return NULL;
4787 abort();
4788 /*NOTREACHED*/
4789 Py_FatalError("abort() called from Python code didn't abort!");
4790 return NULL;
4791}
Fred Drakebec628d1999-12-15 18:31:10 +00004792
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004793
4794static PyMethodDef posix_methods[] = {
4795 {"access", posix_access, METH_VARARGS, posix_access__doc__},
4796#ifdef HAVE_TTYNAME
4797 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
4798#endif
4799 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
4800 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004801#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004802 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004803#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004804#ifdef HAVE_CTERMID
4805 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
4806#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00004807#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004808 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00004809#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004810#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004811 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004812#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004813 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
4814 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
4815 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004816#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004817 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004818#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004819#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004820 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004821#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004822 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
4823 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
4824 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004825#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004826 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004827#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004828#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004829 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004830#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004831 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004832#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004833 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004834#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004835 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
4836 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
4837 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004838#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004839 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004840#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004841 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004842#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004843 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
4844 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004845#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00004846#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004847 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
4848 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00004849#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004850#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004851 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004852#endif /* HAVE_FORK */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004853#ifdef HAVE_OPENPTY
4854 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
4855#endif /* HAVE_OPENPTY */
4856#ifdef HAVE_FORKPTY
4857 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
4858#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004859#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004860 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004861#endif /* HAVE_GETEGID */
4862#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004863 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004864#endif /* HAVE_GETEUID */
4865#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004866 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004867#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00004868#ifdef HAVE_GETGROUPS
4869 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
4870#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004871 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004872#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004873 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004874#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004875#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004876 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004877#endif /* HAVE_GETPPID */
4878#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004879 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004880#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004881#ifdef HAVE_GETLOGIN
4882 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
4883#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00004884#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004885 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004886#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00004887#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004888 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00004889#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004890#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004891 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004892#ifdef MS_WIN32
4893 {"popen2", win32_popen2, METH_VARARGS},
4894 {"popen3", win32_popen3, METH_VARARGS},
4895 {"popen4", win32_popen4, METH_VARARGS},
4896#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004897#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004898#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004899 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004900#endif /* HAVE_SETUID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004901#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004902 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004903#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004904#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004905 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004906#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004907#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004908 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004909#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004910#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004911 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004912#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004913#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004914 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004915#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004916#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004917 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004918#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004919#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004920 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004921#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004922#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004923 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004924#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004925 {"open", posix_open, METH_VARARGS, posix_open__doc__},
4926 {"close", posix_close, METH_VARARGS, posix_close__doc__},
4927 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
4928 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
4929 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
4930 {"read", posix_read, METH_VARARGS, posix_read__doc__},
4931 {"write", posix_write, METH_VARARGS, posix_write__doc__},
4932 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
4933 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004934#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004935 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004936#endif
4937#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004938 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004939#endif
4940#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004941 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004942#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004943#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004944 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004945#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00004946#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004947 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00004948#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00004949#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004950 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00004951#endif
4952#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004953 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00004954#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00004955#ifdef HAVE_SYS_WAIT_H
4956#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004957 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004958#endif /* WIFSTOPPED */
4959#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004960 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004961#endif /* WIFSIGNALED */
4962#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004963 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004964#endif /* WIFEXITED */
4965#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004966 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004967#endif /* WEXITSTATUS */
4968#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004969 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004970#endif /* WTERMSIG */
4971#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004972 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004973#endif /* WSTOPSIG */
4974#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004975#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004976 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00004977#endif
4978#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004979 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00004980#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004981#ifdef HAVE_TMPNAM
4982 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
4983#endif
4984#ifdef HAVE_TEMPNAM
4985 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
4986#endif
4987#ifdef HAVE_TMPNAM
4988 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
4989#endif
Fred Drakec9680921999-12-13 16:37:25 +00004990#ifdef HAVE_CONFSTR
4991 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
4992#endif
4993#ifdef HAVE_SYSCONF
4994 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
4995#endif
4996#ifdef HAVE_FPATHCONF
4997 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
4998#endif
4999#ifdef HAVE_PATHCONF
5000 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5001#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005002 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005003 {NULL, NULL} /* Sentinel */
5004};
5005
5006
Barry Warsaw4a342091996-12-19 23:50:02 +00005007static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005008ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005009{
5010 PyObject* v = PyInt_FromLong(value);
5011 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5012 return -1; /* triggers fatal error */
5013
5014 Py_DECREF(v);
5015 return 0;
5016}
5017
Guido van Rossumd48f2521997-12-05 22:19:34 +00005018#if defined(PYOS_OS2)
5019/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5020static int insertvalues(PyObject *d)
5021{
5022 APIRET rc;
5023 ULONG values[QSV_MAX+1];
5024 PyObject *v;
5025 char *ver, tmp[10];
5026
5027 Py_BEGIN_ALLOW_THREADS
5028 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5029 Py_END_ALLOW_THREADS
5030
5031 if (rc != NO_ERROR) {
5032 os2_error(rc);
5033 return -1;
5034 }
5035
5036 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5037 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5038 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5039 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5040 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5041 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5042 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5043
5044 switch (values[QSV_VERSION_MINOR]) {
5045 case 0: ver = "2.00"; break;
5046 case 10: ver = "2.10"; break;
5047 case 11: ver = "2.11"; break;
5048 case 30: ver = "3.00"; break;
5049 case 40: ver = "4.00"; break;
5050 case 50: ver = "5.00"; break;
5051 default:
5052 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5053 values[QSV_VERSION_MINOR]);
5054 ver = &tmp[0];
5055 }
5056
5057 /* Add Indicator of the Version of the Operating System */
5058 v = PyString_FromString(ver);
5059 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5060 return -1;
5061 Py_DECREF(v);
5062
5063 /* Add Indicator of Which Drive was Used to Boot the System */
5064 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5065 tmp[1] = ':';
5066 tmp[2] = '\0';
5067
5068 v = PyString_FromString(tmp);
5069 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5070 return -1;
5071 Py_DECREF(v);
5072
5073 return 0;
5074}
5075#endif
5076
Barry Warsaw4a342091996-12-19 23:50:02 +00005077static int
5078all_ins(d)
5079 PyObject* d;
5080{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005081#ifdef F_OK
5082 if (ins(d, "F_OK", (long)F_OK)) return -1;
5083#endif
5084#ifdef R_OK
5085 if (ins(d, "R_OK", (long)R_OK)) return -1;
5086#endif
5087#ifdef W_OK
5088 if (ins(d, "W_OK", (long)W_OK)) return -1;
5089#endif
5090#ifdef X_OK
5091 if (ins(d, "X_OK", (long)X_OK)) return -1;
5092#endif
Fred Drakec9680921999-12-13 16:37:25 +00005093#ifdef NGROUPS_MAX
5094 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5095#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005096#ifdef TMP_MAX
5097 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5098#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005099#ifdef WNOHANG
5100 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5101#endif
5102#ifdef O_RDONLY
5103 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5104#endif
5105#ifdef O_WRONLY
5106 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5107#endif
5108#ifdef O_RDWR
5109 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5110#endif
5111#ifdef O_NDELAY
5112 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5113#endif
5114#ifdef O_NONBLOCK
5115 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5116#endif
5117#ifdef O_APPEND
5118 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5119#endif
5120#ifdef O_DSYNC
5121 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5122#endif
5123#ifdef O_RSYNC
5124 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5125#endif
5126#ifdef O_SYNC
5127 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5128#endif
5129#ifdef O_NOCTTY
5130 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5131#endif
5132#ifdef O_CREAT
5133 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5134#endif
5135#ifdef O_EXCL
5136 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5137#endif
5138#ifdef O_TRUNC
5139 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5140#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005141#ifdef O_BINARY
5142 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5143#endif
5144#ifdef O_TEXT
5145 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5146#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005147
Guido van Rossum246bc171999-02-01 23:54:31 +00005148#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005149 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5150 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5151 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5152 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5153 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005154#endif
5155
Guido van Rossumd48f2521997-12-05 22:19:34 +00005156#if defined(PYOS_OS2)
5157 if (insertvalues(d)) return -1;
5158#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005159 return 0;
5160}
5161
5162
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005163#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005164#define INITFUNC initnt
5165#define MODNAME "nt"
5166#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005167#if defined(PYOS_OS2)
5168#define INITFUNC initos2
5169#define MODNAME "os2"
5170#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005171#define INITFUNC initposix
5172#define MODNAME "posix"
5173#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005174#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005175
Guido van Rossum3886bb61998-12-04 18:50:17 +00005176DL_EXPORT(void)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005177INITFUNC()
Guido van Rossumb6775db1994-08-01 11:34:53 +00005178{
Barry Warsaw53699e91996-12-10 23:23:01 +00005179 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005180
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005181 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005182 posix_methods,
5183 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005184 (PyObject *)NULL,
5185 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005186 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005187
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005188 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005189 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005190 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005191 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005192 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005193
Barry Warsaw4a342091996-12-19 23:50:02 +00005194 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005195 return;
5196
Fred Drakebec628d1999-12-15 18:31:10 +00005197 if (setup_confname_tables(d))
5198 return;
5199
Barry Warsawca74da41999-02-09 19:31:45 +00005200 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005201
Guido van Rossumb3d39562000-01-31 18:41:26 +00005202#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00005203 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005204#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005205}