blob: 8ea404e579b27fb70a00d037f7fed9aeef391c8f [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
Barry Warsaw53699e91996-12-10 23:23:01 +0000515static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000516posix_strintint(PyObject *args, char *format,
517 int (*func)(const char *, int, int))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000518{
519 char *path;
520 int i,i2;
521 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000522 if (!PyArg_ParseTuple(args, format, &path, &i, &i2))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000523 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000524 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000525 res = (*func)(path, i, i2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000526 Py_END_ALLOW_THREADS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000527 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000528 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +0000529 Py_INCREF(Py_None);
530 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000531}
532
Fred Drake699f3522000-06-29 21:12:41 +0000533
534
535/* pack a system stat C structure into the Python stat tuple
536 (used by posix_stat() and posix_fstat()) */
537static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000538_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000539{
540 PyObject *v = PyTuple_New(10);
541 if (v == NULL)
542 return NULL;
543
544 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
545#ifdef HAVE_LARGEFILE_SUPPORT
546 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
547#else
548 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
549#endif
550#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
551 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
552#else
553 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
554#endif
555 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
556 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
557 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
558#ifdef HAVE_LARGEFILE_SUPPORT
559 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
560#else
561 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
562#endif
563#if SIZEOF_TIME_T > SIZEOF_LONG
564 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
565 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
566 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
567#else
568 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
569 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
570 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
571#endif
572
573 if (PyErr_Occurred()) {
574 Py_DECREF(v);
575 return NULL;
576 }
577
578 return v;
579}
580
581
Barry Warsaw53699e91996-12-10 23:23:01 +0000582static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000583posix_do_stat(PyObject *self, PyObject *args, char *format,
584 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000585{
Fred Drake699f3522000-06-29 21:12:41 +0000586 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000587 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000588 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000589
590#ifdef MS_WIN32
591 int pathlen;
592 char pathcopy[MAX_PATH];
593#endif /* MS_WIN32 */
594
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000595 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000596 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000597
598#ifdef MS_WIN32
599 pathlen = strlen(path);
600 /* the library call can blow up if the file name is too long! */
601 if (pathlen > MAX_PATH) {
602 errno = ENAMETOOLONG;
603 return posix_error();
604 }
605
606 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000607 /* exception for specific or current drive root */
608 if (!((pathlen == 1) ||
609 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000610 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000611 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000612 {
613 strncpy(pathcopy, path, pathlen);
614 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
615 path = pathcopy;
616 }
617 }
618#endif /* MS_WIN32 */
619
Barry Warsaw53699e91996-12-10 23:23:01 +0000620 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000621 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000622 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000623 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000624 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000625
626 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000627}
628
629
630/* POSIX methods */
631
Guido van Rossum94f6f721999-01-06 18:42:14 +0000632static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000633"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000634Test for access to a file.";
635
636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000637posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000638{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000639 char *path;
640 int mode;
641 int res;
642
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000643 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000644 return NULL;
645 Py_BEGIN_ALLOW_THREADS
646 res = access(path, mode);
647 Py_END_ALLOW_THREADS
648 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000649}
650
Guido van Rossumd371ff11999-01-25 16:12:23 +0000651#ifndef F_OK
652#define F_OK 0
653#endif
654#ifndef R_OK
655#define R_OK 4
656#endif
657#ifndef W_OK
658#define W_OK 2
659#endif
660#ifndef X_OK
661#define X_OK 1
662#endif
663
664#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000665static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000666"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000667Return the name of the terminal device connected to 'fd'.";
668
669static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000670posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000671{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000672 int id;
673 char *ret;
674
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000675 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000676 return NULL;
677
Guido van Rossum94f6f721999-01-06 18:42:14 +0000678 ret = ttyname(id);
679 if (ret == NULL)
680 return(posix_error());
681 return(PyString_FromString(ret));
682}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000683#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000684
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000685#ifdef HAVE_CTERMID
686static char posix_ctermid__doc__[] =
687"ctermid() -> String\n\
688Return the name of the controlling terminal for this process.";
689
690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000691posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000692{
693 char *ret;
694 char buffer[L_ctermid];
695
696 if (!PyArg_ParseTuple(args, ":ctermid"))
697 return NULL;
698
Greg Wardb48bc172000-03-01 21:51:56 +0000699#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000700 ret = ctermid_r(buffer);
701#else
702 ret = ctermid(buffer);
703#endif
704 if (ret == NULL)
705 return(posix_error());
706 return(PyString_FromString(buffer));
707}
708#endif
709
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000710static char posix_chdir__doc__[] =
711"chdir(path) -> None\n\
712Change the current working directory to the specified path.";
713
Barry Warsaw53699e91996-12-10 23:23:01 +0000714static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000715posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000716{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000717 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000718}
719
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000720
721static char posix_chmod__doc__[] =
722"chmod(path, mode) -> None\n\
723Change the access permissions of a file.";
724
Barry Warsaw53699e91996-12-10 23:23:01 +0000725static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000726posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000727{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000728 char *path;
729 int i;
730 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000731 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000732 return NULL;
733 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000734 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000735 Py_END_ALLOW_THREADS
736 if (res < 0)
737 return posix_error_with_filename(path);
738 Py_INCREF(Py_None);
739 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740}
741
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000742
Guido van Rossum21142a01999-01-08 21:05:37 +0000743#ifdef HAVE_FSYNC
744static char posix_fsync__doc__[] =
745"fsync(fildes) -> None\n\
746force write of file with filedescriptor to disk.";
747
748static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000749posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000750{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000751 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000752}
753#endif /* HAVE_FSYNC */
754
755#ifdef HAVE_FDATASYNC
756static char posix_fdatasync__doc__[] =
757"fdatasync(fildes) -> None\n\
758force write of file with filedescriptor to disk.\n\
759 does not force update of metadata.";
760
Guido van Rossum5d00b6d1999-01-08 21:28:05 +0000761extern int fdatasync(int); /* Prototype just in case */
762
Guido van Rossum21142a01999-01-08 21:05:37 +0000763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000764posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000765{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000766 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000767}
768#endif /* HAVE_FDATASYNC */
769
770
Guido van Rossumb6775db1994-08-01 11:34:53 +0000771#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000772static char posix_chown__doc__[] =
773"chown(path, uid, gid) -> None\n\
774Change the owner and group id of path to the numeric uid and gid.";
775
Barry Warsaw53699e91996-12-10 23:23:01 +0000776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000777posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000778{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000779 return posix_strintint(args, "sii:chown", chown);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000780}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000781#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000783
Guido van Rossum36bc6801995-06-14 22:54:23 +0000784#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000785static char posix_getcwd__doc__[] =
786"getcwd() -> path\n\
787Return a string representing the current working directory.";
788
Barry Warsaw53699e91996-12-10 23:23:01 +0000789static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000790posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000791{
792 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000793 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000794 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000795 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000796 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000797 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000798 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000799 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000800 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000801 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000802}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000803#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000805
Guido van Rossumb6775db1994-08-01 11:34:53 +0000806#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000807static char posix_link__doc__[] =
808"link(src, dst) -> None\n\
809Create a hard link to a file.";
810
Barry Warsaw53699e91996-12-10 23:23:01 +0000811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000812posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000813{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000814 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000815}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000816#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000818
819static char posix_listdir__doc__[] =
820"listdir(path) -> list_of_strings\n\
821Return a list containing the names of the entries in the directory.\n\
822\n\
823 path: path of directory to list\n\
824\n\
825The list is in arbitrary order. It does not include the special\n\
826entries '.' and '..' even if they are present in the directory.";
827
Barry Warsaw53699e91996-12-10 23:23:01 +0000828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000829posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000830{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000831 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000832 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000833#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000834
Guido van Rossumb6775db1994-08-01 11:34:53 +0000835 char *name;
836 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000837 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000838 HANDLE hFindFile;
839 WIN32_FIND_DATA FileData;
840 char namebuf[MAX_PATH+5];
841
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000842 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000843 return NULL;
844 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000845 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000846 return NULL;
847 }
848 strcpy(namebuf, name);
849 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
850 namebuf[len++] = '/';
851 strcpy(namebuf + len, "*.*");
852
Barry Warsaw53699e91996-12-10 23:23:01 +0000853 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000854 return NULL;
855
856 hFindFile = FindFirstFile(namebuf, &FileData);
857 if (hFindFile == INVALID_HANDLE_VALUE) {
858 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000859 if (errno == ERROR_FILE_NOT_FOUND)
860 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000861 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000862 }
863 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000864 if (FileData.cFileName[0] == '.' &&
865 (FileData.cFileName[1] == '\0' ||
866 FileData.cFileName[1] == '.' &&
867 FileData.cFileName[2] == '\0'))
868 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000869 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000870 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000871 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000872 d = NULL;
873 break;
874 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000875 if (PyList_Append(d, v) != 0) {
876 Py_DECREF(v);
877 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000878 d = NULL;
879 break;
880 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000881 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000882 } while (FindNextFile(hFindFile, &FileData) == TRUE);
883
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000884 if (FindClose(hFindFile) == FALSE)
885 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000886
887 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000888
Guido van Rossum8d665e61996-06-26 18:22:49 +0000889#else /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000890#ifdef _MSC_VER /* 16-bit Windows */
891
892#ifndef MAX_PATH
893#define MAX_PATH 250
894#endif
895 char *name, *pt;
896 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000897 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000898 char namebuf[MAX_PATH+5];
899 struct _find_t ep;
900
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000901 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000902 return NULL;
903 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000904 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000905 return NULL;
906 }
907 strcpy(namebuf, name);
908 for (pt = namebuf; *pt; pt++)
909 if (*pt == '/')
910 *pt = '\\';
911 if (namebuf[len-1] != '\\')
912 namebuf[len++] = '\\';
913 strcpy(namebuf + len, "*.*");
914
Barry Warsaw53699e91996-12-10 23:23:01 +0000915 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000916 return NULL;
917
918 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000919 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
920 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000921 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000922 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000923 }
924 do {
925 if (ep.name[0] == '.' &&
926 (ep.name[1] == '\0' ||
927 ep.name[1] == '.' &&
928 ep.name[2] == '\0'))
929 continue;
930 strcpy(namebuf, ep.name);
931 for (pt = namebuf; *pt; pt++)
932 if (isupper(*pt))
933 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000934 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000935 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000936 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000937 d = NULL;
938 break;
939 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000940 if (PyList_Append(d, v) != 0) {
941 Py_DECREF(v);
942 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000943 d = NULL;
944 break;
945 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000946 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000947 } while (_dos_findnext(&ep) == 0);
948
949 return d;
950
951#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000952#if defined(PYOS_OS2)
953
954#ifndef MAX_PATH
955#define MAX_PATH CCHMAXPATH
956#endif
957 char *name, *pt;
958 int len;
959 PyObject *d, *v;
960 char namebuf[MAX_PATH+5];
961 HDIR hdir = 1;
962 ULONG srchcnt = 1;
963 FILEFINDBUF3 ep;
964 APIRET rc;
965
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000966 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000967 return NULL;
968 if (len >= MAX_PATH) {
969 PyErr_SetString(PyExc_ValueError, "path too long");
970 return NULL;
971 }
972 strcpy(namebuf, name);
973 for (pt = namebuf; *pt; pt++)
974 if (*pt == '/')
975 *pt = '\\';
976 if (namebuf[len-1] != '\\')
977 namebuf[len++] = '\\';
978 strcpy(namebuf + len, "*.*");
979
980 if ((d = PyList_New(0)) == NULL)
981 return NULL;
982
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000983 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
984 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000985 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000986 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
987 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
988 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000989
990 if (rc != NO_ERROR) {
991 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000992 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000993 }
994
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000995 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000996 do {
997 if (ep.achName[0] == '.'
998 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000999 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001000
1001 strcpy(namebuf, ep.achName);
1002
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001003 /* Leave Case of Name Alone -- In Native Form */
1004 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001005
1006 v = PyString_FromString(namebuf);
1007 if (v == NULL) {
1008 Py_DECREF(d);
1009 d = NULL;
1010 break;
1011 }
1012 if (PyList_Append(d, v) != 0) {
1013 Py_DECREF(v);
1014 Py_DECREF(d);
1015 d = NULL;
1016 break;
1017 }
1018 Py_DECREF(v);
1019 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1020 }
1021
1022 return d;
1023#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001024
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001025 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001026 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001027 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001028 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001029 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001030 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001031 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001032 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001033 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001034 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001035 closedir(dirp);
1036 return NULL;
1037 }
1038 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001039 if (ep->d_name[0] == '.' &&
1040 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001041 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001042 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001043 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001044 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001045 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001046 d = NULL;
1047 break;
1048 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001049 if (PyList_Append(d, v) != 0) {
1050 Py_DECREF(v);
1051 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001052 d = NULL;
1053 break;
1054 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001055 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001056 }
1057 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001058
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001059 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001060
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001061#endif /* !PYOS_OS2 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001062#endif /* !_MSC_VER */
Guido van Rossum8d665e61996-06-26 18:22:49 +00001063#endif /* !MS_WIN32 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001064}
1065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001066static char posix_mkdir__doc__[] =
1067"mkdir(path [, mode=0777]) -> None\n\
1068Create a directory.";
1069
Barry Warsaw53699e91996-12-10 23:23:01 +00001070static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001071posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001072{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001073 int res;
1074 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001075 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001076 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001077 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001078 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001079#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001080 res = mkdir(path);
1081#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001082 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001083#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001084 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001085 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001086 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001087 Py_INCREF(Py_None);
1088 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001089}
1090
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001091
Guido van Rossumb6775db1994-08-01 11:34:53 +00001092#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001093static char posix_nice__doc__[] =
1094"nice(inc) -> new_priority\n\
1095Decrease the priority of process and return new priority.";
1096
Barry Warsaw53699e91996-12-10 23:23:01 +00001097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001098posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001099{
1100 int increment, value;
1101
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001102 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001103 return NULL;
1104 value = nice(increment);
1105 if (value == -1)
1106 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001107 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001108}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001109#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001111
1112static char posix_rename__doc__[] =
1113"rename(old, new) -> None\n\
1114Rename a file or directory.";
1115
Barry Warsaw53699e91996-12-10 23:23:01 +00001116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001117posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001118{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001119 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001120}
1121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001122
1123static char posix_rmdir__doc__[] =
1124"rmdir(path) -> None\n\
1125Remove a directory.";
1126
Barry Warsaw53699e91996-12-10 23:23:01 +00001127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001128posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001129{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001130 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001131}
1132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001133
1134static char posix_stat__doc__[] =
1135"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1136Perform a stat system call on the given path.";
1137
Barry Warsaw53699e91996-12-10 23:23:01 +00001138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001139posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001140{
Fred Drake699f3522000-06-29 21:12:41 +00001141 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142}
1143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001144
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001145#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001146static char posix_system__doc__[] =
1147"system(command) -> exit_status\n\
1148Execute the command (a string) in a subshell.";
1149
Barry Warsaw53699e91996-12-10 23:23:01 +00001150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001151posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001152{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001153 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001154 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001155 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001156 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001157 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001158 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001159 Py_END_ALLOW_THREADS
1160 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001161}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001162#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001164
1165static char posix_umask__doc__[] =
1166"umask(new_mask) -> old_mask\n\
1167Set the current numeric umask and return the previous umask.";
1168
Barry Warsaw53699e91996-12-10 23:23:01 +00001169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001170posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171{
1172 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001173 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001174 return NULL;
1175 i = umask(i);
1176 if (i < 0)
1177 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001178 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001179}
1180
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001181
1182static char posix_unlink__doc__[] =
1183"unlink(path) -> None\n\
1184Remove a file (same as remove(path)).";
1185
1186static char posix_remove__doc__[] =
1187"remove(path) -> None\n\
1188Remove a file (same as unlink(path)).";
1189
Barry Warsaw53699e91996-12-10 23:23:01 +00001190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001191posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001192{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001193 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001194}
1195
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001196
Guido van Rossumb6775db1994-08-01 11:34:53 +00001197#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001198static char posix_uname__doc__[] =
1199"uname() -> (sysname, nodename, release, version, machine)\n\
1200Return a tuple identifying the current operating system.";
1201
Barry Warsaw53699e91996-12-10 23:23:01 +00001202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001203posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001204{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001205 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001206 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001207 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001208 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001209 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001210 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001211 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001212 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001213 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001214 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001215 u.sysname,
1216 u.nodename,
1217 u.release,
1218 u.version,
1219 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001220}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001221#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001223
1224static char posix_utime__doc__[] =
1225"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001226utime(path, None) -> None\n\
1227Set the access and modified time of the file to the given values. If the\n\
1228second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001229
Barry Warsaw53699e91996-12-10 23:23:01 +00001230static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001231posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001232{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001233 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001234 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001235 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001236 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001237
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001238/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001239#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001240 struct utimbuf buf;
1241#define ATIME buf.actime
1242#define MTIME buf.modtime
1243#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001244#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001245 time_t buf[2];
1246#define ATIME buf[0]
1247#define MTIME buf[1]
1248#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001249#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001250
Barry Warsaw3cef8562000-05-01 16:17:24 +00001251 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001252 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001253 if (arg == Py_None) {
1254 /* optional time values not given */
1255 Py_BEGIN_ALLOW_THREADS
1256 res = utime(path, NULL);
1257 Py_END_ALLOW_THREADS
1258 }
1259 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1260 PyErr_SetString(PyExc_TypeError,
1261 "Second argument must be a 2-tuple of numbers.");
1262 return NULL;
1263 }
1264 else {
1265 ATIME = atime;
1266 MTIME = mtime;
1267 Py_BEGIN_ALLOW_THREADS
1268 res = utime(path, UTIME_ARG);
1269 Py_END_ALLOW_THREADS
1270 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001271 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001272 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001273 Py_INCREF(Py_None);
1274 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001275#undef UTIME_ARG
1276#undef ATIME
1277#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001278}
1279
Guido van Rossum85e3b011991-06-03 12:42:10 +00001280
Guido van Rossum3b066191991-06-04 19:40:25 +00001281/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001283static char posix__exit__doc__[] =
1284"_exit(status)\n\
1285Exit to the system with specified status, without normal exit processing.";
1286
Barry Warsaw53699e91996-12-10 23:23:01 +00001287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001288posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001289{
1290 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001291 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001292 return NULL;
1293 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001294 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001295}
1296
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001297
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001298#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001299static char posix_execv__doc__[] =
1300"execv(path, args)\n\
1301Execute an executable path with arguments, replacing current process.\n\
1302\n\
1303 path: path of executable file\n\
1304 args: tuple or list of strings";
1305
Barry Warsaw53699e91996-12-10 23:23:01 +00001306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001307posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001308{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001309 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001310 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001311 char **argvlist;
1312 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001313 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001314
Guido van Rossum89b33251993-10-22 14:26:06 +00001315 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001316 argv is a list or tuple of strings. */
1317
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001318 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001319 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001320 if (PyList_Check(argv)) {
1321 argc = PyList_Size(argv);
1322 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001323 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001324 else if (PyTuple_Check(argv)) {
1325 argc = PyTuple_Size(argv);
1326 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001327 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001328 else {
Guido van Rossum50422b42000-04-26 20:34:28 +00001329 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1330 return NULL;
1331 }
1332
1333 if (argc == 0) {
1334 PyErr_SetString(PyExc_ValueError, "empty argument list");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001335 return NULL;
1336 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001337
Barry Warsaw53699e91996-12-10 23:23:01 +00001338 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001339 if (argvlist == NULL)
1340 return NULL;
1341 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001342 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1343 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001344 PyErr_SetString(PyExc_TypeError,
1345 "all arguments must be strings");
1346 return NULL;
1347
Guido van Rossum85e3b011991-06-03 12:42:10 +00001348 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001349 }
1350 argvlist[argc] = NULL;
1351
Guido van Rossumb6775db1994-08-01 11:34:53 +00001352#ifdef BAD_EXEC_PROTOTYPES
1353 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001354#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001355 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001356#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001357
Guido van Rossum85e3b011991-06-03 12:42:10 +00001358 /* If we get here it's definitely an error */
1359
Barry Warsaw53699e91996-12-10 23:23:01 +00001360 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001361 return posix_error();
1362}
1363
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001364
1365static char posix_execve__doc__[] =
1366"execve(path, args, env)\n\
1367Execute a path with arguments and environment, replacing current process.\n\
1368\n\
1369 path: path of executable file\n\
1370 args: tuple or list of arguments\n\
1371 env: dictonary of strings mapping to strings";
1372
Barry Warsaw53699e91996-12-10 23:23:01 +00001373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001374posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001375{
1376 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001377 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001378 char **argvlist;
1379 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001380 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001381 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001382 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001383
1384 /* execve has three arguments: (path, argv, env), where
1385 argv is a list or tuple of strings and env is a dictionary
1386 like posix.environ. */
1387
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001388 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001389 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001390 if (PyList_Check(argv)) {
1391 argc = PyList_Size(argv);
1392 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001393 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001394 else if (PyTuple_Check(argv)) {
1395 argc = PyTuple_Size(argv);
1396 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001397 }
1398 else {
Barry Warsaw53699e91996-12-10 23:23:01 +00001399 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001400 return NULL;
1401 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001402 if (!PyMapping_Check(env)) {
1403 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001404 return NULL;
1405 }
1406
Guido van Rossum50422b42000-04-26 20:34:28 +00001407 if (argc == 0) {
1408 PyErr_SetString(PyExc_ValueError,
1409 "empty argument list");
1410 return NULL;
1411 }
1412
Barry Warsaw53699e91996-12-10 23:23:01 +00001413 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001414 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001415 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001416 return NULL;
1417 }
1418 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001419 if (!PyArg_Parse((*getitem)(argv, i),
Barry Warsaw43d68b81996-12-19 22:10:44 +00001420 "s;argv must be list of strings",
1421 &argvlist[i]))
1422 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001423 goto fail_1;
1424 }
1425 }
1426 argvlist[argc] = NULL;
1427
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001428 i = PyMapping_Length(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001429 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001430 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001431 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001432 goto fail_1;
1433 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001434 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001435 keys = PyMapping_Keys(env);
1436 vals = PyMapping_Values(env);
1437 if (!keys || !vals)
1438 goto fail_2;
1439
1440 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001441 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001442
1443 key = PyList_GetItem(keys, pos);
1444 val = PyList_GetItem(vals, pos);
1445 if (!key || !val)
1446 goto fail_2;
1447
Barry Warsaw53699e91996-12-10 23:23:01 +00001448 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
Barry Warsaw43d68b81996-12-19 22:10:44 +00001449 !PyArg_Parse(val, "s;non-string value in env", &v))
1450 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001451 goto fail_2;
1452 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001453
1454#if defined(PYOS_OS2)
1455 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1456 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1457#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001458 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001459 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001460 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001461 goto fail_2;
1462 }
1463 sprintf(p, "%s=%s", k, v);
1464 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001465#if defined(PYOS_OS2)
1466 }
1467#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001468 }
1469 envlist[envc] = 0;
1470
Guido van Rossumb6775db1994-08-01 11:34:53 +00001471
1472#ifdef BAD_EXEC_PROTOTYPES
1473 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001474#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001475 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001476#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001477
1478 /* If we get here it's definitely an error */
1479
1480 (void) posix_error();
1481
1482 fail_2:
1483 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001484 PyMem_DEL(envlist[envc]);
1485 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001486 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001487 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001488 Py_XDECREF(vals);
1489 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001490 return NULL;
1491}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001492#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001493
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001494
Guido van Rossuma1065681999-01-25 23:20:23 +00001495#ifdef HAVE_SPAWNV
1496static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001497"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001498Execute an executable path with arguments, replacing current process.\n\
1499\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001500 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001501 path: path of executable file\n\
1502 args: tuple or list of strings";
1503
1504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001505posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001506{
1507 char *path;
1508 PyObject *argv;
1509 char **argvlist;
1510 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001511 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001512 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001513
1514 /* spawnv has three arguments: (mode, path, argv), where
1515 argv is a list or tuple of strings. */
1516
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001517 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001518 return NULL;
1519 if (PyList_Check(argv)) {
1520 argc = PyList_Size(argv);
1521 getitem = PyList_GetItem;
1522 }
1523 else if (PyTuple_Check(argv)) {
1524 argc = PyTuple_Size(argv);
1525 getitem = PyTuple_GetItem;
1526 }
1527 else {
Fred Drake137507e2000-06-01 02:02:46 +00001528 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001529 return NULL;
1530 }
1531
1532 argvlist = PyMem_NEW(char *, argc+1);
1533 if (argvlist == NULL)
1534 return NULL;
1535 for (i = 0; i < argc; i++) {
1536 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1537 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001538 PyErr_SetString(PyExc_TypeError,
1539 "all arguments must be strings");
1540 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001541 }
1542 }
1543 argvlist[argc] = NULL;
1544
Guido van Rossum246bc171999-02-01 23:54:31 +00001545 if (mode == _OLD_P_OVERLAY)
1546 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001547 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001548
1549 PyMem_DEL(argvlist);
1550
Fred Drake699f3522000-06-29 21:12:41 +00001551 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001552 return posix_error();
1553 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001554#if SIZEOF_LONG == SIZEOF_VOID_P
1555 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001556#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001557 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001558#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001559}
1560
1561
1562static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001563"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001564Execute a path with arguments and environment, replacing current process.\n\
1565\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001566 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001567 path: path of executable file\n\
1568 args: tuple or list of arguments\n\
1569 env: dictonary of strings mapping to strings";
1570
1571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001572posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001573{
1574 char *path;
1575 PyObject *argv, *env;
1576 char **argvlist;
1577 char **envlist;
1578 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1579 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001580 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001581 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001582
1583 /* spawnve has four arguments: (mode, path, argv, env), where
1584 argv is a list or tuple of strings and env is a dictionary
1585 like posix.environ. */
1586
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001587 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001588 return NULL;
1589 if (PyList_Check(argv)) {
1590 argc = PyList_Size(argv);
1591 getitem = PyList_GetItem;
1592 }
1593 else if (PyTuple_Check(argv)) {
1594 argc = PyTuple_Size(argv);
1595 getitem = PyTuple_GetItem;
1596 }
1597 else {
1598 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1599 return NULL;
1600 }
1601 if (!PyMapping_Check(env)) {
1602 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1603 return NULL;
1604 }
1605
1606 argvlist = PyMem_NEW(char *, argc+1);
1607 if (argvlist == NULL) {
1608 PyErr_NoMemory();
1609 return NULL;
1610 }
1611 for (i = 0; i < argc; i++) {
1612 if (!PyArg_Parse((*getitem)(argv, i),
1613 "s;argv must be list of strings",
1614 &argvlist[i]))
1615 {
1616 goto fail_1;
1617 }
1618 }
1619 argvlist[argc] = NULL;
1620
1621 i = PyMapping_Length(env);
1622 envlist = PyMem_NEW(char *, i + 1);
1623 if (envlist == NULL) {
1624 PyErr_NoMemory();
1625 goto fail_1;
1626 }
1627 envc = 0;
1628 keys = PyMapping_Keys(env);
1629 vals = PyMapping_Values(env);
1630 if (!keys || !vals)
1631 goto fail_2;
1632
1633 for (pos = 0; pos < i; pos++) {
1634 char *p, *k, *v;
1635
1636 key = PyList_GetItem(keys, pos);
1637 val = PyList_GetItem(vals, pos);
1638 if (!key || !val)
1639 goto fail_2;
1640
1641 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1642 !PyArg_Parse(val, "s;non-string value in env", &v))
1643 {
1644 goto fail_2;
1645 }
1646 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1647 if (p == NULL) {
1648 PyErr_NoMemory();
1649 goto fail_2;
1650 }
1651 sprintf(p, "%s=%s", k, v);
1652 envlist[envc++] = p;
1653 }
1654 envlist[envc] = 0;
1655
Guido van Rossum246bc171999-02-01 23:54:31 +00001656 if (mode == _OLD_P_OVERLAY)
1657 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001658 spawnval = _spawnve(mode, path, argvlist, envlist);
1659 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001660 (void) posix_error();
1661 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001662#if SIZEOF_LONG == SIZEOF_VOID_P
1663 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001664#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001665 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001666#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001667
1668 fail_2:
1669 while (--envc >= 0)
1670 PyMem_DEL(envlist[envc]);
1671 PyMem_DEL(envlist);
1672 fail_1:
1673 PyMem_DEL(argvlist);
1674 Py_XDECREF(vals);
1675 Py_XDECREF(keys);
1676 return res;
1677}
1678#endif /* HAVE_SPAWNV */
1679
1680
Guido van Rossumad0ee831995-03-01 10:34:45 +00001681#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001682static char posix_fork__doc__[] =
1683"fork() -> pid\n\
1684Fork a child process.\n\
1685\n\
1686Return 0 to child process and PID of child to parent process.";
1687
Barry Warsaw53699e91996-12-10 23:23:01 +00001688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001689posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001690{
1691 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001692 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001693 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001694 pid = fork();
1695 if (pid == -1)
1696 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001697 if (pid == 0)
1698 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001699 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001700}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001701#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001702
Fred Drake8cef4cf2000-06-28 16:40:38 +00001703#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1704#ifdef HAVE_PTY_H
1705#include <pty.h>
1706#else
1707#ifdef HAVE_LIBUTIL_H
1708#include <libutil.h>
1709#else
1710/* BSDI does not supply a prototype for the 'openpty' and 'forkpty'
1711 functions, eventhough they are included in libutil. */
1712#include <termios.h>
1713extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
1714extern int forkpty(int *, char *, struct termios *, struct winsize *);
1715#endif /* HAVE_LIBUTIL_H */
1716#endif /* HAVE_PTY_H */
1717#endif /* defined(HAVE_OPENPTY) or defined(HAVE_FORKPTY) */
1718
1719#ifdef HAVE_OPENPTY
1720static char posix_openpty__doc__[] =
1721"openpty() -> (master_fd, slave_fd)\n\
1722Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1723
1724static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001725posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001726{
1727 int master_fd, slave_fd;
1728 if (!PyArg_ParseTuple(args, ":openpty"))
1729 return NULL;
1730 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1731 return posix_error();
1732 return Py_BuildValue("(ii)", master_fd, slave_fd);
1733}
1734#endif
1735
1736#ifdef HAVE_FORKPTY
1737static char posix_forkpty__doc__[] =
1738"forkpty() -> (pid, master_fd)\n\
1739Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1740Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1741To both, return fd of newly opened pseudo-terminal.\n";
1742
1743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001744posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001745{
1746 int master_fd, pid;
1747
1748 if (!PyArg_ParseTuple(args, ":forkpty"))
1749 return NULL;
1750 pid = forkpty(&master_fd, NULL, NULL, NULL);
1751 if (pid == -1)
1752 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001753 if (pid == 0)
1754 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001755 return Py_BuildValue("(ii)", pid, master_fd);
1756}
1757#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001758
Guido van Rossumad0ee831995-03-01 10:34:45 +00001759#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001760static char posix_getegid__doc__[] =
1761"getegid() -> egid\n\
1762Return the current process's effective group id.";
1763
Barry Warsaw53699e91996-12-10 23:23:01 +00001764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001765posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001766{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001767 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001768 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001769 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001770}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001771#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001772
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001773
Guido van Rossumad0ee831995-03-01 10:34:45 +00001774#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001775static char posix_geteuid__doc__[] =
1776"geteuid() -> euid\n\
1777Return the current process's effective user id.";
1778
Barry Warsaw53699e91996-12-10 23:23:01 +00001779static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001780posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001781{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001782 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001783 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001784 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001785}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001786#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001788
Guido van Rossumad0ee831995-03-01 10:34:45 +00001789#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001790static char posix_getgid__doc__[] =
1791"getgid() -> gid\n\
1792Return the current process's group id.";
1793
Barry Warsaw53699e91996-12-10 23:23:01 +00001794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001795posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001796{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001797 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001798 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001799 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001800}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001801#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001802
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001803
1804static char posix_getpid__doc__[] =
1805"getpid() -> pid\n\
1806Return the current process id";
1807
Barry Warsaw53699e91996-12-10 23:23:01 +00001808static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001809posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001810{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001811 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001812 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001813 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001814}
1815
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001816
Fred Drakec9680921999-12-13 16:37:25 +00001817#ifdef HAVE_GETGROUPS
1818static char posix_getgroups__doc__[] = "\
1819getgroups() -> list of group IDs\n\
1820Return list of supplemental group IDs for the process.";
1821
1822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001823posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001824{
1825 PyObject *result = NULL;
1826
1827 if (PyArg_ParseTuple(args, ":getgroups")) {
1828#ifdef NGROUPS_MAX
1829#define MAX_GROUPS NGROUPS_MAX
1830#else
1831 /* defined to be 16 on Solaris7, so this should be a small number */
1832#define MAX_GROUPS 64
1833#endif
1834 gid_t grouplist[MAX_GROUPS];
1835 int n;
1836
1837 n = getgroups(MAX_GROUPS, grouplist);
1838 if (n < 0)
1839 posix_error();
1840 else {
1841 result = PyList_New(n);
1842 if (result != NULL) {
1843 PyObject *o;
1844 int i;
1845 for (i = 0; i < n; ++i) {
1846 o = PyInt_FromLong((long)grouplist[i]);
1847 if (o == NULL) {
1848 Py_DECREF(result);
1849 result = NULL;
1850 break;
1851 }
1852 PyList_SET_ITEM(result, i, o);
1853 }
1854 }
1855 }
1856 }
1857 return result;
1858}
1859#endif
1860
Guido van Rossumb6775db1994-08-01 11:34:53 +00001861#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001862static char posix_getpgrp__doc__[] =
1863"getpgrp() -> pgrp\n\
1864Return the current process group id.";
1865
Barry Warsaw53699e91996-12-10 23:23:01 +00001866static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001867posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001868{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001869 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001870 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001871#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001872 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001873#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001874 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001875#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001876}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001877#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001878
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001879
Guido van Rossumb6775db1994-08-01 11:34:53 +00001880#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001881static char posix_setpgrp__doc__[] =
1882"setpgrp() -> None\n\
1883Make this process a session leader.";
1884
Barry Warsaw53699e91996-12-10 23:23:01 +00001885static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001886posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001887{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001888 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001889 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001890#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001891 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001892#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001893 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001894#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001895 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001896 Py_INCREF(Py_None);
1897 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001898}
1899
Guido van Rossumb6775db1994-08-01 11:34:53 +00001900#endif /* HAVE_SETPGRP */
1901
Guido van Rossumad0ee831995-03-01 10:34:45 +00001902#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001903static char posix_getppid__doc__[] =
1904"getppid() -> ppid\n\
1905Return the parent's process id.";
1906
Barry Warsaw53699e91996-12-10 23:23:01 +00001907static PyObject *
Guido van Rossum85e3b011991-06-03 12:42:10 +00001908posix_getppid(self, args)
Barry Warsaw53699e91996-12-10 23:23:01 +00001909 PyObject *self;
1910 PyObject *args;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001911{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001912 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001913 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001914 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001915}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001916#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001917
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001918
Fred Drake12c6e2d1999-12-14 21:25:03 +00001919#ifdef HAVE_GETLOGIN
1920static char posix_getlogin__doc__[] = "\
1921getlogin() -> string\n\
1922Return the actual login name.";
1923
1924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001925posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001926{
1927 PyObject *result = NULL;
1928
1929 if (PyArg_ParseTuple(args, ":getlogin")) {
1930 char *name = getlogin();
1931
1932 if (name == NULL)
1933 posix_error();
1934 else
1935 result = PyString_FromString(name);
1936 }
1937 return result;
1938}
1939#endif
1940
Guido van Rossumad0ee831995-03-01 10:34:45 +00001941#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001942static char posix_getuid__doc__[] =
1943"getuid() -> uid\n\
1944Return the current process's user id.";
1945
Barry Warsaw53699e91996-12-10 23:23:01 +00001946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001947posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001948{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001949 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001950 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001951 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001952}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001953#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001954
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001955
Guido van Rossumad0ee831995-03-01 10:34:45 +00001956#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001957static char posix_kill__doc__[] =
1958"kill(pid, sig) -> None\n\
1959Kill a process with a signal.";
1960
Barry Warsaw53699e91996-12-10 23:23:01 +00001961static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001962posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001963{
1964 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001965 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001966 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001967#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001968 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1969 APIRET rc;
1970 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001971 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001972
1973 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1974 APIRET rc;
1975 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001976 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001977
1978 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001979 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001980#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001981 if (kill(pid, sig) == -1)
1982 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001983#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001984 Py_INCREF(Py_None);
1985 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001986}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001987#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001988
Guido van Rossumc0125471996-06-28 18:55:32 +00001989#ifdef HAVE_PLOCK
1990
1991#ifdef HAVE_SYS_LOCK_H
1992#include <sys/lock.h>
1993#endif
1994
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001995static char posix_plock__doc__[] =
1996"plock(op) -> None\n\
1997Lock program segments into memory.";
1998
Barry Warsaw53699e91996-12-10 23:23:01 +00001999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002000posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002001{
2002 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002003 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002004 return NULL;
2005 if (plock(op) == -1)
2006 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002007 Py_INCREF(Py_None);
2008 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002009}
2010#endif
2011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002012
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002013#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014static char posix_popen__doc__[] =
2015"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2016Open a pipe to/from a command returning a file object.";
2017
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002018#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002019static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002020async_system(const char *command)
2021{
2022 char *p, errormsg[256], args[1024];
2023 RESULTCODES rcodes;
2024 APIRET rc;
2025 char *shell = getenv("COMSPEC");
2026 if (!shell)
2027 shell = "cmd";
2028
2029 strcpy(args, shell);
2030 p = &args[ strlen(args)+1 ];
2031 strcpy(p, "/c ");
2032 strcat(p, command);
2033 p += strlen(p) + 1;
2034 *p = '\0';
2035
2036 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002037 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002038 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002039 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002040 &rcodes, shell);
2041 return rc;
2042}
2043
Guido van Rossumd48f2521997-12-05 22:19:34 +00002044static FILE *
2045popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002046{
2047 HFILE rhan, whan;
2048 FILE *retfd = NULL;
2049 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2050
Guido van Rossumd48f2521997-12-05 22:19:34 +00002051 if (rc != NO_ERROR) {
2052 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002053 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002054 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002055
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002056 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2057 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002058
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002059 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2060 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002061
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002062 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2063 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002064
2065 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002066 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002067 }
2068
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002069 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2070 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002071
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002072 close(oldfd); /* And Close Saved STDOUT Handle */
2073 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002075 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2076 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002077
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002078 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2079 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002080
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002081 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2082 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002083
2084 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002085 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002086 }
2087
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002088 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2089 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002090
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002091 close(oldfd); /* And Close Saved STDIN Handle */
2092 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002093
Guido van Rossumd48f2521997-12-05 22:19:34 +00002094 } else {
2095 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002096 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002097 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002098}
2099
2100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002101posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002102{
2103 char *name;
2104 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002105 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002106 FILE *fp;
2107 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002108 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002109 return NULL;
2110 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002111 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002112 Py_END_ALLOW_THREADS
2113 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002114 return os2_error(err);
2115
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002116 f = PyFile_FromFile(fp, name, mode, fclose);
2117 if (f != NULL)
2118 PyFile_SetBufSize(f, bufsize);
2119 return f;
2120}
2121
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002122#elif defined(MS_WIN32)
2123
2124/*
2125 * Portable 'popen' replacement for Win32.
2126 *
2127 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2128 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
2129 */
2130
2131#include <malloc.h>
2132#include <io.h>
2133#include <fcntl.h>
2134
2135/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2136#define POPEN_1 1
2137#define POPEN_2 2
2138#define POPEN_3 3
2139#define POPEN_4 4
2140
2141static PyObject *_PyPopen(char *, int, int);
2142
2143/* popen that works from a GUI.
2144 *
2145 * The result of this function is a pipe (file) connected to the
2146 * processes stdin or stdout, depending on the requested mode.
2147 */
2148
2149static PyObject *
2150posix_popen(PyObject *self, PyObject *args)
2151{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002152 PyObject *f, *s;
2153 int tm = 0;
2154
2155 char *cmdstring;
2156 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002157 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002158 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002159 return NULL;
2160
2161 s = PyTuple_New(0);
2162
2163 if (*mode == 'r')
2164 tm = _O_RDONLY;
2165 else if (*mode != 'w') {
2166 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'");
2167 return NULL;
2168 } else
2169 tm = _O_WRONLY;
2170
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002171 if (bufsize != -1) {
2172 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2173 return NULL;
2174 }
2175
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002176 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002177 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002178 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002179 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002180 else
2181 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2182
2183 return f;
2184}
2185
2186/* Variation on win32pipe.popen
2187 *
2188 * The result of this function is a pipe (file) connected to the
2189 * process's stdin, and a pipe connected to the process's stdout.
2190 */
2191
2192static PyObject *
2193win32_popen2(PyObject *self, PyObject *args)
2194{
2195 PyObject *f;
2196 int tm=0;
2197
2198 char *cmdstring;
2199 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002200 int bufsize = -1;
2201 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002202 return NULL;
2203
2204 if (*mode == 't')
2205 tm = _O_TEXT;
2206 else if (*mode != 'b') {
2207 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2208 return NULL;
2209 } else
2210 tm = _O_BINARY;
2211
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002212 if (bufsize != -1) {
2213 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2214 return NULL;
2215 }
2216
2217 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002218
2219 return f;
2220}
2221
2222/*
2223 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002224 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002225 * The result of this function is 3 pipes - the process's stdin,
2226 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002227 */
2228
2229static PyObject *
2230win32_popen3(PyObject *self, PyObject *args)
2231{
2232 PyObject *f;
2233 int tm = 0;
2234
2235 char *cmdstring;
2236 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002237 int bufsize = -1;
2238 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002239 return NULL;
2240
2241 if (*mode == 't')
2242 tm = _O_TEXT;
2243 else if (*mode != 'b') {
2244 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2245 return NULL;
2246 } else
2247 tm = _O_BINARY;
2248
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002249 if (bufsize != -1) {
2250 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2251 return NULL;
2252 }
2253
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002254 f = _PyPopen(cmdstring, tm, POPEN_3);
2255
2256 return f;
2257}
2258
2259/*
2260 * Variation on win32pipe.popen
2261 *
2262 * The result of this function is 2 pipes - the processes stdin,
2263 * and stdout+stderr combined as a single pipe.
2264 */
2265
2266static PyObject *
2267win32_popen4(PyObject *self, PyObject *args)
2268{
2269 PyObject *f;
2270 int tm = 0;
2271
2272 char *cmdstring;
2273 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002274 int bufsize = -1;
2275 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002276 return NULL;
2277
2278 if (*mode == 't')
2279 tm = _O_TEXT;
2280 else if (*mode != 'b') {
2281 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2282 return NULL;
2283 } else
2284 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002285
2286 if (bufsize != -1) {
2287 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2288 return NULL;
2289 }
2290
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002291 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002292
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002293 return f;
2294}
2295
2296static int
2297_PyPopenCreateProcess(char *cmdstring,
2298 HANDLE hStdin,
2299 HANDLE hStdout,
2300 HANDLE hStderr)
2301{
2302 PROCESS_INFORMATION piProcInfo;
2303 STARTUPINFO siStartInfo;
2304 char *s1,*s2, *s3 = " /c ";
2305 const char *szConsoleSpawn = "w9xpopen.exe \"";
2306 int i;
2307 int x;
2308
2309 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2310 s1 = (char *)_alloca(i);
2311 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2312 return x;
2313 if (GetVersion() < 0x80000000) {
2314 /*
2315 * NT/2000
2316 */
2317 x = i + strlen(s3) + strlen(cmdstring) + 1;
2318 s2 = (char *)_alloca(x);
2319 ZeroMemory(s2, x);
2320 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2321 }
2322 else {
2323 /*
2324 * Oh gag, we're on Win9x. Use the workaround listed in
2325 * KB: Q150956
2326 */
2327 char modulepath[256];
2328 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2329 for (i = x = 0; modulepath[i]; i++)
2330 if (modulepath[i] == '\\')
2331 x = i+1;
2332 modulepath[x] = '\0';
2333 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2334 strlen(modulepath) +
2335 strlen(szConsoleSpawn) + 1;
2336 s2 = (char *)_alloca(x);
2337 ZeroMemory(s2, x);
2338 sprintf(
2339 s2,
2340 "%s%s%s%s%s\"",
2341 modulepath,
2342 szConsoleSpawn,
2343 s1,
2344 s3,
2345 cmdstring);
2346 }
2347 }
2348
2349 /* Could be an else here to try cmd.exe / command.com in the path
2350 Now we'll just error out.. */
2351 else
2352 return -1;
2353
2354 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2355 siStartInfo.cb = sizeof(STARTUPINFO);
2356 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2357 siStartInfo.hStdInput = hStdin;
2358 siStartInfo.hStdOutput = hStdout;
2359 siStartInfo.hStdError = hStderr;
2360 siStartInfo.wShowWindow = SW_HIDE;
2361
2362 if (CreateProcess(NULL,
2363 s2,
2364 NULL,
2365 NULL,
2366 TRUE,
2367 CREATE_NEW_CONSOLE,
2368 NULL,
2369 NULL,
2370 &siStartInfo,
2371 &piProcInfo) ) {
2372 /* Close the handles now so anyone waiting is woken. */
2373 CloseHandle(piProcInfo.hProcess);
2374 CloseHandle(piProcInfo.hThread);
2375 return TRUE;
2376 }
2377 return FALSE;
2378}
2379
2380/* The following code is based off of KB: Q190351 */
2381
2382static PyObject *
2383_PyPopen(char *cmdstring, int mode, int n)
2384{
2385 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2386 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
2387 hChildStderrRdDup; /* hChildStdoutWrDup; */
2388
2389 SECURITY_ATTRIBUTES saAttr;
2390 BOOL fSuccess;
2391 int fd1, fd2, fd3;
2392 FILE *f1, *f2, *f3;
2393 PyObject *f;
2394
2395 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2396 saAttr.bInheritHandle = TRUE;
2397 saAttr.lpSecurityDescriptor = NULL;
2398
2399 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2400 return win32_error("CreatePipe", NULL);
2401
2402 /* Create new output read handle and the input write handle. Set
2403 * the inheritance properties to FALSE. Otherwise, the child inherits
2404 * the these handles; resulting in non-closeable handles to the pipes
2405 * being created. */
2406 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
2407 GetCurrentProcess(), &hChildStdinWrDup, 0,
2408 FALSE,
2409 DUPLICATE_SAME_ACCESS);
2410 if (!fSuccess)
2411 return win32_error("DuplicateHandle", NULL);
2412
2413 /* Close the inheritable version of ChildStdin
2414 that we're using. */
2415 CloseHandle(hChildStdinWr);
2416
2417 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2418 return win32_error("CreatePipe", NULL);
2419
2420 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
2421 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2422 FALSE,
2423 DUPLICATE_SAME_ACCESS);
2424 if (!fSuccess)
2425 return win32_error("DuplicateHandle", NULL);
2426
2427 /* Close the inheritable version of ChildStdout
2428 that we're using. */
2429 CloseHandle(hChildStdoutRd);
2430
2431 if (n != POPEN_4) {
2432 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2433 return win32_error("CreatePipe", NULL);
2434 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStderrRd,
2435 GetCurrentProcess(), &hChildStderrRdDup, 0,
2436 FALSE,
2437 DUPLICATE_SAME_ACCESS);
2438 if (!fSuccess)
2439 return win32_error("DuplicateHandle", NULL);
2440 /* Close the inheritable version of ChildStdErr that we're using. */
2441 CloseHandle(hChildStderrRd);
2442 }
2443
2444 switch (n) {
2445 case POPEN_1:
2446 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2447 case _O_WRONLY | _O_TEXT:
2448 /* Case for writing to child Stdin in text mode. */
2449 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2450 f1 = _fdopen(fd1, "w");
2451 f = PyFile_FromFile(f1, cmdstring, "w", fclose);
2452 PyFile_SetBufSize(f, 0);
2453 /* We don't care about these pipes anymore, so close them. */
2454 CloseHandle(hChildStdoutRdDup);
2455 CloseHandle(hChildStderrRdDup);
2456 break;
2457
2458 case _O_RDONLY | _O_TEXT:
2459 /* Case for reading from child Stdout in text mode. */
2460 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2461 f1 = _fdopen(fd1, "r");
2462 f = PyFile_FromFile(f1, cmdstring, "r", fclose);
2463 PyFile_SetBufSize(f, 0);
2464 /* We don't care about these pipes anymore, so close them. */
2465 CloseHandle(hChildStdinWrDup);
2466 CloseHandle(hChildStderrRdDup);
2467 break;
2468
2469 case _O_RDONLY | _O_BINARY:
2470 /* Case for readinig from child Stdout in binary mode. */
2471 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2472 f1 = _fdopen(fd1, "rb");
2473 f = PyFile_FromFile(f1, cmdstring, "rb", fclose);
2474 PyFile_SetBufSize(f, 0);
2475 /* We don't care about these pipes anymore, so close them. */
2476 CloseHandle(hChildStdinWrDup);
2477 CloseHandle(hChildStderrRdDup);
2478 break;
2479
2480 case _O_WRONLY | _O_BINARY:
2481 /* Case for writing to child Stdin in binary mode. */
2482 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2483 f1 = _fdopen(fd1, "wb");
2484 f = PyFile_FromFile(f1, cmdstring, "wb", fclose);
2485 PyFile_SetBufSize(f, 0);
2486 /* We don't care about these pipes anymore, so close them. */
2487 CloseHandle(hChildStdoutRdDup);
2488 CloseHandle(hChildStderrRdDup);
2489 break;
2490 }
2491 break;
2492
2493 case POPEN_2:
2494 case POPEN_4:
2495 {
2496 char *m1, *m2;
2497 PyObject *p1, *p2;
2498
2499 if (mode && _O_TEXT) {
2500 m1 = "r";
2501 m2 = "w";
2502 } else {
2503 m1 = "rb";
2504 m2 = "wb";
2505 }
2506
2507 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2508 f1 = _fdopen(fd1, m2);
2509 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2510 f2 = _fdopen(fd2, m1);
2511 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose);
2512 PyFile_SetBufSize(p1, 0);
2513 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2514 PyFile_SetBufSize(p2, 0);
2515
2516 if (n != 4)
2517 CloseHandle(hChildStderrRdDup);
2518
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002519 f = Py_BuildValue("OO",p2,p1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002520 break;
2521 }
2522
2523 case POPEN_3:
2524 {
2525 char *m1, *m2;
2526 PyObject *p1, *p2, *p3;
2527
2528 if (mode && _O_TEXT) {
2529 m1 = "r";
2530 m2 = "w";
2531 } else {
2532 m1 = "rb";
2533 m2 = "wb";
2534 }
2535
2536 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2537 f1 = _fdopen(fd1, m2);
2538 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2539 f2 = _fdopen(fd2, m1);
2540 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2541 f3 = _fdopen(fd3, m1);
2542 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose);
2543 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2544 p3 = PyFile_FromFile(f3, cmdstring, m1, fclose);
2545 PyFile_SetBufSize(p1, 0);
2546 PyFile_SetBufSize(p2, 0);
2547 PyFile_SetBufSize(p3, 0);
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002548 f = Py_BuildValue("OOO",p2,p1,p3);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002549 break;
2550 }
2551 }
2552
2553 if (n == POPEN_4) {
2554 if (!_PyPopenCreateProcess(cmdstring,
2555 hChildStdinRd,
2556 hChildStdoutWr,
2557 hChildStdoutWr))
2558 return win32_error("CreateProcess", NULL);
2559 }
2560 else {
2561 if (!_PyPopenCreateProcess(cmdstring,
2562 hChildStdinRd,
2563 hChildStdoutWr,
2564 hChildStderrWr))
2565 return win32_error("CreateProcess", NULL);
2566 }
2567
2568 /* Child is launched. Close the parents copy of those pipe
2569 * handles that only the child should have open. You need to
2570 * make sure that no handles to the write end of the output pipe
2571 * are maintained in this process or else the pipe will not close
2572 * when the child process exits and the ReadFile will hang. */
2573
2574 if (!CloseHandle(hChildStdinRd))
2575 return win32_error("CloseHandle", NULL);
2576
2577 if (!CloseHandle(hChildStdoutWr))
2578 return win32_error("CloseHandle", NULL);
2579
2580 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2581 return win32_error("CloseHandle", NULL);
2582
2583 return f;
2584}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002585#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002586static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002587posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002588{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002589 char *name;
2590 char *mode = "r";
2591 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002592 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002593 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002594 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002595 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002596 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002597 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002598 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002599 if (fp == NULL)
2600 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002601 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002602 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002603 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002604 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002605}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002606#endif
2607
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002608#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002610
Guido van Rossumb6775db1994-08-01 11:34:53 +00002611#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002612static char posix_setuid__doc__[] =
2613"setuid(uid) -> None\n\
2614Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002616posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002617{
2618 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002619 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002620 return NULL;
2621 if (setuid(uid) < 0)
2622 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002623 Py_INCREF(Py_None);
2624 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002625}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002626#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002627
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002628
Guido van Rossumb6775db1994-08-01 11:34:53 +00002629#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002630static char posix_setgid__doc__[] =
2631"setgid(gid) -> None\n\
2632Set the current process's group id.";
2633
Barry Warsaw53699e91996-12-10 23:23:01 +00002634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002635posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002636{
2637 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002638 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002639 return NULL;
2640 if (setgid(gid) < 0)
2641 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002642 Py_INCREF(Py_None);
2643 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002644}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002645#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002646
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002647
Guido van Rossumb6775db1994-08-01 11:34:53 +00002648#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002649static char posix_waitpid__doc__[] =
2650"waitpid(pid, options) -> (pid, status)\n\
2651Wait for completion of a give child process.";
2652
Barry Warsaw53699e91996-12-10 23:23:01 +00002653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002654posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002655{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002656 int pid, options;
2657#ifdef UNION_WAIT
2658 union wait status;
2659#define status_i (status.w_status)
2660#else
2661 int status;
2662#define status_i status
2663#endif
2664 status_i = 0;
2665
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002666 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00002667 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002668 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002669#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002670 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002671#else
2672 pid = waitpid(pid, &status, options);
2673#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002674 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00002675 if (pid == -1)
2676 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00002677 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002678 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00002679}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002680#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00002681
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002682
Guido van Rossumad0ee831995-03-01 10:34:45 +00002683#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002684static char posix_wait__doc__[] =
2685"wait() -> (pid, status)\n\
2686Wait for completion of a child process.";
2687
Barry Warsaw53699e91996-12-10 23:23:01 +00002688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002689posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00002690{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002691 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002692#ifdef UNION_WAIT
2693 union wait status;
2694#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002695#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002696 int status;
2697#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002698#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002699 if (!PyArg_ParseTuple(args, ":wait"))
2700 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002701 status_i = 0;
2702 Py_BEGIN_ALLOW_THREADS
2703 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00002704 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00002705 if (pid == -1)
2706 return posix_error();
2707 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002708 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002709#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00002710}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002711#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002712
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002713
2714static char posix_lstat__doc__[] =
2715"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
2716Like stat(path), but do not follow symbolic links.";
2717
Barry Warsaw53699e91996-12-10 23:23:01 +00002718static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002719posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002720{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002721#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002722 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002723#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00002724 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002725#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002726}
2727
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002728
Guido van Rossumb6775db1994-08-01 11:34:53 +00002729#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002730static char posix_readlink__doc__[] =
2731"readlink(path) -> path\n\
2732Return a string representing the path to which the symbolic link points.";
2733
Barry Warsaw53699e91996-12-10 23:23:01 +00002734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002735posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002736{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002737 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002738 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002739 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002740 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002741 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002742 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002743 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00002744 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002745 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002746 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002747 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002748}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002749#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002750
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002751
Guido van Rossumb6775db1994-08-01 11:34:53 +00002752#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002753static char posix_symlink__doc__[] =
2754"symlink(src, dst) -> None\n\
2755Create a symbolic link.";
2756
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002758posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002759{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002760 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002761}
2762#endif /* HAVE_SYMLINK */
2763
2764
2765#ifdef HAVE_TIMES
2766#ifndef HZ
2767#define HZ 60 /* Universal constant :-) */
2768#endif /* HZ */
2769
Guido van Rossumd48f2521997-12-05 22:19:34 +00002770#if defined(PYCC_VACPP) && defined(PYOS_OS2)
2771static long
2772system_uptime()
2773{
2774 ULONG value = 0;
2775
2776 Py_BEGIN_ALLOW_THREADS
2777 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
2778 Py_END_ALLOW_THREADS
2779
2780 return value;
2781}
2782
2783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002784posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002785{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002786 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00002787 return NULL;
2788
2789 /* Currently Only Uptime is Provided -- Others Later */
2790 return Py_BuildValue("ddddd",
2791 (double)0 /* t.tms_utime / HZ */,
2792 (double)0 /* t.tms_stime / HZ */,
2793 (double)0 /* t.tms_cutime / HZ */,
2794 (double)0 /* t.tms_cstime / HZ */,
2795 (double)system_uptime() / 1000);
2796}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002797#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002798static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002799posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00002800{
2801 struct tms t;
2802 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002803 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00002804 return NULL;
2805 errno = 0;
2806 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00002807 if (c == (clock_t) -1)
2808 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002809 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002810 (double)t.tms_utime / HZ,
2811 (double)t.tms_stime / HZ,
2812 (double)t.tms_cutime / HZ,
2813 (double)t.tms_cstime / HZ,
2814 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00002815}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002816#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002817#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002818
2819
Guido van Rossum87755a21996-09-07 00:59:43 +00002820#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002821#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00002822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002823posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002824{
2825 FILETIME create, exit, kernel, user;
2826 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002827 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002828 return NULL;
2829 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002830 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
2831 /* The fields of a FILETIME structure are the hi and lo part
2832 of a 64-bit value expressed in 100 nanosecond units.
2833 1e7 is one second in such units; 1e-7 the inverse.
2834 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
2835 */
Barry Warsaw53699e91996-12-10 23:23:01 +00002836 return Py_BuildValue(
2837 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00002838 (double)(kernel.dwHighDateTime*429.4967296 +
2839 kernel.dwLowDateTime*1e-7),
2840 (double)(user.dwHighDateTime*429.4967296 +
2841 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00002842 (double)0,
2843 (double)0,
2844 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002845}
Guido van Rossum8d665e61996-06-26 18:22:49 +00002846#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002847
2848#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00002849static char posix_times__doc__[] =
2850"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
2851Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00002852#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00002853
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002854
Guido van Rossumb6775db1994-08-01 11:34:53 +00002855#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002856static char posix_setsid__doc__[] =
2857"setsid() -> None\n\
2858Call the system call setsid().";
2859
Barry Warsaw53699e91996-12-10 23:23:01 +00002860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002861posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002862{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002863 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002864 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002865 if (setsid() < 0)
2866 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002867 Py_INCREF(Py_None);
2868 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002869}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002870#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00002871
Guido van Rossumb6775db1994-08-01 11:34:53 +00002872#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002873static char posix_setpgid__doc__[] =
2874"setpgid(pid, pgrp) -> None\n\
2875Call the system call setpgid().";
2876
Barry Warsaw53699e91996-12-10 23:23:01 +00002877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002878posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002879{
2880 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002881 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002882 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002883 if (setpgid(pid, pgrp) < 0)
2884 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002885 Py_INCREF(Py_None);
2886 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002887}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002888#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00002889
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002890
Guido van Rossumb6775db1994-08-01 11:34:53 +00002891#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002892static char posix_tcgetpgrp__doc__[] =
2893"tcgetpgrp(fd) -> pgid\n\
2894Return the process group associated with the terminal given by a fd.";
2895
Barry Warsaw53699e91996-12-10 23:23:01 +00002896static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002897posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00002898{
2899 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002900 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00002901 return NULL;
2902 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00002903 if (pgid < 0)
2904 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002905 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00002906}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002907#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00002908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002909
Guido van Rossumb6775db1994-08-01 11:34:53 +00002910#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002911static char posix_tcsetpgrp__doc__[] =
2912"tcsetpgrp(fd, pgid) -> None\n\
2913Set the process group associated with the terminal given by a fd.";
2914
Barry Warsaw53699e91996-12-10 23:23:01 +00002915static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002916posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00002917{
2918 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002919 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00002920 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00002921 if (tcsetpgrp(fd, pgid) < 0)
2922 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00002923 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00002924 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00002925}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002926#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00002927
Guido van Rossum687dd131993-05-17 08:34:16 +00002928/* Functions acting on file descriptors */
2929
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002930static char posix_open__doc__[] =
2931"open(filename, flag [, mode=0777]) -> fd\n\
2932Open a file (for low level IO).";
2933
Barry Warsaw53699e91996-12-10 23:23:01 +00002934static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002935posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002936{
2937 char *file;
2938 int flag;
2939 int mode = 0777;
2940 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00002941 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
2942 return NULL;
2943
Barry Warsaw53699e91996-12-10 23:23:01 +00002944 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002945 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002946 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002947 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002948 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00002949 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00002950}
2951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002952
2953static char posix_close__doc__[] =
2954"close(fd) -> None\n\
2955Close a file descriptor (for low level IO).";
2956
Barry Warsaw53699e91996-12-10 23:23:01 +00002957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002958posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002959{
2960 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002961 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00002962 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002963 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002964 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00002965 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002966 if (res < 0)
2967 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002968 Py_INCREF(Py_None);
2969 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00002970}
2971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002972
2973static char posix_dup__doc__[] =
2974"dup(fd) -> fd2\n\
2975Return a duplicate of a file descriptor.";
2976
Barry Warsaw53699e91996-12-10 23:23:01 +00002977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002978posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002979{
2980 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002981 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00002982 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002983 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002984 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00002985 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00002986 if (fd < 0)
2987 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002988 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00002989}
2990
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002991
2992static char posix_dup2__doc__[] =
2993"dup2(fd, fd2) -> None\n\
2994Duplicate file descriptor.";
2995
Barry Warsaw53699e91996-12-10 23:23:01 +00002996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002997posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00002998{
2999 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003000 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003001 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003002 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003003 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003004 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003005 if (res < 0)
3006 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003007 Py_INCREF(Py_None);
3008 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003009}
3010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003011
3012static char posix_lseek__doc__[] =
3013"lseek(fd, pos, how) -> newpos\n\
3014Set the current position of a file descriptor.";
3015
Barry Warsaw53699e91996-12-10 23:23:01 +00003016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003017posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003018{
3019 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003020#ifdef MS_WIN64
3021 LONG_LONG pos, res;
3022#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003023 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003024#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003025 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003026 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003027 return NULL;
3028#ifdef SEEK_SET
3029 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3030 switch (how) {
3031 case 0: how = SEEK_SET; break;
3032 case 1: how = SEEK_CUR; break;
3033 case 2: how = SEEK_END; break;
3034 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003035#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003036
3037#if !defined(HAVE_LARGEFILE_SUPPORT)
3038 pos = PyInt_AsLong(posobj);
3039#else
3040 pos = PyLong_Check(posobj) ?
3041 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3042#endif
3043 if (PyErr_Occurred())
3044 return NULL;
3045
Barry Warsaw53699e91996-12-10 23:23:01 +00003046 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003047#ifdef MS_WIN64
3048 res = _lseeki64(fd, pos, how);
3049#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003050 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003051#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003052 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003053 if (res < 0)
3054 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003055
3056#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003057 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003058#else
3059 return PyLong_FromLongLong(res);
3060#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003061}
3062
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003063
3064static char posix_read__doc__[] =
3065"read(fd, buffersize) -> string\n\
3066Read a file descriptor.";
3067
Barry Warsaw53699e91996-12-10 23:23:01 +00003068static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003069posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003070{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003071 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003072 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003073 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003074 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003075 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003076 if (buffer == NULL)
3077 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003078 Py_BEGIN_ALLOW_THREADS
3079 n = read(fd, PyString_AsString(buffer), size);
3080 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003081 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003082 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003083 return posix_error();
3084 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003085 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003086 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003087 return buffer;
3088}
3089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003090
3091static char posix_write__doc__[] =
3092"write(fd, string) -> byteswritten\n\
3093Write a string to a file descriptor.";
3094
Barry Warsaw53699e91996-12-10 23:23:01 +00003095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003096posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003097{
3098 int fd, size;
3099 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003100 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003101 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003102 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003103 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003104 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003105 if (size < 0)
3106 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003107 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003108}
3109
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003110
3111static char posix_fstat__doc__[]=
3112"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3113Like stat(), but for an open file descriptor.";
3114
Barry Warsaw53699e91996-12-10 23:23:01 +00003115static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003116posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003117{
3118 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003119 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003120 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003121 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003122 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003123 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003124 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003125 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003126 if (res != 0)
3127 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003128
3129 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003130}
3131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003132
3133static char posix_fdopen__doc__[] =
3134"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3135Return an open file object connected to a file descriptor.";
3136
Barry Warsaw53699e91996-12-10 23:23:01 +00003137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003138posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003139{
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003140 extern int fclose(FILE *);
Guido van Rossum687dd131993-05-17 08:34:16 +00003141 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003142 char *mode = "r";
3143 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003144 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003145 PyObject *f;
3146 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003147 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003148
Barry Warsaw53699e91996-12-10 23:23:01 +00003149 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003150 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003151 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003152 if (fp == NULL)
3153 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003154 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003155 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003156 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003157 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003158}
3159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003160
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003161#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003162static char posix_pipe__doc__[] =
3163"pipe() -> (read_end, write_end)\n\
3164Create a pipe.";
3165
Barry Warsaw53699e91996-12-10 23:23:01 +00003166static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003167posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003168{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003169#if defined(PYOS_OS2)
3170 HFILE read, write;
3171 APIRET rc;
3172
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003173 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003174 return NULL;
3175
3176 Py_BEGIN_ALLOW_THREADS
3177 rc = DosCreatePipe( &read, &write, 4096);
3178 Py_END_ALLOW_THREADS
3179 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003180 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003181
3182 return Py_BuildValue("(ii)", read, write);
3183#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003184#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003185 int fds[2];
3186 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003187 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003188 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003189 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003190 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003191 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003192 if (res != 0)
3193 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003194 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003195#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003196 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003197 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003198 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003199 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003200 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003201 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003202 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003203 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003204 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003205 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003206 read_fd = _open_osfhandle((intptr_t)read, 0);
3207 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003208 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003209#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003210#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003211}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003212#endif /* HAVE_PIPE */
3213
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003214
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003215#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003216static char posix_mkfifo__doc__[] =
3217"mkfifo(file, [, mode=0666]) -> None\n\
3218Create a FIFO (a POSIX named pipe).";
3219
Barry Warsaw53699e91996-12-10 23:23:01 +00003220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003221posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003222{
3223 char *file;
3224 int mode = 0666;
3225 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003226 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003227 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003228 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003229 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003230 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003231 if (res < 0)
3232 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003233 Py_INCREF(Py_None);
3234 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003235}
3236#endif
3237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003238
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003239#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003240static char posix_ftruncate__doc__[] =
3241"ftruncate(fd, length) -> None\n\
3242Truncate a file to a specified length.";
3243
Barry Warsaw53699e91996-12-10 23:23:01 +00003244static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003245posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003246{
3247 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003248 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003249 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003250 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003251
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003252 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003253 return NULL;
3254
3255#if !defined(HAVE_LARGEFILE_SUPPORT)
3256 length = PyInt_AsLong(lenobj);
3257#else
3258 length = PyLong_Check(lenobj) ?
3259 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3260#endif
3261 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003262 return NULL;
3263
Barry Warsaw53699e91996-12-10 23:23:01 +00003264 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003265 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003266 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003267 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003268 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003269 return NULL;
3270 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003271 Py_INCREF(Py_None);
3272 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003273}
3274#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003275
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003276#ifdef NeXT
3277#define HAVE_PUTENV
3278/* Steve Spicklemire got this putenv from NeXTAnswers */
3279static int
3280putenv(char *newval)
3281{
3282 extern char **environ;
3283
3284 static int firstTime = 1;
3285 char **ep;
3286 char *cp;
3287 int esiz;
3288 char *np;
3289
3290 if (!(np = strchr(newval, '=')))
3291 return 1;
3292 *np = '\0';
3293
3294 /* look it up */
3295 for (ep=environ ; *ep ; ep++)
3296 {
3297 /* this should always be true... */
3298 if (cp = strchr(*ep, '='))
3299 {
3300 *cp = '\0';
3301 if (!strcmp(*ep, newval))
3302 {
3303 /* got it! */
3304 *cp = '=';
3305 break;
3306 }
3307 *cp = '=';
3308 }
3309 else
3310 {
3311 *np = '=';
3312 return 1;
3313 }
3314 }
3315
3316 *np = '=';
3317 if (*ep)
3318 {
3319 /* the string was already there:
3320 just replace it with the new one */
3321 *ep = newval;
3322 return 0;
3323 }
3324
3325 /* expand environ by one */
3326 for (esiz=2, ep=environ ; *ep ; ep++)
3327 esiz++;
3328 if (firstTime)
3329 {
3330 char **epp;
3331 char **newenv;
3332 if (!(newenv = malloc(esiz * sizeof(char *))))
3333 return 1;
3334
3335 for (ep=environ, epp=newenv ; *ep ;)
3336 *epp++ = *ep++;
3337 *epp++ = newval;
3338 *epp = (char *) 0;
3339 environ = newenv;
3340 }
3341 else
3342 {
3343 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3344 return 1;
3345 environ[esiz - 2] = newval;
3346 environ[esiz - 1] = (char *) 0;
3347 firstTime = 0;
3348 }
3349
3350 return 0;
3351}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003352#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003353
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003354
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003355#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003356static char posix_putenv__doc__[] =
3357"putenv(key, value) -> None\n\
3358Change or add an environment variable.";
3359
Guido van Rossumbcc20741998-08-04 22:53:56 +00003360#ifdef __BEOS__
3361/* We have putenv(), but not in the headers (as of PR2). - [cjh] */
3362int putenv( const char *str );
3363#endif
3364
Fred Drake762e2061999-08-26 17:23:54 +00003365/* Save putenv() parameters as values here, so we can collect them when they
3366 * get re-set with another call for the same key. */
3367static PyObject *posix_putenv_garbage;
3368
Barry Warsaw53699e91996-12-10 23:23:01 +00003369static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003370posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003371{
3372 char *s1, *s2;
3373 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003374 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003375
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003376 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003377 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003378
3379#if defined(PYOS_OS2)
3380 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3381 APIRET rc;
3382
3383 if (strlen(s2) == 0) /* If New Value is an Empty String */
3384 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3385
3386 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3387 if (rc != NO_ERROR)
3388 return os2_error(rc);
3389
3390 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3391 APIRET rc;
3392
3393 if (strlen(s2) == 0) /* If New Value is an Empty String */
3394 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3395
3396 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3397 if (rc != NO_ERROR)
3398 return os2_error(rc);
3399 } else {
3400#endif
3401
Fred Drake762e2061999-08-26 17:23:54 +00003402 /* XXX This can leak memory -- not easy to fix :-( */
3403 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3404 if (newstr == NULL)
3405 return PyErr_NoMemory();
3406 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003407 (void) sprintf(new, "%s=%s", s1, s2);
3408 if (putenv(new)) {
3409 posix_error();
3410 return NULL;
3411 }
Fred Drake762e2061999-08-26 17:23:54 +00003412 /* Install the first arg and newstr in posix_putenv_garbage;
3413 * this will cause previous value to be collected. This has to
3414 * happen after the real putenv() call because the old value
3415 * was still accessible until then. */
3416 if (PyDict_SetItem(posix_putenv_garbage,
3417 PyTuple_GET_ITEM(args, 0), newstr)) {
3418 /* really not much we can do; just leak */
3419 PyErr_Clear();
3420 }
3421 else {
3422 Py_DECREF(newstr);
3423 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003424
3425#if defined(PYOS_OS2)
3426 }
3427#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003428 Py_INCREF(Py_None);
3429 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003430}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003431#endif /* putenv */
3432
3433#ifdef HAVE_STRERROR
3434static char posix_strerror__doc__[] =
3435"strerror(code) -> string\n\
3436Translate an error code to a message string.";
3437
3438PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003439posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003440{
3441 int code;
3442 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003443 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003444 return NULL;
3445 message = strerror(code);
3446 if (message == NULL) {
3447 PyErr_SetString(PyExc_ValueError,
3448 "strerror code out of range");
3449 return NULL;
3450 }
3451 return PyString_FromString(message);
3452}
3453#endif /* strerror */
3454
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003455
Guido van Rossumc9641791998-08-04 15:26:23 +00003456#ifdef HAVE_SYS_WAIT_H
3457
3458#ifdef WIFSTOPPED
3459static char posix_WIFSTOPPED__doc__[] =
3460"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003461Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003462
3463static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003464posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003465{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003466#ifdef UNION_WAIT
3467 union wait status;
3468#define status_i (status.w_status)
3469#else
3470 int status;
3471#define status_i status
3472#endif
3473 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003474
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003475 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003476 {
3477 return NULL;
3478 }
3479
3480 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003481#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003482}
3483#endif /* WIFSTOPPED */
3484
3485#ifdef WIFSIGNALED
3486static char posix_WIFSIGNALED__doc__[] =
3487"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003488Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003489
3490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003491posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003492{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003493#ifdef UNION_WAIT
3494 union wait status;
3495#define status_i (status.w_status)
3496#else
3497 int status;
3498#define status_i status
3499#endif
3500 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003501
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003502 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003503 {
3504 return NULL;
3505 }
3506
3507 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003508#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003509}
3510#endif /* WIFSIGNALED */
3511
3512#ifdef WIFEXITED
3513static char posix_WIFEXITED__doc__[] =
3514"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003515Return true if the process returning 'status' exited using the exit()\n\
3516system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003517
3518static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003519posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003520{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003521#ifdef UNION_WAIT
3522 union wait status;
3523#define status_i (status.w_status)
3524#else
3525 int status;
3526#define status_i status
3527#endif
3528 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003529
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003530 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003531 {
3532 return NULL;
3533 }
3534
3535 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003536#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003537}
3538#endif /* WIFEXITED */
3539
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003540#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003541static char posix_WEXITSTATUS__doc__[] =
3542"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003543Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003544
3545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003546posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003547{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003548#ifdef UNION_WAIT
3549 union wait status;
3550#define status_i (status.w_status)
3551#else
3552 int status;
3553#define status_i status
3554#endif
3555 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003556
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003557 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003558 {
3559 return NULL;
3560 }
3561
3562 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003563#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003564}
3565#endif /* WEXITSTATUS */
3566
3567#ifdef WTERMSIG
3568static char posix_WTERMSIG__doc__[] =
3569"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003570Return the signal that terminated the process that provided the 'status'\n\
3571value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003572
3573static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003574posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003575{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003576#ifdef UNION_WAIT
3577 union wait status;
3578#define status_i (status.w_status)
3579#else
3580 int status;
3581#define status_i status
3582#endif
3583 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003584
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003585 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003586 {
3587 return NULL;
3588 }
3589
3590 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003591#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003592}
3593#endif /* WTERMSIG */
3594
3595#ifdef WSTOPSIG
3596static char posix_WSTOPSIG__doc__[] =
3597"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003598Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003599
3600static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003601posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003602{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003603#ifdef UNION_WAIT
3604 union wait status;
3605#define status_i (status.w_status)
3606#else
3607 int status;
3608#define status_i status
3609#endif
3610 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003611
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003612 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003613 {
3614 return NULL;
3615 }
3616
3617 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003618#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003619}
3620#endif /* WSTOPSIG */
3621
3622#endif /* HAVE_SYS_WAIT_H */
3623
3624
Guido van Rossum94f6f721999-01-06 18:42:14 +00003625#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003626#ifdef _SCO_DS
3627/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3628 needed definitions in sys/statvfs.h */
3629#define _SVID3
3630#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003631#include <sys/statvfs.h>
3632
3633static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003634"fstatvfs(fd) -> \n\
3635 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003636Perform an fstatvfs system call on the given fd.";
3637
3638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003639posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003640{
3641 int fd, res;
3642 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003643 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003644 return NULL;
3645 Py_BEGIN_ALLOW_THREADS
3646 res = fstatvfs(fd, &st);
3647 Py_END_ALLOW_THREADS
3648 if (res != 0)
3649 return posix_error();
3650#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003651 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003652 (long) st.f_bsize,
3653 (long) st.f_frsize,
3654 (long) st.f_blocks,
3655 (long) st.f_bfree,
3656 (long) st.f_bavail,
3657 (long) st.f_files,
3658 (long) st.f_ffree,
3659 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003660 (long) st.f_flag,
3661 (long) st.f_namemax);
3662#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003663 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003664 (long) st.f_bsize,
3665 (long) st.f_frsize,
3666 (LONG_LONG) st.f_blocks,
3667 (LONG_LONG) st.f_bfree,
3668 (LONG_LONG) st.f_bavail,
3669 (LONG_LONG) st.f_files,
3670 (LONG_LONG) st.f_ffree,
3671 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003672 (long) st.f_flag,
3673 (long) st.f_namemax);
3674#endif
3675}
3676#endif /* HAVE_FSTATVFS */
3677
3678
3679#if defined(HAVE_STATVFS)
3680#include <sys/statvfs.h>
3681
3682static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003683"statvfs(path) -> \n\
3684 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003685Perform a statvfs system call on the given path.";
3686
3687static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003688posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003689{
3690 char *path;
3691 int res;
3692 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003693 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003694 return NULL;
3695 Py_BEGIN_ALLOW_THREADS
3696 res = statvfs(path, &st);
3697 Py_END_ALLOW_THREADS
3698 if (res != 0)
3699 return posix_error_with_filename(path);
3700#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003701 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003702 (long) st.f_bsize,
3703 (long) st.f_frsize,
3704 (long) st.f_blocks,
3705 (long) st.f_bfree,
3706 (long) st.f_bavail,
3707 (long) st.f_files,
3708 (long) st.f_ffree,
3709 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003710 (long) st.f_flag,
3711 (long) st.f_namemax);
3712#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003713 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003714 (long) st.f_bsize,
3715 (long) st.f_frsize,
3716 (LONG_LONG) st.f_blocks,
3717 (LONG_LONG) st.f_bfree,
3718 (LONG_LONG) st.f_bavail,
3719 (LONG_LONG) st.f_files,
3720 (LONG_LONG) st.f_ffree,
3721 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003722 (long) st.f_flag,
3723 (long) st.f_namemax);
3724#endif
3725}
3726#endif /* HAVE_STATVFS */
3727
3728
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003729#ifdef HAVE_TEMPNAM
3730static char posix_tempnam__doc__[] = "\
3731tempnam([dir[, prefix]]) -> string\n\
3732Return a unique name for a temporary file.\n\
3733The directory and a short may be specified as strings; they may be omitted\n\
3734or None if not needed.";
3735
3736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003737posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003738{
3739 PyObject *result = NULL;
3740 char *dir = NULL;
3741 char *pfx = NULL;
3742 char *name;
3743
3744 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
3745 return NULL;
3746 name = tempnam(dir, pfx);
3747 if (name == NULL)
3748 return PyErr_NoMemory();
3749 result = PyString_FromString(name);
3750 free(name);
3751 return result;
3752}
Guido van Rossumd371ff11999-01-25 16:12:23 +00003753#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003754
3755
3756#ifdef HAVE_TMPFILE
3757static char posix_tmpfile__doc__[] = "\
3758tmpfile() -> file object\n\
3759Create a temporary file with no directory entries.";
3760
3761static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003762posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003763{
3764 FILE *fp;
3765
3766 if (!PyArg_ParseTuple(args, ":tmpfile"))
3767 return NULL;
3768 fp = tmpfile();
3769 if (fp == NULL)
3770 return posix_error();
3771 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
3772}
3773#endif
3774
3775
3776#ifdef HAVE_TMPNAM
3777static char posix_tmpnam__doc__[] = "\
3778tmpnam() -> string\n\
3779Return a unique name for a temporary file.";
3780
3781static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003782posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003783{
3784 char buffer[L_tmpnam];
3785 char *name;
3786
3787 if (!PyArg_ParseTuple(args, ":tmpnam"))
3788 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00003789#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003790 name = tmpnam_r(buffer);
3791#else
3792 name = tmpnam(buffer);
3793#endif
3794 if (name == NULL) {
3795 PyErr_SetObject(PyExc_OSError,
3796 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00003797#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003798 "unexpected NULL from tmpnam_r"
3799#else
3800 "unexpected NULL from tmpnam"
3801#endif
3802 ));
3803 return NULL;
3804 }
3805 return PyString_FromString(buffer);
3806}
3807#endif
3808
3809
Fred Drakec9680921999-12-13 16:37:25 +00003810/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
3811 * It maps strings representing configuration variable names to
3812 * integer values, allowing those functions to be called with the
3813 * magic names instead of poluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00003814 * rarely-used constants. There are three separate tables that use
3815 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00003816 *
3817 * This code is always included, even if none of the interfaces that
3818 * need it are included. The #if hackery needed to avoid it would be
3819 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00003820 */
3821struct constdef {
3822 char *name;
3823 long value;
3824};
3825
Fred Drake12c6e2d1999-12-14 21:25:03 +00003826static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003827conv_confname(PyObject *arg, int *valuep, struct constdef *table,
3828 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003829{
3830 if (PyInt_Check(arg)) {
3831 *valuep = PyInt_AS_LONG(arg);
3832 return 1;
3833 }
3834 if (PyString_Check(arg)) {
3835 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00003836 size_t lo = 0;
3837 size_t mid;
3838 size_t hi = tablesize;
3839 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003840 char *confname = PyString_AS_STRING(arg);
3841 while (lo < hi) {
3842 mid = (lo + hi) / 2;
3843 cmp = strcmp(confname, table[mid].name);
3844 if (cmp < 0)
3845 hi = mid;
3846 else if (cmp > 0)
3847 lo = mid + 1;
3848 else {
3849 *valuep = table[mid].value;
3850 return 1;
3851 }
3852 }
3853 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
3854 }
3855 else
3856 PyErr_SetString(PyExc_TypeError,
3857 "configuration names must be strings or integers");
3858 return 0;
3859}
3860
3861
3862#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
3863static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00003864#ifdef _PC_ABI_AIO_XFER_MAX
3865 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
3866#endif
3867#ifdef _PC_ABI_ASYNC_IO
3868 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
3869#endif
Fred Drakec9680921999-12-13 16:37:25 +00003870#ifdef _PC_ASYNC_IO
3871 {"PC_ASYNC_IO", _PC_ASYNC_IO},
3872#endif
3873#ifdef _PC_CHOWN_RESTRICTED
3874 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
3875#endif
3876#ifdef _PC_FILESIZEBITS
3877 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
3878#endif
3879#ifdef _PC_LAST
3880 {"PC_LAST", _PC_LAST},
3881#endif
3882#ifdef _PC_LINK_MAX
3883 {"PC_LINK_MAX", _PC_LINK_MAX},
3884#endif
3885#ifdef _PC_MAX_CANON
3886 {"PC_MAX_CANON", _PC_MAX_CANON},
3887#endif
3888#ifdef _PC_MAX_INPUT
3889 {"PC_MAX_INPUT", _PC_MAX_INPUT},
3890#endif
3891#ifdef _PC_NAME_MAX
3892 {"PC_NAME_MAX", _PC_NAME_MAX},
3893#endif
3894#ifdef _PC_NO_TRUNC
3895 {"PC_NO_TRUNC", _PC_NO_TRUNC},
3896#endif
3897#ifdef _PC_PATH_MAX
3898 {"PC_PATH_MAX", _PC_PATH_MAX},
3899#endif
3900#ifdef _PC_PIPE_BUF
3901 {"PC_PIPE_BUF", _PC_PIPE_BUF},
3902#endif
3903#ifdef _PC_PRIO_IO
3904 {"PC_PRIO_IO", _PC_PRIO_IO},
3905#endif
3906#ifdef _PC_SOCK_MAXBUF
3907 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
3908#endif
3909#ifdef _PC_SYNC_IO
3910 {"PC_SYNC_IO", _PC_SYNC_IO},
3911#endif
3912#ifdef _PC_VDISABLE
3913 {"PC_VDISABLE", _PC_VDISABLE},
3914#endif
3915};
3916
Fred Drakec9680921999-12-13 16:37:25 +00003917static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003918conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00003919{
3920 return conv_confname(arg, valuep, posix_constants_pathconf,
3921 sizeof(posix_constants_pathconf)
3922 / sizeof(struct constdef));
3923}
3924#endif
3925
3926#ifdef HAVE_FPATHCONF
3927static char posix_fpathconf__doc__[] = "\
3928fpathconf(fd, name) -> integer\n\
3929Return the configuration limit name for the file descriptor fd.\n\
3930If there is no limit, return -1.";
3931
3932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003933posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00003934{
3935 PyObject *result = NULL;
3936 int name, fd;
3937
Fred Drake12c6e2d1999-12-14 21:25:03 +00003938 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
3939 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00003940 long limit;
3941
3942 errno = 0;
3943 limit = fpathconf(fd, name);
3944 if (limit == -1 && errno != 0)
3945 posix_error();
3946 else
3947 result = PyInt_FromLong(limit);
3948 }
3949 return result;
3950}
3951#endif
3952
3953
3954#ifdef HAVE_PATHCONF
3955static char posix_pathconf__doc__[] = "\
3956pathconf(path, name) -> integer\n\
3957Return the configuration limit name for the file or directory path.\n\
3958If there is no limit, return -1.";
3959
3960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003961posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00003962{
3963 PyObject *result = NULL;
3964 int name;
3965 char *path;
3966
3967 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
3968 conv_path_confname, &name)) {
3969 long limit;
3970
3971 errno = 0;
3972 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00003973 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00003974 if (errno == EINVAL)
3975 /* could be a path or name problem */
3976 posix_error();
3977 else
3978 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00003979 }
Fred Drakec9680921999-12-13 16:37:25 +00003980 else
3981 result = PyInt_FromLong(limit);
3982 }
3983 return result;
3984}
3985#endif
3986
3987#ifdef HAVE_CONFSTR
3988static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00003989#ifdef _CS_ARCHITECTURE
3990 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
3991#endif
3992#ifdef _CS_HOSTNAME
3993 {"CS_HOSTNAME", _CS_HOSTNAME},
3994#endif
3995#ifdef _CS_HW_PROVIDER
3996 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
3997#endif
3998#ifdef _CS_HW_SERIAL
3999 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4000#endif
4001#ifdef _CS_INITTAB_NAME
4002 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4003#endif
Fred Drakec9680921999-12-13 16:37:25 +00004004#ifdef _CS_LFS64_CFLAGS
4005 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4006#endif
4007#ifdef _CS_LFS64_LDFLAGS
4008 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4009#endif
4010#ifdef _CS_LFS64_LIBS
4011 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4012#endif
4013#ifdef _CS_LFS64_LINTFLAGS
4014 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4015#endif
4016#ifdef _CS_LFS_CFLAGS
4017 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4018#endif
4019#ifdef _CS_LFS_LDFLAGS
4020 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4021#endif
4022#ifdef _CS_LFS_LIBS
4023 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4024#endif
4025#ifdef _CS_LFS_LINTFLAGS
4026 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4027#endif
Fred Draked86ed291999-12-15 15:34:33 +00004028#ifdef _CS_MACHINE
4029 {"CS_MACHINE", _CS_MACHINE},
4030#endif
Fred Drakec9680921999-12-13 16:37:25 +00004031#ifdef _CS_PATH
4032 {"CS_PATH", _CS_PATH},
4033#endif
Fred Draked86ed291999-12-15 15:34:33 +00004034#ifdef _CS_RELEASE
4035 {"CS_RELEASE", _CS_RELEASE},
4036#endif
4037#ifdef _CS_SRPC_DOMAIN
4038 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4039#endif
4040#ifdef _CS_SYSNAME
4041 {"CS_SYSNAME", _CS_SYSNAME},
4042#endif
4043#ifdef _CS_VERSION
4044 {"CS_VERSION", _CS_VERSION},
4045#endif
Fred Drakec9680921999-12-13 16:37:25 +00004046#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4047 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4048#endif
4049#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4050 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4051#endif
4052#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4053 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4054#endif
4055#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4056 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4057#endif
4058#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4059 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4060#endif
4061#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4062 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4063#endif
4064#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4065 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4066#endif
4067#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4068 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4069#endif
4070#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4071 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4072#endif
4073#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4074 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4075#endif
4076#ifdef _CS_XBS5_LP64_OFF64_LIBS
4077 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4078#endif
4079#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4080 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4081#endif
4082#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4083 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4084#endif
4085#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4086 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4087#endif
4088#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4089 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4090#endif
4091#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4092 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4093#endif
Fred Draked86ed291999-12-15 15:34:33 +00004094#ifdef _MIPS_CS_AVAIL_PROCESSORS
4095 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4096#endif
4097#ifdef _MIPS_CS_BASE
4098 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4099#endif
4100#ifdef _MIPS_CS_HOSTID
4101 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4102#endif
4103#ifdef _MIPS_CS_HW_NAME
4104 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4105#endif
4106#ifdef _MIPS_CS_NUM_PROCESSORS
4107 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4108#endif
4109#ifdef _MIPS_CS_OSREL_MAJ
4110 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4111#endif
4112#ifdef _MIPS_CS_OSREL_MIN
4113 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4114#endif
4115#ifdef _MIPS_CS_OSREL_PATCH
4116 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4117#endif
4118#ifdef _MIPS_CS_OS_NAME
4119 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4120#endif
4121#ifdef _MIPS_CS_OS_PROVIDER
4122 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4123#endif
4124#ifdef _MIPS_CS_PROCESSORS
4125 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4126#endif
4127#ifdef _MIPS_CS_SERIAL
4128 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4129#endif
4130#ifdef _MIPS_CS_VENDOR
4131 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4132#endif
Fred Drakec9680921999-12-13 16:37:25 +00004133};
4134
4135static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004136conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004137{
4138 return conv_confname(arg, valuep, posix_constants_confstr,
4139 sizeof(posix_constants_confstr)
4140 / sizeof(struct constdef));
4141}
4142
4143static char posix_confstr__doc__[] = "\
4144confstr(name) -> string\n\
4145Return a string-valued system configuration variable.";
4146
4147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004148posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004149{
4150 PyObject *result = NULL;
4151 int name;
4152 char buffer[64];
4153
4154 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4155 int len = confstr(name, buffer, sizeof(buffer));
4156
Fred Drakec9680921999-12-13 16:37:25 +00004157 errno = 0;
4158 if (len == 0) {
4159 if (errno != 0)
4160 posix_error();
4161 else
4162 result = PyString_FromString("");
4163 }
4164 else {
4165 if (len >= sizeof(buffer)) {
4166 result = PyString_FromStringAndSize(NULL, len);
4167 if (result != NULL)
4168 confstr(name, PyString_AS_STRING(result), len+1);
4169 }
4170 else
4171 result = PyString_FromString(buffer);
4172 }
4173 }
4174 return result;
4175}
4176#endif
4177
4178
4179#ifdef HAVE_SYSCONF
4180static struct constdef posix_constants_sysconf[] = {
4181#ifdef _SC_2_CHAR_TERM
4182 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4183#endif
4184#ifdef _SC_2_C_BIND
4185 {"SC_2_C_BIND", _SC_2_C_BIND},
4186#endif
4187#ifdef _SC_2_C_DEV
4188 {"SC_2_C_DEV", _SC_2_C_DEV},
4189#endif
4190#ifdef _SC_2_C_VERSION
4191 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4192#endif
4193#ifdef _SC_2_FORT_DEV
4194 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4195#endif
4196#ifdef _SC_2_FORT_RUN
4197 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4198#endif
4199#ifdef _SC_2_LOCALEDEF
4200 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4201#endif
4202#ifdef _SC_2_SW_DEV
4203 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4204#endif
4205#ifdef _SC_2_UPE
4206 {"SC_2_UPE", _SC_2_UPE},
4207#endif
4208#ifdef _SC_2_VERSION
4209 {"SC_2_VERSION", _SC_2_VERSION},
4210#endif
Fred Draked86ed291999-12-15 15:34:33 +00004211#ifdef _SC_ABI_ASYNCHRONOUS_IO
4212 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4213#endif
4214#ifdef _SC_ACL
4215 {"SC_ACL", _SC_ACL},
4216#endif
Fred Drakec9680921999-12-13 16:37:25 +00004217#ifdef _SC_AIO_LISTIO_MAX
4218 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4219#endif
Fred Drakec9680921999-12-13 16:37:25 +00004220#ifdef _SC_AIO_MAX
4221 {"SC_AIO_MAX", _SC_AIO_MAX},
4222#endif
4223#ifdef _SC_AIO_PRIO_DELTA_MAX
4224 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4225#endif
4226#ifdef _SC_ARG_MAX
4227 {"SC_ARG_MAX", _SC_ARG_MAX},
4228#endif
4229#ifdef _SC_ASYNCHRONOUS_IO
4230 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4231#endif
4232#ifdef _SC_ATEXIT_MAX
4233 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4234#endif
Fred Draked86ed291999-12-15 15:34:33 +00004235#ifdef _SC_AUDIT
4236 {"SC_AUDIT", _SC_AUDIT},
4237#endif
Fred Drakec9680921999-12-13 16:37:25 +00004238#ifdef _SC_AVPHYS_PAGES
4239 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4240#endif
4241#ifdef _SC_BC_BASE_MAX
4242 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4243#endif
4244#ifdef _SC_BC_DIM_MAX
4245 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4246#endif
4247#ifdef _SC_BC_SCALE_MAX
4248 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4249#endif
4250#ifdef _SC_BC_STRING_MAX
4251 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4252#endif
Fred Draked86ed291999-12-15 15:34:33 +00004253#ifdef _SC_CAP
4254 {"SC_CAP", _SC_CAP},
4255#endif
Fred Drakec9680921999-12-13 16:37:25 +00004256#ifdef _SC_CHARCLASS_NAME_MAX
4257 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4258#endif
4259#ifdef _SC_CHAR_BIT
4260 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4261#endif
4262#ifdef _SC_CHAR_MAX
4263 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4264#endif
4265#ifdef _SC_CHAR_MIN
4266 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4267#endif
4268#ifdef _SC_CHILD_MAX
4269 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4270#endif
4271#ifdef _SC_CLK_TCK
4272 {"SC_CLK_TCK", _SC_CLK_TCK},
4273#endif
4274#ifdef _SC_COHER_BLKSZ
4275 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4276#endif
4277#ifdef _SC_COLL_WEIGHTS_MAX
4278 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4279#endif
4280#ifdef _SC_DCACHE_ASSOC
4281 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4282#endif
4283#ifdef _SC_DCACHE_BLKSZ
4284 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4285#endif
4286#ifdef _SC_DCACHE_LINESZ
4287 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4288#endif
4289#ifdef _SC_DCACHE_SZ
4290 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4291#endif
4292#ifdef _SC_DCACHE_TBLKSZ
4293 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4294#endif
4295#ifdef _SC_DELAYTIMER_MAX
4296 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4297#endif
4298#ifdef _SC_EQUIV_CLASS_MAX
4299 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4300#endif
4301#ifdef _SC_EXPR_NEST_MAX
4302 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4303#endif
4304#ifdef _SC_FSYNC
4305 {"SC_FSYNC", _SC_FSYNC},
4306#endif
4307#ifdef _SC_GETGR_R_SIZE_MAX
4308 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4309#endif
4310#ifdef _SC_GETPW_R_SIZE_MAX
4311 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4312#endif
4313#ifdef _SC_ICACHE_ASSOC
4314 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4315#endif
4316#ifdef _SC_ICACHE_BLKSZ
4317 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4318#endif
4319#ifdef _SC_ICACHE_LINESZ
4320 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4321#endif
4322#ifdef _SC_ICACHE_SZ
4323 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4324#endif
Fred Draked86ed291999-12-15 15:34:33 +00004325#ifdef _SC_INF
4326 {"SC_INF", _SC_INF},
4327#endif
Fred Drakec9680921999-12-13 16:37:25 +00004328#ifdef _SC_INT_MAX
4329 {"SC_INT_MAX", _SC_INT_MAX},
4330#endif
4331#ifdef _SC_INT_MIN
4332 {"SC_INT_MIN", _SC_INT_MIN},
4333#endif
4334#ifdef _SC_IOV_MAX
4335 {"SC_IOV_MAX", _SC_IOV_MAX},
4336#endif
Fred Draked86ed291999-12-15 15:34:33 +00004337#ifdef _SC_IP_SECOPTS
4338 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4339#endif
Fred Drakec9680921999-12-13 16:37:25 +00004340#ifdef _SC_JOB_CONTROL
4341 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4342#endif
Fred Draked86ed291999-12-15 15:34:33 +00004343#ifdef _SC_KERN_POINTERS
4344 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4345#endif
4346#ifdef _SC_KERN_SIM
4347 {"SC_KERN_SIM", _SC_KERN_SIM},
4348#endif
Fred Drakec9680921999-12-13 16:37:25 +00004349#ifdef _SC_LINE_MAX
4350 {"SC_LINE_MAX", _SC_LINE_MAX},
4351#endif
4352#ifdef _SC_LOGIN_NAME_MAX
4353 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4354#endif
4355#ifdef _SC_LOGNAME_MAX
4356 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4357#endif
4358#ifdef _SC_LONG_BIT
4359 {"SC_LONG_BIT", _SC_LONG_BIT},
4360#endif
Fred Draked86ed291999-12-15 15:34:33 +00004361#ifdef _SC_MAC
4362 {"SC_MAC", _SC_MAC},
4363#endif
Fred Drakec9680921999-12-13 16:37:25 +00004364#ifdef _SC_MAPPED_FILES
4365 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4366#endif
4367#ifdef _SC_MAXPID
4368 {"SC_MAXPID", _SC_MAXPID},
4369#endif
4370#ifdef _SC_MB_LEN_MAX
4371 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4372#endif
4373#ifdef _SC_MEMLOCK
4374 {"SC_MEMLOCK", _SC_MEMLOCK},
4375#endif
4376#ifdef _SC_MEMLOCK_RANGE
4377 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4378#endif
4379#ifdef _SC_MEMORY_PROTECTION
4380 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4381#endif
4382#ifdef _SC_MESSAGE_PASSING
4383 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4384#endif
Fred Draked86ed291999-12-15 15:34:33 +00004385#ifdef _SC_MMAP_FIXED_ALIGNMENT
4386 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4387#endif
Fred Drakec9680921999-12-13 16:37:25 +00004388#ifdef _SC_MQ_OPEN_MAX
4389 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4390#endif
4391#ifdef _SC_MQ_PRIO_MAX
4392 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4393#endif
Fred Draked86ed291999-12-15 15:34:33 +00004394#ifdef _SC_NACLS_MAX
4395 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4396#endif
Fred Drakec9680921999-12-13 16:37:25 +00004397#ifdef _SC_NGROUPS_MAX
4398 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4399#endif
4400#ifdef _SC_NL_ARGMAX
4401 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4402#endif
4403#ifdef _SC_NL_LANGMAX
4404 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4405#endif
4406#ifdef _SC_NL_MSGMAX
4407 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4408#endif
4409#ifdef _SC_NL_NMAX
4410 {"SC_NL_NMAX", _SC_NL_NMAX},
4411#endif
4412#ifdef _SC_NL_SETMAX
4413 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4414#endif
4415#ifdef _SC_NL_TEXTMAX
4416 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4417#endif
4418#ifdef _SC_NPROCESSORS_CONF
4419 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4420#endif
4421#ifdef _SC_NPROCESSORS_ONLN
4422 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4423#endif
Fred Draked86ed291999-12-15 15:34:33 +00004424#ifdef _SC_NPROC_CONF
4425 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4426#endif
4427#ifdef _SC_NPROC_ONLN
4428 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4429#endif
Fred Drakec9680921999-12-13 16:37:25 +00004430#ifdef _SC_NZERO
4431 {"SC_NZERO", _SC_NZERO},
4432#endif
4433#ifdef _SC_OPEN_MAX
4434 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4435#endif
4436#ifdef _SC_PAGESIZE
4437 {"SC_PAGESIZE", _SC_PAGESIZE},
4438#endif
4439#ifdef _SC_PAGE_SIZE
4440 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4441#endif
4442#ifdef _SC_PASS_MAX
4443 {"SC_PASS_MAX", _SC_PASS_MAX},
4444#endif
4445#ifdef _SC_PHYS_PAGES
4446 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4447#endif
4448#ifdef _SC_PII
4449 {"SC_PII", _SC_PII},
4450#endif
4451#ifdef _SC_PII_INTERNET
4452 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4453#endif
4454#ifdef _SC_PII_INTERNET_DGRAM
4455 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4456#endif
4457#ifdef _SC_PII_INTERNET_STREAM
4458 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4459#endif
4460#ifdef _SC_PII_OSI
4461 {"SC_PII_OSI", _SC_PII_OSI},
4462#endif
4463#ifdef _SC_PII_OSI_CLTS
4464 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4465#endif
4466#ifdef _SC_PII_OSI_COTS
4467 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4468#endif
4469#ifdef _SC_PII_OSI_M
4470 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4471#endif
4472#ifdef _SC_PII_SOCKET
4473 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4474#endif
4475#ifdef _SC_PII_XTI
4476 {"SC_PII_XTI", _SC_PII_XTI},
4477#endif
4478#ifdef _SC_POLL
4479 {"SC_POLL", _SC_POLL},
4480#endif
4481#ifdef _SC_PRIORITIZED_IO
4482 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4483#endif
4484#ifdef _SC_PRIORITY_SCHEDULING
4485 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4486#endif
4487#ifdef _SC_REALTIME_SIGNALS
4488 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4489#endif
4490#ifdef _SC_RE_DUP_MAX
4491 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4492#endif
4493#ifdef _SC_RTSIG_MAX
4494 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4495#endif
4496#ifdef _SC_SAVED_IDS
4497 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4498#endif
4499#ifdef _SC_SCHAR_MAX
4500 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4501#endif
4502#ifdef _SC_SCHAR_MIN
4503 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4504#endif
4505#ifdef _SC_SELECT
4506 {"SC_SELECT", _SC_SELECT},
4507#endif
4508#ifdef _SC_SEMAPHORES
4509 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4510#endif
4511#ifdef _SC_SEM_NSEMS_MAX
4512 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4513#endif
4514#ifdef _SC_SEM_VALUE_MAX
4515 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4516#endif
4517#ifdef _SC_SHARED_MEMORY_OBJECTS
4518 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4519#endif
4520#ifdef _SC_SHRT_MAX
4521 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4522#endif
4523#ifdef _SC_SHRT_MIN
4524 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4525#endif
4526#ifdef _SC_SIGQUEUE_MAX
4527 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4528#endif
4529#ifdef _SC_SIGRT_MAX
4530 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4531#endif
4532#ifdef _SC_SIGRT_MIN
4533 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4534#endif
Fred Draked86ed291999-12-15 15:34:33 +00004535#ifdef _SC_SOFTPOWER
4536 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4537#endif
Fred Drakec9680921999-12-13 16:37:25 +00004538#ifdef _SC_SPLIT_CACHE
4539 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4540#endif
4541#ifdef _SC_SSIZE_MAX
4542 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4543#endif
4544#ifdef _SC_STACK_PROT
4545 {"SC_STACK_PROT", _SC_STACK_PROT},
4546#endif
4547#ifdef _SC_STREAM_MAX
4548 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4549#endif
4550#ifdef _SC_SYNCHRONIZED_IO
4551 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4552#endif
4553#ifdef _SC_THREADS
4554 {"SC_THREADS", _SC_THREADS},
4555#endif
4556#ifdef _SC_THREAD_ATTR_STACKADDR
4557 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4558#endif
4559#ifdef _SC_THREAD_ATTR_STACKSIZE
4560 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4561#endif
4562#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4563 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4564#endif
4565#ifdef _SC_THREAD_KEYS_MAX
4566 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4567#endif
4568#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4569 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4570#endif
4571#ifdef _SC_THREAD_PRIO_INHERIT
4572 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4573#endif
4574#ifdef _SC_THREAD_PRIO_PROTECT
4575 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4576#endif
4577#ifdef _SC_THREAD_PROCESS_SHARED
4578 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4579#endif
4580#ifdef _SC_THREAD_SAFE_FUNCTIONS
4581 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4582#endif
4583#ifdef _SC_THREAD_STACK_MIN
4584 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4585#endif
4586#ifdef _SC_THREAD_THREADS_MAX
4587 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4588#endif
4589#ifdef _SC_TIMERS
4590 {"SC_TIMERS", _SC_TIMERS},
4591#endif
4592#ifdef _SC_TIMER_MAX
4593 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4594#endif
4595#ifdef _SC_TTY_NAME_MAX
4596 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4597#endif
4598#ifdef _SC_TZNAME_MAX
4599 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4600#endif
4601#ifdef _SC_T_IOV_MAX
4602 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4603#endif
4604#ifdef _SC_UCHAR_MAX
4605 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4606#endif
4607#ifdef _SC_UINT_MAX
4608 {"SC_UINT_MAX", _SC_UINT_MAX},
4609#endif
4610#ifdef _SC_UIO_MAXIOV
4611 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4612#endif
4613#ifdef _SC_ULONG_MAX
4614 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4615#endif
4616#ifdef _SC_USHRT_MAX
4617 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4618#endif
4619#ifdef _SC_VERSION
4620 {"SC_VERSION", _SC_VERSION},
4621#endif
4622#ifdef _SC_WORD_BIT
4623 {"SC_WORD_BIT", _SC_WORD_BIT},
4624#endif
4625#ifdef _SC_XBS5_ILP32_OFF32
4626 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4627#endif
4628#ifdef _SC_XBS5_ILP32_OFFBIG
4629 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4630#endif
4631#ifdef _SC_XBS5_LP64_OFF64
4632 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4633#endif
4634#ifdef _SC_XBS5_LPBIG_OFFBIG
4635 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
4636#endif
4637#ifdef _SC_XOPEN_CRYPT
4638 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
4639#endif
4640#ifdef _SC_XOPEN_ENH_I18N
4641 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
4642#endif
4643#ifdef _SC_XOPEN_LEGACY
4644 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
4645#endif
4646#ifdef _SC_XOPEN_REALTIME
4647 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
4648#endif
4649#ifdef _SC_XOPEN_REALTIME_THREADS
4650 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
4651#endif
4652#ifdef _SC_XOPEN_SHM
4653 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
4654#endif
4655#ifdef _SC_XOPEN_UNIX
4656 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
4657#endif
4658#ifdef _SC_XOPEN_VERSION
4659 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
4660#endif
4661#ifdef _SC_XOPEN_XCU_VERSION
4662 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
4663#endif
4664#ifdef _SC_XOPEN_XPG2
4665 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
4666#endif
4667#ifdef _SC_XOPEN_XPG3
4668 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
4669#endif
4670#ifdef _SC_XOPEN_XPG4
4671 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
4672#endif
4673};
4674
4675static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004676conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004677{
4678 return conv_confname(arg, valuep, posix_constants_sysconf,
4679 sizeof(posix_constants_sysconf)
4680 / sizeof(struct constdef));
4681}
4682
4683static char posix_sysconf__doc__[] = "\
4684sysconf(name) -> integer\n\
4685Return an integer-valued system configuration variable.";
4686
4687static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004688posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004689{
4690 PyObject *result = NULL;
4691 int name;
4692
4693 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
4694 int value;
4695
4696 errno = 0;
4697 value = sysconf(name);
4698 if (value == -1 && errno != 0)
4699 posix_error();
4700 else
4701 result = PyInt_FromLong(value);
4702 }
4703 return result;
4704}
4705#endif
4706
4707
Fred Drakebec628d1999-12-15 18:31:10 +00004708/* This code is used to ensure that the tables of configuration value names
4709 * are in sorted order as required by conv_confname(), and also to build the
4710 * the exported dictionaries that are used to publish information about the
4711 * names available on the host platform.
4712 *
4713 * Sorting the table at runtime ensures that the table is properly ordered
4714 * when used, even for platforms we're not able to test on. It also makes
4715 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00004716 */
Fred Drakebec628d1999-12-15 18:31:10 +00004717
4718static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004719cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00004720{
4721 const struct constdef *c1 =
4722 (const struct constdef *) v1;
4723 const struct constdef *c2 =
4724 (const struct constdef *) v2;
4725
4726 return strcmp(c1->name, c2->name);
4727}
4728
4729static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004730setup_confname_table(struct constdef *table, size_t tablesize,
4731 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004732{
Fred Drakebec628d1999-12-15 18:31:10 +00004733 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00004734 size_t i;
4735 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00004736
4737 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
4738 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00004739 if (d == NULL)
4740 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004741
Barry Warsaw3155db32000-04-13 15:20:40 +00004742 for (i=0; i < tablesize; ++i) {
4743 PyObject *o = PyInt_FromLong(table[i].value);
4744 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
4745 Py_XDECREF(o);
4746 Py_DECREF(d);
4747 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004748 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004749 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00004750 }
Barry Warsaw3155db32000-04-13 15:20:40 +00004751 status = PyDict_SetItemString(moddict, tablename, d);
4752 Py_DECREF(d);
4753 return status;
Fred Draked86ed291999-12-15 15:34:33 +00004754}
4755
Fred Drakebec628d1999-12-15 18:31:10 +00004756/* Return -1 on failure, 0 on success. */
4757static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004758setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004759{
4760#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00004761 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00004762 sizeof(posix_constants_pathconf)
4763 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004764 "pathconf_names", moddict))
4765 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004766#endif
4767#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00004768 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00004769 sizeof(posix_constants_confstr)
4770 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004771 "confstr_names", moddict))
4772 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004773#endif
4774#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00004775 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00004776 sizeof(posix_constants_sysconf)
4777 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00004778 "sysconf_names", moddict))
4779 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00004780#endif
Fred Drakebec628d1999-12-15 18:31:10 +00004781 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00004782}
Fred Draked86ed291999-12-15 15:34:33 +00004783
4784
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004785static char posix_abort__doc__[] = "\
4786abort() -> does not return!\n\
4787Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
4788in the hardest way possible on the hosting operating system.";
4789
4790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004791posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004792{
4793 if (!PyArg_ParseTuple(args, ":abort"))
4794 return NULL;
4795 abort();
4796 /*NOTREACHED*/
4797 Py_FatalError("abort() called from Python code didn't abort!");
4798 return NULL;
4799}
Fred Drakebec628d1999-12-15 18:31:10 +00004800
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004801
4802static PyMethodDef posix_methods[] = {
4803 {"access", posix_access, METH_VARARGS, posix_access__doc__},
4804#ifdef HAVE_TTYNAME
4805 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
4806#endif
4807 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
4808 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004809#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004810 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004811#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004812#ifdef HAVE_CTERMID
4813 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
4814#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00004815#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004816 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00004817#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004818#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004819 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004820#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004821 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
4822 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
4823 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004824#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004825 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004826#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004827#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004828 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004829#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004830 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
4831 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
4832 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004833#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004834 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004835#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004836#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004837 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004838#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004839 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004840#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004841 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004842#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004843 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
4844 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
4845 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004846#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004847 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004848#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004849 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004850#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004851 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
4852 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004853#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00004854#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004855 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
4856 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00004857#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004858#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004859 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004860#endif /* HAVE_FORK */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004861#ifdef HAVE_OPENPTY
4862 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
4863#endif /* HAVE_OPENPTY */
4864#ifdef HAVE_FORKPTY
4865 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
4866#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004867#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004868 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004869#endif /* HAVE_GETEGID */
4870#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004871 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004872#endif /* HAVE_GETEUID */
4873#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004874 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004875#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00004876#ifdef HAVE_GETGROUPS
4877 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
4878#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004879 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00004880#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004881 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004882#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004883#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004884 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004885#endif /* HAVE_GETPPID */
4886#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004887 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004888#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00004889#ifdef HAVE_GETLOGIN
4890 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
4891#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00004892#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004893 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004894#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00004895#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004896 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00004897#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004898#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004899 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004900#ifdef MS_WIN32
4901 {"popen2", win32_popen2, METH_VARARGS},
4902 {"popen3", win32_popen3, METH_VARARGS},
4903 {"popen4", win32_popen4, METH_VARARGS},
4904#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004905#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004906#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004907 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004908#endif /* HAVE_SETUID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004909#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004910 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004911#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004912#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004913 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004914#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00004915#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004916 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00004917#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004918#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004919 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004920#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004921#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004922 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004923#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004924#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004925 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004926#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004927#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004928 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004929#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004930#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004931 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004932#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004933 {"open", posix_open, METH_VARARGS, posix_open__doc__},
4934 {"close", posix_close, METH_VARARGS, posix_close__doc__},
4935 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
4936 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
4937 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
4938 {"read", posix_read, METH_VARARGS, posix_read__doc__},
4939 {"write", posix_write, METH_VARARGS, posix_write__doc__},
4940 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
4941 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004942#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004943 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004944#endif
4945#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004946 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004947#endif
4948#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004949 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004950#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004951#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004952 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004953#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00004954#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004955 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00004956#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00004957#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004958 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00004959#endif
4960#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004961 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00004962#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00004963#ifdef HAVE_SYS_WAIT_H
4964#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004965 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004966#endif /* WIFSTOPPED */
4967#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004968 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004969#endif /* WIFSIGNALED */
4970#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004971 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004972#endif /* WIFEXITED */
4973#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004974 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004975#endif /* WEXITSTATUS */
4976#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004977 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004978#endif /* WTERMSIG */
4979#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004980 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00004981#endif /* WSTOPSIG */
4982#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004983#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004984 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00004985#endif
4986#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004987 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00004988#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004989#ifdef HAVE_TMPNAM
4990 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
4991#endif
4992#ifdef HAVE_TEMPNAM
4993 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
4994#endif
4995#ifdef HAVE_TMPNAM
4996 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
4997#endif
Fred Drakec9680921999-12-13 16:37:25 +00004998#ifdef HAVE_CONFSTR
4999 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5000#endif
5001#ifdef HAVE_SYSCONF
5002 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5003#endif
5004#ifdef HAVE_FPATHCONF
5005 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5006#endif
5007#ifdef HAVE_PATHCONF
5008 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5009#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005010 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005011 {NULL, NULL} /* Sentinel */
5012};
5013
5014
Barry Warsaw4a342091996-12-19 23:50:02 +00005015static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005016ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005017{
5018 PyObject* v = PyInt_FromLong(value);
5019 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5020 return -1; /* triggers fatal error */
5021
5022 Py_DECREF(v);
5023 return 0;
5024}
5025
Guido van Rossumd48f2521997-12-05 22:19:34 +00005026#if defined(PYOS_OS2)
5027/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5028static int insertvalues(PyObject *d)
5029{
5030 APIRET rc;
5031 ULONG values[QSV_MAX+1];
5032 PyObject *v;
5033 char *ver, tmp[10];
5034
5035 Py_BEGIN_ALLOW_THREADS
5036 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5037 Py_END_ALLOW_THREADS
5038
5039 if (rc != NO_ERROR) {
5040 os2_error(rc);
5041 return -1;
5042 }
5043
5044 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5045 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5046 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5047 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5048 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5049 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5050 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5051
5052 switch (values[QSV_VERSION_MINOR]) {
5053 case 0: ver = "2.00"; break;
5054 case 10: ver = "2.10"; break;
5055 case 11: ver = "2.11"; break;
5056 case 30: ver = "3.00"; break;
5057 case 40: ver = "4.00"; break;
5058 case 50: ver = "5.00"; break;
5059 default:
5060 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5061 values[QSV_VERSION_MINOR]);
5062 ver = &tmp[0];
5063 }
5064
5065 /* Add Indicator of the Version of the Operating System */
5066 v = PyString_FromString(ver);
5067 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5068 return -1;
5069 Py_DECREF(v);
5070
5071 /* Add Indicator of Which Drive was Used to Boot the System */
5072 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5073 tmp[1] = ':';
5074 tmp[2] = '\0';
5075
5076 v = PyString_FromString(tmp);
5077 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5078 return -1;
5079 Py_DECREF(v);
5080
5081 return 0;
5082}
5083#endif
5084
Barry Warsaw4a342091996-12-19 23:50:02 +00005085static int
5086all_ins(d)
5087 PyObject* d;
5088{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005089#ifdef F_OK
5090 if (ins(d, "F_OK", (long)F_OK)) return -1;
5091#endif
5092#ifdef R_OK
5093 if (ins(d, "R_OK", (long)R_OK)) return -1;
5094#endif
5095#ifdef W_OK
5096 if (ins(d, "W_OK", (long)W_OK)) return -1;
5097#endif
5098#ifdef X_OK
5099 if (ins(d, "X_OK", (long)X_OK)) return -1;
5100#endif
Fred Drakec9680921999-12-13 16:37:25 +00005101#ifdef NGROUPS_MAX
5102 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5103#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005104#ifdef TMP_MAX
5105 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5106#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005107#ifdef WNOHANG
5108 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5109#endif
5110#ifdef O_RDONLY
5111 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5112#endif
5113#ifdef O_WRONLY
5114 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5115#endif
5116#ifdef O_RDWR
5117 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5118#endif
5119#ifdef O_NDELAY
5120 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5121#endif
5122#ifdef O_NONBLOCK
5123 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5124#endif
5125#ifdef O_APPEND
5126 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5127#endif
5128#ifdef O_DSYNC
5129 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5130#endif
5131#ifdef O_RSYNC
5132 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5133#endif
5134#ifdef O_SYNC
5135 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5136#endif
5137#ifdef O_NOCTTY
5138 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5139#endif
5140#ifdef O_CREAT
5141 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5142#endif
5143#ifdef O_EXCL
5144 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5145#endif
5146#ifdef O_TRUNC
5147 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5148#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005149#ifdef O_BINARY
5150 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5151#endif
5152#ifdef O_TEXT
5153 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5154#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005155
Guido van Rossum246bc171999-02-01 23:54:31 +00005156#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005157 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5158 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5159 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5160 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5161 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005162#endif
5163
Guido van Rossumd48f2521997-12-05 22:19:34 +00005164#if defined(PYOS_OS2)
5165 if (insertvalues(d)) return -1;
5166#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005167 return 0;
5168}
5169
5170
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005171#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005172#define INITFUNC initnt
5173#define MODNAME "nt"
5174#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005175#if defined(PYOS_OS2)
5176#define INITFUNC initos2
5177#define MODNAME "os2"
5178#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005179#define INITFUNC initposix
5180#define MODNAME "posix"
5181#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005182#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005183
Guido van Rossum3886bb61998-12-04 18:50:17 +00005184DL_EXPORT(void)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005185INITFUNC()
Guido van Rossumb6775db1994-08-01 11:34:53 +00005186{
Barry Warsaw53699e91996-12-10 23:23:01 +00005187 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005188
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005189 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005190 posix_methods,
5191 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005192 (PyObject *)NULL,
5193 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005194 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005195
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005196 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005197 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005198 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005199 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005200 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005201
Barry Warsaw4a342091996-12-19 23:50:02 +00005202 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005203 return;
5204
Fred Drakebec628d1999-12-15 18:31:10 +00005205 if (setup_confname_tables(d))
5206 return;
5207
Barry Warsawca74da41999-02-09 19:31:45 +00005208 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005209
Guido van Rossumb3d39562000-01-31 18:41:26 +00005210#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00005211 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005212#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005213}