blob: e7f35cfdbd2fe2baf4ba206d08a0032a94d2369d [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#ifdef HAVE_FCNTL_H
49#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000050#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000051
Guido van Rossuma4916fa1996-05-23 22:58:55 +000052/* Various compilers have only certain posix functions */
Guido van Rossum6d8841c1997-08-14 19:57:39 +000053/* XXX Gosh I wish these were all moved into config.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000054#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000055#include <process.h>
56#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000057#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000058#define HAVE_GETCWD 1
59#define HAVE_OPENDIR 1
60#define HAVE_SYSTEM 1
61#if defined(__OS2__)
62#define HAVE_EXECV 1
63#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000064#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000065#include <process.h>
66#else
67#ifdef __BORLANDC__ /* Borland compiler */
68#define HAVE_EXECV 1
69#define HAVE_GETCWD 1
70#define HAVE_GETEGID 1
71#define HAVE_GETEUID 1
72#define HAVE_GETGID 1
73#define HAVE_GETPPID 1
74#define HAVE_GETUID 1
75#define HAVE_KILL 1
76#define HAVE_OPENDIR 1
77#define HAVE_PIPE 1
78#define HAVE_POPEN 1
79#define HAVE_SYSTEM 1
80#define HAVE_WAIT 1
81#else
82#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000083#define HAVE_GETCWD 1
84#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000085#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000086#define HAVE_EXECV 1
87#define HAVE_PIPE 1
88#define HAVE_POPEN 1
89#define HAVE_SYSTEM 1
90#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000091#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092#else /* all other compilers */
93/* Unix functions that the configure script doesn't check for */
94#define HAVE_EXECV 1
95#define HAVE_FORK 1
96#define HAVE_GETCWD 1
97#define HAVE_GETEGID 1
98#define HAVE_GETEUID 1
99#define HAVE_GETGID 1
100#define HAVE_GETPPID 1
101#define HAVE_GETUID 1
102#define HAVE_KILL 1
103#define HAVE_OPENDIR 1
104#define HAVE_PIPE 1
105#define HAVE_POPEN 1
106#define HAVE_SYSTEM 1
107#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000108#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000109#endif /* _MSC_VER */
110#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000111#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000112#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000113
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000114#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000115
Guido van Rossumb6775db1994-08-01 11:34:53 +0000116#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000117#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000118#endif
119
120#ifdef NeXT
121/* NeXT's <unistd.h> and <utime.h> aren't worth much */
122#undef HAVE_UNISTD_H
123#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000124#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000125/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000126#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000127#endif
128
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000129#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000130#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000131extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000132#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000133#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000136extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000138#endif
139#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int chdir(char *);
141extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000142#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int chdir(const char *);
144extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000145#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chmod(const char *, mode_t);
147extern int chown(const char *, uid_t, gid_t);
148extern char *getcwd(char *, int);
149extern char *strerror(int);
150extern int link(const char *, const char *);
151extern int rename(const char *, const char *);
152extern int stat(const char *, struct stat *);
153extern int unlink(const char *);
154extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000155#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000156extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000157#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000158#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000159extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000160#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000161#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000162
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000163#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_UTIME_H
166#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000167#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000169#ifdef HAVE_SYS_UTIME_H
170#include <sys/utime.h>
171#define HAVE_UTIME_H /* pretend we do for the rest of this file */
172#endif /* HAVE_SYS_UTIME_H */
173
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#ifdef HAVE_SYS_TIMES_H
175#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000176#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177
178#ifdef HAVE_SYS_PARAM_H
179#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000180#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181
182#ifdef HAVE_SYS_UTSNAME_H
183#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000184#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000185
186#ifndef MAXPATHLEN
187#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000188#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000190#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000191#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000192#define NAMLEN(dirent) strlen((dirent)->d_name)
193#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000194#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000195#include <direct.h>
196#define NAMLEN(dirent) strlen((dirent)->d_name)
197#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000200#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000203#endif
204#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#endif
207#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213#include <direct.h>
214#include <io.h>
215#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000216#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000218#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000219#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000220#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#else /* 16-bit Windows */
222#include <dos.h>
223#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000224#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
Guido van Rossumd48f2521997-12-05 22:19:34 +0000227#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000231#ifdef UNION_WAIT
232/* Emulate some macros on systems that have a union instead of macros */
233
234#ifndef WIFEXITED
235#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
236#endif
237
238#ifndef WEXITSTATUS
239#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
240#endif
241
242#ifndef WTERMSIG
243#define WTERMSIG(u_wait) ((u_wait).w_termsig)
244#endif
245
246#endif /* UNION_WAIT */
247
Greg Wardb48bc172000-03-01 21:51:56 +0000248/* Don't use the "_r" form if we don't need it (also, won't have a
249 prototype for it, at least on Solaris -- maybe others as well?). */
250#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
251#define USE_CTERMID_R
252#endif
253
254#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
255#define USE_TMPNAM_R
256#endif
257
Fred Drake699f3522000-06-29 21:12:41 +0000258/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000259#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000260#ifdef MS_WIN64
261# define STAT _stati64
262# define FSTAT _fstati64
263# define STRUCT_STAT struct _stati64
264#else
265# define STAT stat
266# define FSTAT fstat
267# define STRUCT_STAT struct stat
268#endif
269
270
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000271/* Return a dictionary corresponding to the POSIX environment table */
272
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000273#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000275#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276
Barry Warsaw53699e91996-12-10 23:23:01 +0000277static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000278convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279{
Barry Warsaw53699e91996-12-10 23:23:01 +0000280 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000282 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283 if (d == NULL)
284 return NULL;
285 if (environ == NULL)
286 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000287 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000289 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000290 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291 char *p = strchr(*e, '=');
292 if (p == NULL)
293 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000294 k = PyString_FromStringAndSize(*e, (int)(p-*e));
295 if (k == NULL) {
296 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000298 }
299 v = PyString_FromString(p+1);
300 if (v == NULL) {
301 PyErr_Clear();
302 Py_DECREF(k);
303 continue;
304 }
305 if (PyDict_GetItem(d, k) == NULL) {
306 if (PyDict_SetItem(d, k, v) != 0)
307 PyErr_Clear();
308 }
309 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000310 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000312#if defined(PYOS_OS2)
313 {
314 APIRET rc;
315 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
316
317 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000318 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000319 PyObject *v = PyString_FromString(buffer);
320 PyDict_SetItemString(d, "BEGINLIBPATH", v);
321 Py_DECREF(v);
322 }
323 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
324 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
325 PyObject *v = PyString_FromString(buffer);
326 PyDict_SetItemString(d, "ENDLIBPATH", v);
327 Py_DECREF(v);
328 }
329 }
330#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 return d;
332}
333
334
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335/* Set a POSIX-specific error from errno, and return NULL */
336
Barry Warsawd58d7641998-07-23 16:14:40 +0000337static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000338posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000339{
Barry Warsawca74da41999-02-09 19:31:45 +0000340 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341}
Barry Warsawd58d7641998-07-23 16:14:40 +0000342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000343posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000344{
Barry Warsawca74da41999-02-09 19:31:45 +0000345 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000346}
347
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000348#ifdef MS_WIN32
349static PyObject *
350win32_error(char* function, char* filename)
351{
352 /* XXX this could be improved */
353 errno = GetLastError();
354 if (filename)
355 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
356 else
357 return PyErr_SetFromErrno(PyExc_OSError);
358}
359#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000360
Guido van Rossumd48f2521997-12-05 22:19:34 +0000361#if defined(PYOS_OS2)
362/**********************************************************************
363 * Helper Function to Trim and Format OS/2 Messages
364 **********************************************************************/
365 static void
366os2_formatmsg(char *msgbuf, int msglen, char *reason)
367{
368 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
369
370 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
371 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
372
373 while (lastc > msgbuf && isspace(*lastc))
374 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
375 }
376
377 /* Add Optional Reason Text */
378 if (reason) {
379 strcat(msgbuf, " : ");
380 strcat(msgbuf, reason);
381 }
382}
383
384/**********************************************************************
385 * Decode an OS/2 Operating System Error Code
386 *
387 * A convenience function to lookup an OS/2 error code and return a
388 * text message we can use to raise a Python exception.
389 *
390 * Notes:
391 * The messages for errors returned from the OS/2 kernel reside in
392 * the file OSO001.MSG in the \OS2 directory hierarchy.
393 *
394 **********************************************************************/
395 static char *
396os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
397{
398 APIRET rc;
399 ULONG msglen;
400
401 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
402 Py_BEGIN_ALLOW_THREADS
403 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
404 errorcode, "oso001.msg", &msglen);
405 Py_END_ALLOW_THREADS
406
407 if (rc == NO_ERROR)
408 os2_formatmsg(msgbuf, msglen, reason);
409 else
410 sprintf(msgbuf, "unknown OS error #%d", errorcode);
411
412 return msgbuf;
413}
414
415/* Set an OS/2-specific error and return NULL. OS/2 kernel
416 errors are not in a global variable e.g. 'errno' nor are
417 they congruent with posix error numbers. */
418
419static PyObject * os2_error(int code)
420{
421 char text[1024];
422 PyObject *v;
423
424 os2_strerror(text, sizeof(text), code, "");
425
426 v = Py_BuildValue("(is)", code, text);
427 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000428 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000429 Py_DECREF(v);
430 }
431 return NULL; /* Signal to Python that an Exception is Pending */
432}
433
434#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000435
436/* POSIX generic methods */
437
Barry Warsaw53699e91996-12-10 23:23:01 +0000438static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000439posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000440{
441 int fd;
442 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000443 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000444 return NULL;
445 Py_BEGIN_ALLOW_THREADS
446 res = (*func)(fd);
447 Py_END_ALLOW_THREADS
448 if (res < 0)
449 return posix_error();
450 Py_INCREF(Py_None);
451 return Py_None;
452}
453
454
455static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000456posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000457{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000458 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000459 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000460 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000461 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000462 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000463 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000464 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000465 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000466 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000467 Py_INCREF(Py_None);
468 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000469}
470
Barry Warsaw53699e91996-12-10 23:23:01 +0000471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000472posix_2str(PyObject *args, char *format,
473 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000475 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000476 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000477 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000478 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000479 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000480 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000481 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000482 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000483 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000484 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000485 Py_INCREF(Py_None);
486 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487}
488
Fred Drake699f3522000-06-29 21:12:41 +0000489/* pack a system stat C structure into the Python stat tuple
490 (used by posix_stat() and posix_fstat()) */
491static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000492_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000493{
494 PyObject *v = PyTuple_New(10);
495 if (v == NULL)
496 return NULL;
497
498 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
499#ifdef HAVE_LARGEFILE_SUPPORT
500 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
501#else
502 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
503#endif
504#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
505 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
506#else
507 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
508#endif
509 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
510 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
511 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
512#ifdef HAVE_LARGEFILE_SUPPORT
513 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
514#else
515 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
516#endif
517#if SIZEOF_TIME_T > SIZEOF_LONG
518 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
519 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
520 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
521#else
522 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
523 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
524 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
525#endif
526
527 if (PyErr_Occurred()) {
528 Py_DECREF(v);
529 return NULL;
530 }
531
532 return v;
533}
534
535
Barry Warsaw53699e91996-12-10 23:23:01 +0000536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000537posix_do_stat(PyObject *self, PyObject *args, char *format,
538 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000539{
Fred Drake699f3522000-06-29 21:12:41 +0000540 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000541 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000542 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000543
544#ifdef MS_WIN32
545 int pathlen;
546 char pathcopy[MAX_PATH];
547#endif /* MS_WIN32 */
548
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000549 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000550 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000551
552#ifdef MS_WIN32
553 pathlen = strlen(path);
554 /* the library call can blow up if the file name is too long! */
555 if (pathlen > MAX_PATH) {
556 errno = ENAMETOOLONG;
557 return posix_error();
558 }
559
560 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000561 /* exception for specific or current drive root */
562 if (!((pathlen == 1) ||
563 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000564 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000565 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000566 {
567 strncpy(pathcopy, path, pathlen);
568 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
569 path = pathcopy;
570 }
571 }
572#endif /* MS_WIN32 */
573
Barry Warsaw53699e91996-12-10 23:23:01 +0000574 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000575 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000576 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000577 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000578 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000579
580 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000581}
582
583
584/* POSIX methods */
585
Guido van Rossum94f6f721999-01-06 18:42:14 +0000586static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000587"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000588Test for access to a file.";
589
590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000591posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000592{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000593 char *path;
594 int mode;
595 int res;
596
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000597 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000598 return NULL;
599 Py_BEGIN_ALLOW_THREADS
600 res = access(path, mode);
601 Py_END_ALLOW_THREADS
602 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000603}
604
Guido van Rossumd371ff11999-01-25 16:12:23 +0000605#ifndef F_OK
606#define F_OK 0
607#endif
608#ifndef R_OK
609#define R_OK 4
610#endif
611#ifndef W_OK
612#define W_OK 2
613#endif
614#ifndef X_OK
615#define X_OK 1
616#endif
617
618#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000619static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000620"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000621Return the name of the terminal device connected to 'fd'.";
622
623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000624posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000625{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000626 int id;
627 char *ret;
628
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000629 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000630 return NULL;
631
Guido van Rossum94f6f721999-01-06 18:42:14 +0000632 ret = ttyname(id);
633 if (ret == NULL)
634 return(posix_error());
635 return(PyString_FromString(ret));
636}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000637#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000638
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000639#ifdef HAVE_CTERMID
640static char posix_ctermid__doc__[] =
641"ctermid() -> String\n\
642Return the name of the controlling terminal for this process.";
643
644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000645posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000646{
647 char *ret;
648 char buffer[L_ctermid];
649
650 if (!PyArg_ParseTuple(args, ":ctermid"))
651 return NULL;
652
Greg Wardb48bc172000-03-01 21:51:56 +0000653#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000654 ret = ctermid_r(buffer);
655#else
656 ret = ctermid(buffer);
657#endif
658 if (ret == NULL)
659 return(posix_error());
660 return(PyString_FromString(buffer));
661}
662#endif
663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000664static char posix_chdir__doc__[] =
665"chdir(path) -> None\n\
666Change the current working directory to the specified path.";
667
Barry Warsaw53699e91996-12-10 23:23:01 +0000668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000669posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000670{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000671 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000672}
673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000674
675static char posix_chmod__doc__[] =
676"chmod(path, mode) -> None\n\
677Change the access permissions of a file.";
678
Barry Warsaw53699e91996-12-10 23:23:01 +0000679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000680posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000682 char *path;
683 int i;
684 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000685 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000686 return NULL;
687 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000688 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000689 Py_END_ALLOW_THREADS
690 if (res < 0)
691 return posix_error_with_filename(path);
692 Py_INCREF(Py_None);
693 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694}
695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000696
Guido van Rossum21142a01999-01-08 21:05:37 +0000697#ifdef HAVE_FSYNC
698static char posix_fsync__doc__[] =
699"fsync(fildes) -> None\n\
700force write of file with filedescriptor to disk.";
701
702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000703posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000704{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000705 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000706}
707#endif /* HAVE_FSYNC */
708
709#ifdef HAVE_FDATASYNC
710static char posix_fdatasync__doc__[] =
711"fdatasync(fildes) -> None\n\
712force write of file with filedescriptor to disk.\n\
713 does not force update of metadata.";
714
715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000716posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000717{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000718 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000719}
720#endif /* HAVE_FDATASYNC */
721
722
Fredrik Lundh10723342000-07-10 16:38:09 +0000723#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000724static char posix_chown__doc__[] =
725"chown(path, uid, gid) -> None\n\
726Change the owner and group id of path to the numeric uid and gid.";
727
Barry Warsaw53699e91996-12-10 23:23:01 +0000728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000729posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000730{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000731 char *path;
732 int uid, gid;
733 int res;
734 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
735 return NULL;
736 Py_BEGIN_ALLOW_THREADS
737 res = chown(path, (uid_t) uid, (gid_t) gid);
738 Py_END_ALLOW_THREADS
739 if (res < 0)
740 return posix_error_with_filename(path);
741 Py_INCREF(Py_None);
742 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000743}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000744#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000745
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000746
Guido van Rossum36bc6801995-06-14 22:54:23 +0000747#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000748static char posix_getcwd__doc__[] =
749"getcwd() -> path\n\
750Return a string representing the current working directory.";
751
Barry Warsaw53699e91996-12-10 23:23:01 +0000752static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000753posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000754{
755 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000756 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000757 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000758 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000759 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000760 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000761 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000762 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000763 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000764 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000766#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000767
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000768
Guido van Rossumb6775db1994-08-01 11:34:53 +0000769#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000770static char posix_link__doc__[] =
771"link(src, dst) -> None\n\
772Create a hard link to a file.";
773
Barry Warsaw53699e91996-12-10 23:23:01 +0000774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000775posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000777 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000778}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000779#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000781
782static char posix_listdir__doc__[] =
783"listdir(path) -> list_of_strings\n\
784Return a list containing the names of the entries in the directory.\n\
785\n\
786 path: path of directory to list\n\
787\n\
788The list is in arbitrary order. It does not include the special\n\
789entries '.' and '..' even if they are present in the directory.";
790
Barry Warsaw53699e91996-12-10 23:23:01 +0000791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000792posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000793{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000794 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000795 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000796#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000797
Guido van Rossumb6775db1994-08-01 11:34:53 +0000798 char *name;
799 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000800 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000801 HANDLE hFindFile;
802 WIN32_FIND_DATA FileData;
803 char namebuf[MAX_PATH+5];
804
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000805 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000806 return NULL;
807 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000808 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000809 return NULL;
810 }
811 strcpy(namebuf, name);
812 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
813 namebuf[len++] = '/';
814 strcpy(namebuf + len, "*.*");
815
Barry Warsaw53699e91996-12-10 23:23:01 +0000816 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000817 return NULL;
818
819 hFindFile = FindFirstFile(namebuf, &FileData);
820 if (hFindFile == INVALID_HANDLE_VALUE) {
821 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000822 if (errno == ERROR_FILE_NOT_FOUND)
823 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000824 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000825 }
826 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000827 if (FileData.cFileName[0] == '.' &&
828 (FileData.cFileName[1] == '\0' ||
829 FileData.cFileName[1] == '.' &&
830 FileData.cFileName[2] == '\0'))
831 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000832 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000833 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000834 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000835 d = NULL;
836 break;
837 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000838 if (PyList_Append(d, v) != 0) {
839 Py_DECREF(v);
840 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000841 d = NULL;
842 break;
843 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000844 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000845 } while (FindNextFile(hFindFile, &FileData) == TRUE);
846
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000847 if (FindClose(hFindFile) == FALSE)
848 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000849
850 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000851
Guido van Rossum8d665e61996-06-26 18:22:49 +0000852#else /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000853#ifdef _MSC_VER /* 16-bit Windows */
854
855#ifndef MAX_PATH
856#define MAX_PATH 250
857#endif
858 char *name, *pt;
859 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000860 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000861 char namebuf[MAX_PATH+5];
862 struct _find_t ep;
863
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000864 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000865 return NULL;
866 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000867 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000868 return NULL;
869 }
870 strcpy(namebuf, name);
871 for (pt = namebuf; *pt; pt++)
872 if (*pt == '/')
873 *pt = '\\';
874 if (namebuf[len-1] != '\\')
875 namebuf[len++] = '\\';
876 strcpy(namebuf + len, "*.*");
877
Barry Warsaw53699e91996-12-10 23:23:01 +0000878 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000879 return NULL;
880
881 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000882 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
883 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000884 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000885 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000886 }
887 do {
888 if (ep.name[0] == '.' &&
889 (ep.name[1] == '\0' ||
890 ep.name[1] == '.' &&
891 ep.name[2] == '\0'))
892 continue;
893 strcpy(namebuf, ep.name);
894 for (pt = namebuf; *pt; pt++)
895 if (isupper(*pt))
896 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000897 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000898 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000899 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000900 d = NULL;
901 break;
902 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000903 if (PyList_Append(d, v) != 0) {
904 Py_DECREF(v);
905 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000906 d = NULL;
907 break;
908 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000909 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000910 } while (_dos_findnext(&ep) == 0);
911
912 return d;
913
914#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000915#if defined(PYOS_OS2)
916
917#ifndef MAX_PATH
918#define MAX_PATH CCHMAXPATH
919#endif
920 char *name, *pt;
921 int len;
922 PyObject *d, *v;
923 char namebuf[MAX_PATH+5];
924 HDIR hdir = 1;
925 ULONG srchcnt = 1;
926 FILEFINDBUF3 ep;
927 APIRET rc;
928
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000929 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000930 return NULL;
931 if (len >= MAX_PATH) {
932 PyErr_SetString(PyExc_ValueError, "path too long");
933 return NULL;
934 }
935 strcpy(namebuf, name);
936 for (pt = namebuf; *pt; pt++)
937 if (*pt == '/')
938 *pt = '\\';
939 if (namebuf[len-1] != '\\')
940 namebuf[len++] = '\\';
941 strcpy(namebuf + len, "*.*");
942
943 if ((d = PyList_New(0)) == NULL)
944 return NULL;
945
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000946 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
947 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000948 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000949 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
950 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
951 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000952
953 if (rc != NO_ERROR) {
954 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000955 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000956 }
957
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000958 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000959 do {
960 if (ep.achName[0] == '.'
961 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000962 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963
964 strcpy(namebuf, ep.achName);
965
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000966 /* Leave Case of Name Alone -- In Native Form */
967 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000968
969 v = PyString_FromString(namebuf);
970 if (v == NULL) {
971 Py_DECREF(d);
972 d = NULL;
973 break;
974 }
975 if (PyList_Append(d, v) != 0) {
976 Py_DECREF(v);
977 Py_DECREF(d);
978 d = NULL;
979 break;
980 }
981 Py_DECREF(v);
982 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
983 }
984
985 return d;
986#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000987
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000988 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +0000989 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000990 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000991 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000992 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000993 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000994 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000995 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000996 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000997 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000998 closedir(dirp);
999 return NULL;
1000 }
1001 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001002 if (ep->d_name[0] == '.' &&
1003 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001004 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001005 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001006 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001007 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001008 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001009 d = NULL;
1010 break;
1011 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001012 if (PyList_Append(d, v) != 0) {
1013 Py_DECREF(v);
1014 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001015 d = NULL;
1016 break;
1017 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001018 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001019 }
1020 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001021
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001022 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001023
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001024#endif /* !PYOS_OS2 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001025#endif /* !_MSC_VER */
Guido van Rossum8d665e61996-06-26 18:22:49 +00001026#endif /* !MS_WIN32 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001027}
1028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001029static char posix_mkdir__doc__[] =
1030"mkdir(path [, mode=0777]) -> None\n\
1031Create a directory.";
1032
Barry Warsaw53699e91996-12-10 23:23:01 +00001033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001034posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001035{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001036 int res;
1037 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001038 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001039 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001040 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001041 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001042#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001043 res = mkdir(path);
1044#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001045 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001046#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001047 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001048 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001049 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001050 Py_INCREF(Py_None);
1051 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001052}
1053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001054
Guido van Rossumb6775db1994-08-01 11:34:53 +00001055#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001056static char posix_nice__doc__[] =
1057"nice(inc) -> new_priority\n\
1058Decrease the priority of process and return new priority.";
1059
Barry Warsaw53699e91996-12-10 23:23:01 +00001060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001061posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001062{
1063 int increment, value;
1064
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001065 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001066 return NULL;
1067 value = nice(increment);
1068 if (value == -1)
1069 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001070 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001071}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001072#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001074
1075static char posix_rename__doc__[] =
1076"rename(old, new) -> None\n\
1077Rename a file or directory.";
1078
Barry Warsaw53699e91996-12-10 23:23:01 +00001079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001080posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001081{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001082 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001083}
1084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001085
1086static char posix_rmdir__doc__[] =
1087"rmdir(path) -> None\n\
1088Remove a directory.";
1089
Barry Warsaw53699e91996-12-10 23:23:01 +00001090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001091posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001092{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001093 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001094}
1095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001096
1097static char posix_stat__doc__[] =
1098"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1099Perform a stat system call on the given path.";
1100
Barry Warsaw53699e91996-12-10 23:23:01 +00001101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001102posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001103{
Fred Drake699f3522000-06-29 21:12:41 +00001104 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001105}
1106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001107
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001108#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001109static char posix_system__doc__[] =
1110"system(command) -> exit_status\n\
1111Execute the command (a string) in a subshell.";
1112
Barry Warsaw53699e91996-12-10 23:23:01 +00001113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001114posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001115{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001116 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001117 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001118 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001119 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001120 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001121 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001122 Py_END_ALLOW_THREADS
1123 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001125#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001127
1128static char posix_umask__doc__[] =
1129"umask(new_mask) -> old_mask\n\
1130Set the current numeric umask and return the previous umask.";
1131
Barry Warsaw53699e91996-12-10 23:23:01 +00001132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001133posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001134{
1135 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001136 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137 return NULL;
1138 i = umask(i);
1139 if (i < 0)
1140 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001141 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142}
1143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001144
1145static char posix_unlink__doc__[] =
1146"unlink(path) -> None\n\
1147Remove a file (same as remove(path)).";
1148
1149static char posix_remove__doc__[] =
1150"remove(path) -> None\n\
1151Remove a file (same as unlink(path)).";
1152
Barry Warsaw53699e91996-12-10 23:23:01 +00001153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001154posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001155{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001156 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001157}
1158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001159
Guido van Rossumb6775db1994-08-01 11:34:53 +00001160#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001161static char posix_uname__doc__[] =
1162"uname() -> (sysname, nodename, release, version, machine)\n\
1163Return a tuple identifying the current operating system.";
1164
Barry Warsaw53699e91996-12-10 23:23:01 +00001165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001166posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001167{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001168 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001169 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001170 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001171 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001172 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001173 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001174 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001175 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001176 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001177 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001178 u.sysname,
1179 u.nodename,
1180 u.release,
1181 u.version,
1182 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001183}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001184#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001185
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001186
1187static char posix_utime__doc__[] =
1188"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001189utime(path, None) -> None\n\
1190Set the access and modified time of the file to the given values. If the\n\
1191second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001192
Barry Warsaw53699e91996-12-10 23:23:01 +00001193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001194posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001196 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001197 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001198 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001199 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001200
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001201/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001202#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001203 struct utimbuf buf;
1204#define ATIME buf.actime
1205#define MTIME buf.modtime
1206#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001207#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001208 time_t buf[2];
1209#define ATIME buf[0]
1210#define MTIME buf[1]
1211#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001212#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001213
Barry Warsaw3cef8562000-05-01 16:17:24 +00001214 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001215 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001216 if (arg == Py_None) {
1217 /* optional time values not given */
1218 Py_BEGIN_ALLOW_THREADS
1219 res = utime(path, NULL);
1220 Py_END_ALLOW_THREADS
1221 }
1222 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1223 PyErr_SetString(PyExc_TypeError,
1224 "Second argument must be a 2-tuple of numbers.");
1225 return NULL;
1226 }
1227 else {
1228 ATIME = atime;
1229 MTIME = mtime;
1230 Py_BEGIN_ALLOW_THREADS
1231 res = utime(path, UTIME_ARG);
1232 Py_END_ALLOW_THREADS
1233 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001234 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001235 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001236 Py_INCREF(Py_None);
1237 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001238#undef UTIME_ARG
1239#undef ATIME
1240#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001241}
1242
Guido van Rossum85e3b011991-06-03 12:42:10 +00001243
Guido van Rossum3b066191991-06-04 19:40:25 +00001244/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001246static char posix__exit__doc__[] =
1247"_exit(status)\n\
1248Exit to the system with specified status, without normal exit processing.";
1249
Barry Warsaw53699e91996-12-10 23:23:01 +00001250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001251posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001252{
1253 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001254 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001255 return NULL;
1256 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001257 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001258}
1259
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001260
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001261#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001262static char posix_execv__doc__[] =
1263"execv(path, args)\n\
1264Execute an executable path with arguments, replacing current process.\n\
1265\n\
1266 path: path of executable file\n\
1267 args: tuple or list of strings";
1268
Barry Warsaw53699e91996-12-10 23:23:01 +00001269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001270posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001271{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001272 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001273 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001274 char **argvlist;
1275 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001276 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001277
Guido van Rossum89b33251993-10-22 14:26:06 +00001278 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001279 argv is a list or tuple of strings. */
1280
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001281 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001282 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001283 if (PyList_Check(argv)) {
1284 argc = PyList_Size(argv);
1285 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001286 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001287 else if (PyTuple_Check(argv)) {
1288 argc = PyTuple_Size(argv);
1289 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001290 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001291 else {
Guido van Rossum50422b42000-04-26 20:34:28 +00001292 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1293 return NULL;
1294 }
1295
1296 if (argc == 0) {
1297 PyErr_SetString(PyExc_ValueError, "empty argument list");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001298 return NULL;
1299 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001300
Barry Warsaw53699e91996-12-10 23:23:01 +00001301 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001302 if (argvlist == NULL)
1303 return NULL;
1304 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001305 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1306 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001307 PyErr_SetString(PyExc_TypeError,
1308 "all arguments must be strings");
1309 return NULL;
1310
Guido van Rossum85e3b011991-06-03 12:42:10 +00001311 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001312 }
1313 argvlist[argc] = NULL;
1314
Guido van Rossumb6775db1994-08-01 11:34:53 +00001315#ifdef BAD_EXEC_PROTOTYPES
1316 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001317#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001318 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001319#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001320
Guido van Rossum85e3b011991-06-03 12:42:10 +00001321 /* If we get here it's definitely an error */
1322
Barry Warsaw53699e91996-12-10 23:23:01 +00001323 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001324 return posix_error();
1325}
1326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001327
1328static char posix_execve__doc__[] =
1329"execve(path, args, env)\n\
1330Execute a path with arguments and environment, replacing current process.\n\
1331\n\
1332 path: path of executable file\n\
1333 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001334 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335
Barry Warsaw53699e91996-12-10 23:23:01 +00001336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001337posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001338{
1339 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001340 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001341 char **argvlist;
1342 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001343 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001344 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001345 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001346
1347 /* execve has three arguments: (path, argv, env), where
1348 argv is a list or tuple of strings and env is a dictionary
1349 like posix.environ. */
1350
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001351 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001352 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001353 if (PyList_Check(argv)) {
1354 argc = PyList_Size(argv);
1355 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001356 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001357 else if (PyTuple_Check(argv)) {
1358 argc = PyTuple_Size(argv);
1359 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001360 }
1361 else {
Barry Warsaw53699e91996-12-10 23:23:01 +00001362 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001363 return NULL;
1364 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001365 if (!PyMapping_Check(env)) {
1366 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001367 return NULL;
1368 }
1369
Guido van Rossum50422b42000-04-26 20:34:28 +00001370 if (argc == 0) {
1371 PyErr_SetString(PyExc_ValueError,
1372 "empty argument list");
1373 return NULL;
1374 }
1375
Barry Warsaw53699e91996-12-10 23:23:01 +00001376 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001377 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001378 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001379 return NULL;
1380 }
1381 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001382 if (!PyArg_Parse((*getitem)(argv, i),
Barry Warsaw43d68b81996-12-19 22:10:44 +00001383 "s;argv must be list of strings",
1384 &argvlist[i]))
1385 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001386 goto fail_1;
1387 }
1388 }
1389 argvlist[argc] = NULL;
1390
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001391 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001392 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001393 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001394 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001395 goto fail_1;
1396 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001397 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001398 keys = PyMapping_Keys(env);
1399 vals = PyMapping_Values(env);
1400 if (!keys || !vals)
1401 goto fail_2;
1402
1403 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001404 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001405
1406 key = PyList_GetItem(keys, pos);
1407 val = PyList_GetItem(vals, pos);
1408 if (!key || !val)
1409 goto fail_2;
1410
Barry Warsaw53699e91996-12-10 23:23:01 +00001411 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
Barry Warsaw43d68b81996-12-19 22:10:44 +00001412 !PyArg_Parse(val, "s;non-string value in env", &v))
1413 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001414 goto fail_2;
1415 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001416
1417#if defined(PYOS_OS2)
1418 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1419 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1420#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001421 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001422 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001423 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001424 goto fail_2;
1425 }
1426 sprintf(p, "%s=%s", k, v);
1427 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001428#if defined(PYOS_OS2)
1429 }
1430#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001431 }
1432 envlist[envc] = 0;
1433
Guido van Rossumb6775db1994-08-01 11:34:53 +00001434
1435#ifdef BAD_EXEC_PROTOTYPES
1436 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001437#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001438 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001439#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001440
1441 /* If we get here it's definitely an error */
1442
1443 (void) posix_error();
1444
1445 fail_2:
1446 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001447 PyMem_DEL(envlist[envc]);
1448 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001449 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001450 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001451 Py_XDECREF(vals);
1452 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001453 return NULL;
1454}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001455#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001456
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001457
Guido van Rossuma1065681999-01-25 23:20:23 +00001458#ifdef HAVE_SPAWNV
1459static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001460"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001461Execute an executable path with arguments, replacing current process.\n\
1462\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001463 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001464 path: path of executable file\n\
1465 args: tuple or list of strings";
1466
1467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001468posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001469{
1470 char *path;
1471 PyObject *argv;
1472 char **argvlist;
1473 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001474 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001475 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001476
1477 /* spawnv has three arguments: (mode, path, argv), where
1478 argv is a list or tuple of strings. */
1479
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001480 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001481 return NULL;
1482 if (PyList_Check(argv)) {
1483 argc = PyList_Size(argv);
1484 getitem = PyList_GetItem;
1485 }
1486 else if (PyTuple_Check(argv)) {
1487 argc = PyTuple_Size(argv);
1488 getitem = PyTuple_GetItem;
1489 }
1490 else {
Fred Drake137507e2000-06-01 02:02:46 +00001491 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001492 return NULL;
1493 }
1494
1495 argvlist = PyMem_NEW(char *, argc+1);
1496 if (argvlist == NULL)
1497 return NULL;
1498 for (i = 0; i < argc; i++) {
1499 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1500 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001501 PyErr_SetString(PyExc_TypeError,
1502 "all arguments must be strings");
1503 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001504 }
1505 }
1506 argvlist[argc] = NULL;
1507
Guido van Rossum246bc171999-02-01 23:54:31 +00001508 if (mode == _OLD_P_OVERLAY)
1509 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001510 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001511
1512 PyMem_DEL(argvlist);
1513
Fred Drake699f3522000-06-29 21:12:41 +00001514 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001515 return posix_error();
1516 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001517#if SIZEOF_LONG == SIZEOF_VOID_P
1518 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001519#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001520 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001521#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001522}
1523
1524
1525static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001526"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001527Execute a path with arguments and environment, replacing current process.\n\
1528\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001529 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001530 path: path of executable file\n\
1531 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001532 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001533
1534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001535posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001536{
1537 char *path;
1538 PyObject *argv, *env;
1539 char **argvlist;
1540 char **envlist;
1541 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1542 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001543 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001544 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001545
1546 /* spawnve has four arguments: (mode, path, argv, env), where
1547 argv is a list or tuple of strings and env is a dictionary
1548 like posix.environ. */
1549
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001550 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001551 return NULL;
1552 if (PyList_Check(argv)) {
1553 argc = PyList_Size(argv);
1554 getitem = PyList_GetItem;
1555 }
1556 else if (PyTuple_Check(argv)) {
1557 argc = PyTuple_Size(argv);
1558 getitem = PyTuple_GetItem;
1559 }
1560 else {
1561 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1562 return NULL;
1563 }
1564 if (!PyMapping_Check(env)) {
1565 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1566 return NULL;
1567 }
1568
1569 argvlist = PyMem_NEW(char *, argc+1);
1570 if (argvlist == NULL) {
1571 PyErr_NoMemory();
1572 return NULL;
1573 }
1574 for (i = 0; i < argc; i++) {
1575 if (!PyArg_Parse((*getitem)(argv, i),
1576 "s;argv must be list of strings",
1577 &argvlist[i]))
1578 {
1579 goto fail_1;
1580 }
1581 }
1582 argvlist[argc] = NULL;
1583
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001584 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001585 envlist = PyMem_NEW(char *, i + 1);
1586 if (envlist == NULL) {
1587 PyErr_NoMemory();
1588 goto fail_1;
1589 }
1590 envc = 0;
1591 keys = PyMapping_Keys(env);
1592 vals = PyMapping_Values(env);
1593 if (!keys || !vals)
1594 goto fail_2;
1595
1596 for (pos = 0; pos < i; pos++) {
1597 char *p, *k, *v;
1598
1599 key = PyList_GetItem(keys, pos);
1600 val = PyList_GetItem(vals, pos);
1601 if (!key || !val)
1602 goto fail_2;
1603
1604 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1605 !PyArg_Parse(val, "s;non-string value in env", &v))
1606 {
1607 goto fail_2;
1608 }
1609 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1610 if (p == NULL) {
1611 PyErr_NoMemory();
1612 goto fail_2;
1613 }
1614 sprintf(p, "%s=%s", k, v);
1615 envlist[envc++] = p;
1616 }
1617 envlist[envc] = 0;
1618
Guido van Rossum246bc171999-02-01 23:54:31 +00001619 if (mode == _OLD_P_OVERLAY)
1620 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001621 spawnval = _spawnve(mode, path, argvlist, envlist);
1622 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001623 (void) posix_error();
1624 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001625#if SIZEOF_LONG == SIZEOF_VOID_P
1626 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001627#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001628 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001629#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001630
1631 fail_2:
1632 while (--envc >= 0)
1633 PyMem_DEL(envlist[envc]);
1634 PyMem_DEL(envlist);
1635 fail_1:
1636 PyMem_DEL(argvlist);
1637 Py_XDECREF(vals);
1638 Py_XDECREF(keys);
1639 return res;
1640}
1641#endif /* HAVE_SPAWNV */
1642
1643
Guido van Rossumad0ee831995-03-01 10:34:45 +00001644#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001645static char posix_fork__doc__[] =
1646"fork() -> pid\n\
1647Fork a child process.\n\
1648\n\
1649Return 0 to child process and PID of child to parent process.";
1650
Barry Warsaw53699e91996-12-10 23:23:01 +00001651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001652posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001653{
1654 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001655 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001656 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001657 pid = fork();
1658 if (pid == -1)
1659 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001660 if (pid == 0)
1661 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001662 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001663}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001664#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001665
Fred Drake8cef4cf2000-06-28 16:40:38 +00001666#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1667#ifdef HAVE_PTY_H
1668#include <pty.h>
1669#else
1670#ifdef HAVE_LIBUTIL_H
1671#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001672#endif /* HAVE_LIBUTIL_H */
1673#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001674#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001675
Thomas Wouters70c21a12000-07-14 14:28:33 +00001676#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001677static char posix_openpty__doc__[] =
1678"openpty() -> (master_fd, slave_fd)\n\
1679Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1680
1681static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001682posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001683{
1684 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001685#ifndef HAVE_OPENPTY
1686 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001687#endif
1688
Fred Drake8cef4cf2000-06-28 16:40:38 +00001689 if (!PyArg_ParseTuple(args, ":openpty"))
1690 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001691
1692#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001693 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1694 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001695#else
1696 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1697 if (slave_name == NULL)
1698 return posix_error();
1699
1700 slave_fd = open(slave_name, O_RDWR);
1701 if (slave_fd < 0)
1702 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001703#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001704
Fred Drake8cef4cf2000-06-28 16:40:38 +00001705 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001706
Fred Drake8cef4cf2000-06-28 16:40:38 +00001707}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001708#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001709
1710#ifdef HAVE_FORKPTY
1711static char posix_forkpty__doc__[] =
1712"forkpty() -> (pid, master_fd)\n\
1713Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1714Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1715To both, return fd of newly opened pseudo-terminal.\n";
1716
1717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001718posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001719{
1720 int master_fd, pid;
1721
1722 if (!PyArg_ParseTuple(args, ":forkpty"))
1723 return NULL;
1724 pid = forkpty(&master_fd, NULL, NULL, NULL);
1725 if (pid == -1)
1726 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001727 if (pid == 0)
1728 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001729 return Py_BuildValue("(ii)", pid, master_fd);
1730}
1731#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001732
Guido van Rossumad0ee831995-03-01 10:34:45 +00001733#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001734static char posix_getegid__doc__[] =
1735"getegid() -> egid\n\
1736Return the current process's effective group id.";
1737
Barry Warsaw53699e91996-12-10 23:23:01 +00001738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001739posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001740{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001741 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001742 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001743 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001744}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001745#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001746
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001747
Guido van Rossumad0ee831995-03-01 10:34:45 +00001748#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001749static char posix_geteuid__doc__[] =
1750"geteuid() -> euid\n\
1751Return the current process's effective user id.";
1752
Barry Warsaw53699e91996-12-10 23:23:01 +00001753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001754posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001755{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001756 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001757 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001758 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001759}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001760#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001761
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001762
Guido van Rossumad0ee831995-03-01 10:34:45 +00001763#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001764static char posix_getgid__doc__[] =
1765"getgid() -> gid\n\
1766Return the current process's group id.";
1767
Barry Warsaw53699e91996-12-10 23:23:01 +00001768static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001769posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001770{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001771 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001772 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001773 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001774}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001775#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001776
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001777
1778static char posix_getpid__doc__[] =
1779"getpid() -> pid\n\
1780Return the current process id";
1781
Barry Warsaw53699e91996-12-10 23:23:01 +00001782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001783posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001784{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001785 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001786 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001787 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001788}
1789
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001790
Fred Drakec9680921999-12-13 16:37:25 +00001791#ifdef HAVE_GETGROUPS
1792static char posix_getgroups__doc__[] = "\
1793getgroups() -> list of group IDs\n\
1794Return list of supplemental group IDs for the process.";
1795
1796static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001797posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001798{
1799 PyObject *result = NULL;
1800
1801 if (PyArg_ParseTuple(args, ":getgroups")) {
1802#ifdef NGROUPS_MAX
1803#define MAX_GROUPS NGROUPS_MAX
1804#else
1805 /* defined to be 16 on Solaris7, so this should be a small number */
1806#define MAX_GROUPS 64
1807#endif
1808 gid_t grouplist[MAX_GROUPS];
1809 int n;
1810
1811 n = getgroups(MAX_GROUPS, grouplist);
1812 if (n < 0)
1813 posix_error();
1814 else {
1815 result = PyList_New(n);
1816 if (result != NULL) {
1817 PyObject *o;
1818 int i;
1819 for (i = 0; i < n; ++i) {
1820 o = PyInt_FromLong((long)grouplist[i]);
1821 if (o == NULL) {
1822 Py_DECREF(result);
1823 result = NULL;
1824 break;
1825 }
1826 PyList_SET_ITEM(result, i, o);
1827 }
1828 }
1829 }
1830 }
1831 return result;
1832}
1833#endif
1834
Guido van Rossumb6775db1994-08-01 11:34:53 +00001835#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001836static char posix_getpgrp__doc__[] =
1837"getpgrp() -> pgrp\n\
1838Return the current process group id.";
1839
Barry Warsaw53699e91996-12-10 23:23:01 +00001840static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001841posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001842{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001843 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001844 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001845#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001846 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001847#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001848 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001849#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001850}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001851#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001853
Guido van Rossumb6775db1994-08-01 11:34:53 +00001854#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001855static char posix_setpgrp__doc__[] =
1856"setpgrp() -> None\n\
1857Make this process a session leader.";
1858
Barry Warsaw53699e91996-12-10 23:23:01 +00001859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001860posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001861{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001862 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001863 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001864#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001865 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001866#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001867 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001868#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001869 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001870 Py_INCREF(Py_None);
1871 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001872}
1873
Guido van Rossumb6775db1994-08-01 11:34:53 +00001874#endif /* HAVE_SETPGRP */
1875
Guido van Rossumad0ee831995-03-01 10:34:45 +00001876#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001877static char posix_getppid__doc__[] =
1878"getppid() -> ppid\n\
1879Return the parent's process id.";
1880
Barry Warsaw53699e91996-12-10 23:23:01 +00001881static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001882posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001883{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001884 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001885 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001886 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001887}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001888#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001889
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001890
Fred Drake12c6e2d1999-12-14 21:25:03 +00001891#ifdef HAVE_GETLOGIN
1892static char posix_getlogin__doc__[] = "\
1893getlogin() -> string\n\
1894Return the actual login name.";
1895
1896static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001897posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001898{
1899 PyObject *result = NULL;
1900
1901 if (PyArg_ParseTuple(args, ":getlogin")) {
1902 char *name = getlogin();
1903
1904 if (name == NULL)
1905 posix_error();
1906 else
1907 result = PyString_FromString(name);
1908 }
1909 return result;
1910}
1911#endif
1912
Guido van Rossumad0ee831995-03-01 10:34:45 +00001913#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001914static char posix_getuid__doc__[] =
1915"getuid() -> uid\n\
1916Return the current process's user id.";
1917
Barry Warsaw53699e91996-12-10 23:23:01 +00001918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001919posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001920{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001921 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001922 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001923 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001924}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001925#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001926
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001927
Guido van Rossumad0ee831995-03-01 10:34:45 +00001928#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001929static char posix_kill__doc__[] =
1930"kill(pid, sig) -> None\n\
1931Kill a process with a signal.";
1932
Barry Warsaw53699e91996-12-10 23:23:01 +00001933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001934posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001935{
1936 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001937 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001938 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001939#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001940 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1941 APIRET rc;
1942 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001943 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001944
1945 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1946 APIRET rc;
1947 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001948 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001949
1950 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001951 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001952#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001953 if (kill(pid, sig) == -1)
1954 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001955#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001956 Py_INCREF(Py_None);
1957 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001958}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001959#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001960
Guido van Rossumc0125471996-06-28 18:55:32 +00001961#ifdef HAVE_PLOCK
1962
1963#ifdef HAVE_SYS_LOCK_H
1964#include <sys/lock.h>
1965#endif
1966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001967static char posix_plock__doc__[] =
1968"plock(op) -> None\n\
1969Lock program segments into memory.";
1970
Barry Warsaw53699e91996-12-10 23:23:01 +00001971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001972posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001973{
1974 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001975 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001976 return NULL;
1977 if (plock(op) == -1)
1978 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001979 Py_INCREF(Py_None);
1980 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00001981}
1982#endif
1983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001984
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001985#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001986static char posix_popen__doc__[] =
1987"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
1988Open a pipe to/from a command returning a file object.";
1989
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001990#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001991static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001992async_system(const char *command)
1993{
1994 char *p, errormsg[256], args[1024];
1995 RESULTCODES rcodes;
1996 APIRET rc;
1997 char *shell = getenv("COMSPEC");
1998 if (!shell)
1999 shell = "cmd";
2000
2001 strcpy(args, shell);
2002 p = &args[ strlen(args)+1 ];
2003 strcpy(p, "/c ");
2004 strcat(p, command);
2005 p += strlen(p) + 1;
2006 *p = '\0';
2007
2008 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002009 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002010 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002011 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002012 &rcodes, shell);
2013 return rc;
2014}
2015
Guido van Rossumd48f2521997-12-05 22:19:34 +00002016static FILE *
2017popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002018{
2019 HFILE rhan, whan;
2020 FILE *retfd = NULL;
2021 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2022
Guido van Rossumd48f2521997-12-05 22:19:34 +00002023 if (rc != NO_ERROR) {
2024 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002025 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002026 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002027
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002028 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2029 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002030
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002031 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2032 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002033
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002034 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2035 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002036
2037 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002038 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002039 }
2040
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002041 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2042 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002043
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002044 close(oldfd); /* And Close Saved STDOUT Handle */
2045 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002046
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002047 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2048 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002049
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002050 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2051 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002052
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002053 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2054 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002055
2056 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002057 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002058 }
2059
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002060 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2061 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002062
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002063 close(oldfd); /* And Close Saved STDIN Handle */
2064 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002065
Guido van Rossumd48f2521997-12-05 22:19:34 +00002066 } else {
2067 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002068 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002069 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002070}
2071
2072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002073posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074{
2075 char *name;
2076 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002077 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002078 FILE *fp;
2079 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002080 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002081 return NULL;
2082 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002083 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002084 Py_END_ALLOW_THREADS
2085 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002086 return os2_error(err);
2087
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002088 f = PyFile_FromFile(fp, name, mode, fclose);
2089 if (f != NULL)
2090 PyFile_SetBufSize(f, bufsize);
2091 return f;
2092}
2093
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002094#elif defined(MS_WIN32)
2095
2096/*
2097 * Portable 'popen' replacement for Win32.
2098 *
2099 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2100 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002101 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002102 */
2103
2104#include <malloc.h>
2105#include <io.h>
2106#include <fcntl.h>
2107
2108/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2109#define POPEN_1 1
2110#define POPEN_2 2
2111#define POPEN_3 3
2112#define POPEN_4 4
2113
2114static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002115static int _PyPclose(FILE *file);
2116
2117/*
2118 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002119 * for use when retrieving the process exit code. See _PyPclose() below
2120 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002121 */
2122static PyObject *_PyPopenProcs = NULL;
2123
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002124
2125/* popen that works from a GUI.
2126 *
2127 * The result of this function is a pipe (file) connected to the
2128 * processes stdin or stdout, depending on the requested mode.
2129 */
2130
2131static PyObject *
2132posix_popen(PyObject *self, PyObject *args)
2133{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002134 PyObject *f, *s;
2135 int tm = 0;
2136
2137 char *cmdstring;
2138 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002139 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002140 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002141 return NULL;
2142
2143 s = PyTuple_New(0);
2144
2145 if (*mode == 'r')
2146 tm = _O_RDONLY;
2147 else if (*mode != 'w') {
2148 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'");
2149 return NULL;
2150 } else
2151 tm = _O_WRONLY;
2152
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002153 if (bufsize != -1) {
2154 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2155 return NULL;
2156 }
2157
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002158 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002159 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002160 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002161 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002162 else
2163 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2164
2165 return f;
2166}
2167
2168/* Variation on win32pipe.popen
2169 *
2170 * The result of this function is a pipe (file) connected to the
2171 * process's stdin, and a pipe connected to the process's stdout.
2172 */
2173
2174static PyObject *
2175win32_popen2(PyObject *self, PyObject *args)
2176{
2177 PyObject *f;
2178 int tm=0;
2179
2180 char *cmdstring;
2181 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002182 int bufsize = -1;
2183 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002184 return NULL;
2185
2186 if (*mode == 't')
2187 tm = _O_TEXT;
2188 else if (*mode != 'b') {
2189 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2190 return NULL;
2191 } else
2192 tm = _O_BINARY;
2193
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002194 if (bufsize != -1) {
2195 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2196 return NULL;
2197 }
2198
2199 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002200
2201 return f;
2202}
2203
2204/*
2205 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002206 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002207 * The result of this function is 3 pipes - the process's stdin,
2208 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002209 */
2210
2211static PyObject *
2212win32_popen3(PyObject *self, PyObject *args)
2213{
2214 PyObject *f;
2215 int tm = 0;
2216
2217 char *cmdstring;
2218 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002219 int bufsize = -1;
2220 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002221 return NULL;
2222
2223 if (*mode == 't')
2224 tm = _O_TEXT;
2225 else if (*mode != 'b') {
2226 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2227 return NULL;
2228 } else
2229 tm = _O_BINARY;
2230
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002231 if (bufsize != -1) {
2232 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2233 return NULL;
2234 }
2235
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002236 f = _PyPopen(cmdstring, tm, POPEN_3);
2237
2238 return f;
2239}
2240
2241/*
2242 * Variation on win32pipe.popen
2243 *
2244 * The result of this function is 2 pipes - the processes stdin,
2245 * and stdout+stderr combined as a single pipe.
2246 */
2247
2248static PyObject *
2249win32_popen4(PyObject *self, PyObject *args)
2250{
2251 PyObject *f;
2252 int tm = 0;
2253
2254 char *cmdstring;
2255 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002256 int bufsize = -1;
2257 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002258 return NULL;
2259
2260 if (*mode == 't')
2261 tm = _O_TEXT;
2262 else if (*mode != 'b') {
2263 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2264 return NULL;
2265 } else
2266 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002267
2268 if (bufsize != -1) {
2269 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2270 return NULL;
2271 }
2272
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002273 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002274
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002275 return f;
2276}
2277
2278static int
Mark Hammondb37a3732000-08-14 04:47:33 +00002279_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002280 HANDLE hStdin,
2281 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002282 HANDLE hStderr,
2283 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002284{
2285 PROCESS_INFORMATION piProcInfo;
2286 STARTUPINFO siStartInfo;
2287 char *s1,*s2, *s3 = " /c ";
2288 const char *szConsoleSpawn = "w9xpopen.exe \"";
2289 int i;
2290 int x;
2291
2292 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2293 s1 = (char *)_alloca(i);
2294 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2295 return x;
2296 if (GetVersion() < 0x80000000) {
2297 /*
2298 * NT/2000
2299 */
2300 x = i + strlen(s3) + strlen(cmdstring) + 1;
2301 s2 = (char *)_alloca(x);
2302 ZeroMemory(s2, x);
2303 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2304 }
2305 else {
2306 /*
2307 * Oh gag, we're on Win9x. Use the workaround listed in
2308 * KB: Q150956
2309 */
2310 char modulepath[256];
2311 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2312 for (i = x = 0; modulepath[i]; i++)
2313 if (modulepath[i] == '\\')
2314 x = i+1;
2315 modulepath[x] = '\0';
2316 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2317 strlen(modulepath) +
2318 strlen(szConsoleSpawn) + 1;
2319 s2 = (char *)_alloca(x);
2320 ZeroMemory(s2, x);
2321 sprintf(
2322 s2,
2323 "%s%s%s%s%s\"",
2324 modulepath,
2325 szConsoleSpawn,
2326 s1,
2327 s3,
2328 cmdstring);
2329 }
2330 }
2331
2332 /* Could be an else here to try cmd.exe / command.com in the path
2333 Now we'll just error out.. */
2334 else
2335 return -1;
2336
2337 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2338 siStartInfo.cb = sizeof(STARTUPINFO);
2339 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2340 siStartInfo.hStdInput = hStdin;
2341 siStartInfo.hStdOutput = hStdout;
2342 siStartInfo.hStdError = hStderr;
2343 siStartInfo.wShowWindow = SW_HIDE;
2344
2345 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002346 s2,
2347 NULL,
2348 NULL,
2349 TRUE,
2350 CREATE_NEW_CONSOLE,
2351 NULL,
2352 NULL,
2353 &siStartInfo,
2354 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002355 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002356 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002357
Mark Hammondb37a3732000-08-14 04:47:33 +00002358 /* Return process handle */
2359 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002360 return TRUE;
2361 }
2362 return FALSE;
2363}
2364
2365/* The following code is based off of KB: Q190351 */
2366
2367static PyObject *
2368_PyPopen(char *cmdstring, int mode, int n)
2369{
2370 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2371 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002372 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002373
2374 SECURITY_ATTRIBUTES saAttr;
2375 BOOL fSuccess;
2376 int fd1, fd2, fd3;
2377 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002378 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002379 PyObject *f;
2380
2381 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2382 saAttr.bInheritHandle = TRUE;
2383 saAttr.lpSecurityDescriptor = NULL;
2384
2385 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2386 return win32_error("CreatePipe", NULL);
2387
2388 /* Create new output read handle and the input write handle. Set
2389 * the inheritance properties to FALSE. Otherwise, the child inherits
2390 * the these handles; resulting in non-closeable handles to the pipes
2391 * being created. */
2392 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002393 GetCurrentProcess(), &hChildStdinWrDup, 0,
2394 FALSE,
2395 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002396 if (!fSuccess)
2397 return win32_error("DuplicateHandle", NULL);
2398
2399 /* Close the inheritable version of ChildStdin
2400 that we're using. */
2401 CloseHandle(hChildStdinWr);
2402
2403 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2404 return win32_error("CreatePipe", NULL);
2405
2406 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002407 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2408 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002409 if (!fSuccess)
2410 return win32_error("DuplicateHandle", NULL);
2411
2412 /* Close the inheritable version of ChildStdout
2413 that we're using. */
2414 CloseHandle(hChildStdoutRd);
2415
2416 if (n != POPEN_4) {
2417 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2418 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002419 fSuccess = DuplicateHandle(GetCurrentProcess(),
2420 hChildStderrRd,
2421 GetCurrentProcess(),
2422 &hChildStderrRdDup, 0,
2423 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002424 if (!fSuccess)
2425 return win32_error("DuplicateHandle", NULL);
2426 /* Close the inheritable version of ChildStdErr that we're using. */
2427 CloseHandle(hChildStderrRd);
2428 }
2429
2430 switch (n) {
2431 case POPEN_1:
2432 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2433 case _O_WRONLY | _O_TEXT:
2434 /* Case for writing to child Stdin in text mode. */
2435 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2436 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002437 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002438 PyFile_SetBufSize(f, 0);
2439 /* We don't care about these pipes anymore, so close them. */
2440 CloseHandle(hChildStdoutRdDup);
2441 CloseHandle(hChildStderrRdDup);
2442 break;
2443
2444 case _O_RDONLY | _O_TEXT:
2445 /* Case for reading from child Stdout in text mode. */
2446 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2447 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002448 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002449 PyFile_SetBufSize(f, 0);
2450 /* We don't care about these pipes anymore, so close them. */
2451 CloseHandle(hChildStdinWrDup);
2452 CloseHandle(hChildStderrRdDup);
2453 break;
2454
2455 case _O_RDONLY | _O_BINARY:
2456 /* Case for readinig from child Stdout in binary mode. */
2457 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2458 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002459 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002460 PyFile_SetBufSize(f, 0);
2461 /* We don't care about these pipes anymore, so close them. */
2462 CloseHandle(hChildStdinWrDup);
2463 CloseHandle(hChildStderrRdDup);
2464 break;
2465
2466 case _O_WRONLY | _O_BINARY:
2467 /* Case for writing to child Stdin in binary mode. */
2468 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2469 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002470 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002471 PyFile_SetBufSize(f, 0);
2472 /* We don't care about these pipes anymore, so close them. */
2473 CloseHandle(hChildStdoutRdDup);
2474 CloseHandle(hChildStderrRdDup);
2475 break;
2476 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002477 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002478 break;
2479
2480 case POPEN_2:
2481 case POPEN_4:
2482 {
2483 char *m1, *m2;
2484 PyObject *p1, *p2;
2485
2486 if (mode && _O_TEXT) {
2487 m1 = "r";
2488 m2 = "w";
2489 } else {
2490 m1 = "rb";
2491 m2 = "wb";
2492 }
2493
2494 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2495 f1 = _fdopen(fd1, m2);
2496 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2497 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002498 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002499 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002500 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002501 PyFile_SetBufSize(p2, 0);
2502
2503 if (n != 4)
2504 CloseHandle(hChildStderrRdDup);
2505
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002506 f = Py_BuildValue("OO",p1,p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002507 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002508 break;
2509 }
2510
2511 case POPEN_3:
2512 {
2513 char *m1, *m2;
2514 PyObject *p1, *p2, *p3;
2515
2516 if (mode && _O_TEXT) {
2517 m1 = "r";
2518 m2 = "w";
2519 } else {
2520 m1 = "rb";
2521 m2 = "wb";
2522 }
2523
2524 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2525 f1 = _fdopen(fd1, m2);
2526 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2527 f2 = _fdopen(fd2, m1);
2528 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2529 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002530 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002531 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2532 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002533 PyFile_SetBufSize(p1, 0);
2534 PyFile_SetBufSize(p2, 0);
2535 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002536 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002537 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002538 break;
2539 }
2540 }
2541
2542 if (n == POPEN_4) {
2543 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002544 hChildStdinRd,
2545 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002546 hChildStdoutWr,
2547 &hProcess))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002548 return win32_error("CreateProcess", NULL);
2549 }
2550 else {
2551 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002552 hChildStdinRd,
2553 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002554 hChildStderrWr,
2555 &hProcess))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002556 return win32_error("CreateProcess", NULL);
2557 }
2558
Mark Hammondb37a3732000-08-14 04:47:33 +00002559 /*
2560 * Insert the files we've created into the process dictionary
2561 * all referencing the list with the process handle and the
2562 * initial number of files (see description below in _PyPclose).
2563 * Since if _PyPclose later tried to wait on a process when all
2564 * handles weren't closed, it could create a deadlock with the
2565 * child, we spend some energy here to try to ensure that we
2566 * either insert all file handles into the dictionary or none
2567 * at all. It's a little clumsy with the various popen modes
2568 * and variable number of files involved.
2569 */
2570 if (!_PyPopenProcs) {
2571 _PyPopenProcs = PyDict_New();
2572 }
2573
2574 if (_PyPopenProcs) {
2575 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2576 int ins_rc[3];
2577
2578 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2579 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2580
2581 procObj = PyList_New(2);
2582 hProcessObj = PyLong_FromVoidPtr(hProcess);
2583 intObj = PyInt_FromLong(file_count);
2584
2585 if (procObj && hProcessObj && intObj) {
2586 PyList_SetItem(procObj,0,hProcessObj);
2587 PyList_SetItem(procObj,1,intObj);
2588
2589 fileObj[0] = PyLong_FromVoidPtr(f1);
2590 if (fileObj[0]) {
2591 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2592 fileObj[0],
2593 procObj);
2594 }
2595 if (file_count >= 2) {
2596 fileObj[1] = PyLong_FromVoidPtr(f2);
2597 if (fileObj[1]) {
2598 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2599 fileObj[1],
2600 procObj);
2601 }
2602 }
2603 if (file_count >= 3) {
2604 fileObj[2] = PyLong_FromVoidPtr(f3);
2605 if (fileObj[2]) {
2606 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2607 fileObj[2],
2608 procObj);
2609 }
2610 }
2611
2612 if (ins_rc[0] < 0 || !fileObj[0] ||
2613 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2614 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2615 /* Something failed - remove any dictionary
2616 * entries that did make it.
2617 */
2618 if (!ins_rc[0] && fileObj[0]) {
2619 PyDict_DelItem(_PyPopenProcs,
2620 fileObj[0]);
2621 }
2622 if (!ins_rc[1] && fileObj[1]) {
2623 PyDict_DelItem(_PyPopenProcs,
2624 fileObj[1]);
2625 }
2626 if (!ins_rc[2] && fileObj[2]) {
2627 PyDict_DelItem(_PyPopenProcs,
2628 fileObj[2]);
2629 }
2630 }
2631 }
2632
2633 /*
2634 * Clean up our localized references for the dictionary keys
2635 * and value since PyDict_SetItem will Py_INCREF any copies
2636 * that got placed in the dictionary.
2637 */
2638 Py_XDECREF(procObj);
2639 Py_XDECREF(fileObj[0]);
2640 Py_XDECREF(fileObj[1]);
2641 Py_XDECREF(fileObj[2]);
2642 }
2643
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002644 /* Child is launched. Close the parents copy of those pipe
2645 * handles that only the child should have open. You need to
2646 * make sure that no handles to the write end of the output pipe
2647 * are maintained in this process or else the pipe will not close
2648 * when the child process exits and the ReadFile will hang. */
2649
2650 if (!CloseHandle(hChildStdinRd))
2651 return win32_error("CloseHandle", NULL);
2652
2653 if (!CloseHandle(hChildStdoutWr))
2654 return win32_error("CloseHandle", NULL);
2655
2656 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2657 return win32_error("CloseHandle", NULL);
2658
2659 return f;
2660}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002661
2662/*
2663 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2664 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002665 *
2666 * This function uses the _PyPopenProcs dictionary in order to map the
2667 * input file pointer to information about the process that was
2668 * originally created by the popen* call that created the file pointer.
2669 * The dictionary uses the file pointer as a key (with one entry
2670 * inserted for each file returned by the original popen* call) and a
2671 * single list object as the value for all files from a single call.
2672 * The list object contains the Win32 process handle at [0], and a file
2673 * count at [1], which is initialized to the total number of file
2674 * handles using that list.
2675 *
2676 * This function closes whichever handle it is passed, and decrements
2677 * the file count in the dictionary for the process handle pointed to
2678 * by this file. On the last close (when the file count reaches zero),
2679 * this function will wait for the child process and then return its
2680 * exit code as the result of the close() operation. This permits the
2681 * files to be closed in any order - it is always the close() of the
2682 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002683 */
2684static int _PyPclose(FILE *file)
2685{
Fredrik Lundh20318932000-07-26 17:29:12 +00002686 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002687 DWORD exit_code;
2688 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002689 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2690 long file_count;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002691
Fredrik Lundh20318932000-07-26 17:29:12 +00002692 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002693 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002694 */
2695 result = fclose(file);
2696
Fredrik Lundh56055a42000-07-23 19:47:12 +00002697 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002698 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2699 (procObj = PyDict_GetItem(_PyPopenProcs,
2700 fileObj)) != NULL &&
2701 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2702 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2703
2704 hProcess = PyLong_AsVoidPtr(hProcessObj);
2705 file_count = PyInt_AsLong(intObj);
2706
2707 if (file_count > 1) {
2708 /* Still other files referencing process */
2709 file_count--;
2710 PyList_SetItem(procObj,1,
2711 PyInt_FromLong(file_count));
2712 } else {
2713 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002714 if (result != EOF &&
2715 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2716 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002717 /* Possible truncation here in 16-bit environments, but
2718 * real exit codes are just the lower byte in any event.
2719 */
2720 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002721 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002722 /* Indicate failure - this will cause the file object
2723 * to raise an I/O error and translate the last Win32
2724 * error code from errno. We do have a problem with
2725 * last errors that overlap the normal errno table,
2726 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002727 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002728 if (result != EOF) {
2729 /* If the error wasn't from the fclose(), then
2730 * set errno for the file object error handling.
2731 */
2732 errno = GetLastError();
2733 }
2734 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002735 }
2736
2737 /* Free up the native handle at this point */
2738 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002739 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002740
Mark Hammondb37a3732000-08-14 04:47:33 +00002741 /* Remove this file pointer from dictionary */
2742 PyDict_DelItem(_PyPopenProcs, fileObj);
2743
2744 if (PyDict_Size(_PyPopenProcs) == 0) {
2745 Py_DECREF(_PyPopenProcs);
2746 _PyPopenProcs = NULL;
2747 }
2748
2749 } /* if object retrieval ok */
2750
2751 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002752 } /* if _PyPopenProcs */
2753
Fredrik Lundh56055a42000-07-23 19:47:12 +00002754 return result;
2755}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002756#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002758posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002759{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002760 char *name;
2761 char *mode = "r";
2762 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002763 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002764 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002765 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002766 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002767 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002768 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002769 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002770 if (fp == NULL)
2771 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002772 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002773 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002774 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002775 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002776}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002777#endif
2778
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002779#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002781
Guido van Rossumb6775db1994-08-01 11:34:53 +00002782#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002783static char posix_setuid__doc__[] =
2784"setuid(uid) -> None\n\
2785Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002787posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002788{
2789 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002790 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002791 return NULL;
2792 if (setuid(uid) < 0)
2793 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002794 Py_INCREF(Py_None);
2795 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002796}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002797#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002798
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002799
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002800#ifdef HAVE_SETEUID
2801static char posix_seteuid__doc__[] =
2802"seteuid(uid) -> None\n\
2803Set the current process's effective user id.";
2804static PyObject *
2805posix_seteuid (PyObject *self, PyObject *args)
2806{
2807 int euid;
2808 if (!PyArg_ParseTuple(args, "i", &euid)) {
2809 return NULL;
2810 } else if (seteuid(euid) < 0) {
2811 return posix_error();
2812 } else {
2813 Py_INCREF(Py_None);
2814 return Py_None;
2815 }
2816}
2817#endif /* HAVE_SETEUID */
2818
2819#ifdef HAVE_SETEGID
2820static char posix_setegid__doc__[] =
2821"setegid(gid) -> None\n\
2822Set the current process's effective group id.";
2823static PyObject *
2824posix_setegid (PyObject *self, PyObject *args)
2825{
2826 int egid;
2827 if (!PyArg_ParseTuple(args, "i", &egid)) {
2828 return NULL;
2829 } else if (setegid(egid) < 0) {
2830 return posix_error();
2831 } else {
2832 Py_INCREF(Py_None);
2833 return Py_None;
2834 }
2835}
2836#endif /* HAVE_SETEGID */
2837
2838#ifdef HAVE_SETREUID
2839static char posix_setreuid__doc__[] =
2840"seteuid(ruid, euid) -> None\n\
2841Set the current process's real and effective user ids.";
2842static PyObject *
2843posix_setreuid (PyObject *self, PyObject *args)
2844{
2845 int ruid, euid;
2846 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2847 return NULL;
2848 } else if (setreuid(ruid, euid) < 0) {
2849 return posix_error();
2850 } else {
2851 Py_INCREF(Py_None);
2852 return Py_None;
2853 }
2854}
2855#endif /* HAVE_SETREUID */
2856
2857#ifdef HAVE_SETREGID
2858static char posix_setregid__doc__[] =
2859"setegid(rgid, egid) -> None\n\
2860Set the current process's real and effective group ids.";
2861static PyObject *
2862posix_setregid (PyObject *self, PyObject *args)
2863{
2864 int rgid, egid;
2865 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2866 return NULL;
2867 } else if (setregid(rgid, egid) < 0) {
2868 return posix_error();
2869 } else {
2870 Py_INCREF(Py_None);
2871 return Py_None;
2872 }
2873}
2874#endif /* HAVE_SETREGID */
2875
Guido van Rossumb6775db1994-08-01 11:34:53 +00002876#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002877static char posix_setgid__doc__[] =
2878"setgid(gid) -> None\n\
2879Set the current process's group id.";
2880
Barry Warsaw53699e91996-12-10 23:23:01 +00002881static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002882posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002883{
2884 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002885 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002886 return NULL;
2887 if (setgid(gid) < 0)
2888 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002889 Py_INCREF(Py_None);
2890 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002891}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002892#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002894
Guido van Rossumb6775db1994-08-01 11:34:53 +00002895#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002896static char posix_waitpid__doc__[] =
2897"waitpid(pid, options) -> (pid, status)\n\
2898Wait for completion of a give child process.";
2899
Barry Warsaw53699e91996-12-10 23:23:01 +00002900static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002901posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002902{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002903 int pid, options;
2904#ifdef UNION_WAIT
2905 union wait status;
2906#define status_i (status.w_status)
2907#else
2908 int status;
2909#define status_i status
2910#endif
2911 status_i = 0;
2912
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002913 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00002914 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002915 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002916#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002917 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002918#else
2919 pid = waitpid(pid, &status, options);
2920#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002921 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00002922 if (pid == -1)
2923 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00002924 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002925 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00002926}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002927#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00002928
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002929
Guido van Rossumad0ee831995-03-01 10:34:45 +00002930#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002931static char posix_wait__doc__[] =
2932"wait() -> (pid, status)\n\
2933Wait for completion of a child process.";
2934
Barry Warsaw53699e91996-12-10 23:23:01 +00002935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002936posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00002937{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002938 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002939#ifdef UNION_WAIT
2940 union wait status;
2941#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002942#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002943 int status;
2944#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002945#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002946 if (!PyArg_ParseTuple(args, ":wait"))
2947 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002948 status_i = 0;
2949 Py_BEGIN_ALLOW_THREADS
2950 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00002951 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00002952 if (pid == -1)
2953 return posix_error();
2954 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002955 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002956#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00002957}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002958#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002960
2961static char posix_lstat__doc__[] =
2962"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
2963Like stat(path), but do not follow symbolic links.";
2964
Barry Warsaw53699e91996-12-10 23:23:01 +00002965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002966posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002967{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002968#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002969 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002970#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00002971 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002972#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002973}
2974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002975
Guido van Rossumb6775db1994-08-01 11:34:53 +00002976#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002977static char posix_readlink__doc__[] =
2978"readlink(path) -> path\n\
2979Return a string representing the path to which the symbolic link points.";
2980
Barry Warsaw53699e91996-12-10 23:23:01 +00002981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002982posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002983{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002984 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002985 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002986 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002987 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002988 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002989 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002990 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00002991 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002992 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002993 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002994 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002995}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002996#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002997
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002998
Guido van Rossumb6775db1994-08-01 11:34:53 +00002999#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003000static char posix_symlink__doc__[] =
3001"symlink(src, dst) -> None\n\
3002Create a symbolic link.";
3003
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003005posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003006{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003007 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003008}
3009#endif /* HAVE_SYMLINK */
3010
3011
3012#ifdef HAVE_TIMES
3013#ifndef HZ
3014#define HZ 60 /* Universal constant :-) */
3015#endif /* HZ */
3016
Guido van Rossumd48f2521997-12-05 22:19:34 +00003017#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3018static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003019system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003020{
3021 ULONG value = 0;
3022
3023 Py_BEGIN_ALLOW_THREADS
3024 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3025 Py_END_ALLOW_THREADS
3026
3027 return value;
3028}
3029
3030static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003031posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003032{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003033 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003034 return NULL;
3035
3036 /* Currently Only Uptime is Provided -- Others Later */
3037 return Py_BuildValue("ddddd",
3038 (double)0 /* t.tms_utime / HZ */,
3039 (double)0 /* t.tms_stime / HZ */,
3040 (double)0 /* t.tms_cutime / HZ */,
3041 (double)0 /* t.tms_cstime / HZ */,
3042 (double)system_uptime() / 1000);
3043}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003044#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003046posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003047{
3048 struct tms t;
3049 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003050 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003051 return NULL;
3052 errno = 0;
3053 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003054 if (c == (clock_t) -1)
3055 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003056 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003057 (double)t.tms_utime / HZ,
3058 (double)t.tms_stime / HZ,
3059 (double)t.tms_cutime / HZ,
3060 (double)t.tms_cstime / HZ,
3061 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003062}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003063#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003064#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003065
3066
Guido van Rossum87755a21996-09-07 00:59:43 +00003067#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003068#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003070posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003071{
3072 FILETIME create, exit, kernel, user;
3073 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003074 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003075 return NULL;
3076 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003077 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3078 /* The fields of a FILETIME structure are the hi and lo part
3079 of a 64-bit value expressed in 100 nanosecond units.
3080 1e7 is one second in such units; 1e-7 the inverse.
3081 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3082 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003083 return Py_BuildValue(
3084 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003085 (double)(kernel.dwHighDateTime*429.4967296 +
3086 kernel.dwLowDateTime*1e-7),
3087 (double)(user.dwHighDateTime*429.4967296 +
3088 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003089 (double)0,
3090 (double)0,
3091 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003092}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003093#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003094
3095#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003096static char posix_times__doc__[] =
3097"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3098Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003099#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003101
Guido van Rossumb6775db1994-08-01 11:34:53 +00003102#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003103static char posix_setsid__doc__[] =
3104"setsid() -> None\n\
3105Call the system call setsid().";
3106
Barry Warsaw53699e91996-12-10 23:23:01 +00003107static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003108posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003109{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003110 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003111 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003112 if (setsid() < 0)
3113 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003114 Py_INCREF(Py_None);
3115 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003116}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003117#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003118
Guido van Rossumb6775db1994-08-01 11:34:53 +00003119#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003120static char posix_setpgid__doc__[] =
3121"setpgid(pid, pgrp) -> None\n\
3122Call the system call setpgid().";
3123
Barry Warsaw53699e91996-12-10 23:23:01 +00003124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003125posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003126{
3127 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003128 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003129 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003130 if (setpgid(pid, pgrp) < 0)
3131 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003132 Py_INCREF(Py_None);
3133 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003134}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003135#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003137
Guido van Rossumb6775db1994-08-01 11:34:53 +00003138#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003139static char posix_tcgetpgrp__doc__[] =
3140"tcgetpgrp(fd) -> pgid\n\
3141Return the process group associated with the terminal given by a fd.";
3142
Barry Warsaw53699e91996-12-10 23:23:01 +00003143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003144posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003145{
3146 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003147 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003148 return NULL;
3149 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003150 if (pgid < 0)
3151 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003152 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003153}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003154#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003156
Guido van Rossumb6775db1994-08-01 11:34:53 +00003157#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003158static char posix_tcsetpgrp__doc__[] =
3159"tcsetpgrp(fd, pgid) -> None\n\
3160Set the process group associated with the terminal given by a fd.";
3161
Barry Warsaw53699e91996-12-10 23:23:01 +00003162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003163posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003164{
3165 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003166 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003167 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003168 if (tcsetpgrp(fd, pgid) < 0)
3169 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003170 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003171 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003172}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003173#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003174
Guido van Rossum687dd131993-05-17 08:34:16 +00003175/* Functions acting on file descriptors */
3176
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003177static char posix_open__doc__[] =
3178"open(filename, flag [, mode=0777]) -> fd\n\
3179Open a file (for low level IO).";
3180
Barry Warsaw53699e91996-12-10 23:23:01 +00003181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003182posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003183{
3184 char *file;
3185 int flag;
3186 int mode = 0777;
3187 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003188 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3189 return NULL;
3190
Barry Warsaw53699e91996-12-10 23:23:01 +00003191 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003192 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003193 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003194 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003195 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003196 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003197}
3198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003199
3200static char posix_close__doc__[] =
3201"close(fd) -> None\n\
3202Close a file descriptor (for low level IO).";
3203
Barry Warsaw53699e91996-12-10 23:23:01 +00003204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003205posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003206{
3207 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003208 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003209 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003210 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003211 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003212 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003213 if (res < 0)
3214 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003215 Py_INCREF(Py_None);
3216 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003217}
3218
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003219
3220static char posix_dup__doc__[] =
3221"dup(fd) -> fd2\n\
3222Return a duplicate of a file descriptor.";
3223
Barry Warsaw53699e91996-12-10 23:23:01 +00003224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003225posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003226{
3227 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003228 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003229 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003230 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003231 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003232 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003233 if (fd < 0)
3234 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003235 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003236}
3237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003238
3239static char posix_dup2__doc__[] =
3240"dup2(fd, fd2) -> None\n\
3241Duplicate file descriptor.";
3242
Barry Warsaw53699e91996-12-10 23:23:01 +00003243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003244posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003245{
3246 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003247 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003248 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003249 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003250 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003251 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003252 if (res < 0)
3253 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003254 Py_INCREF(Py_None);
3255 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003256}
3257
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003258
3259static char posix_lseek__doc__[] =
3260"lseek(fd, pos, how) -> newpos\n\
3261Set the current position of a file descriptor.";
3262
Barry Warsaw53699e91996-12-10 23:23:01 +00003263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003264posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003265{
3266 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003267#ifdef MS_WIN64
3268 LONG_LONG pos, res;
3269#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003270 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003271#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003272 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003273 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003274 return NULL;
3275#ifdef SEEK_SET
3276 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3277 switch (how) {
3278 case 0: how = SEEK_SET; break;
3279 case 1: how = SEEK_CUR; break;
3280 case 2: how = SEEK_END; break;
3281 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003282#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003283
3284#if !defined(HAVE_LARGEFILE_SUPPORT)
3285 pos = PyInt_AsLong(posobj);
3286#else
3287 pos = PyLong_Check(posobj) ?
3288 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3289#endif
3290 if (PyErr_Occurred())
3291 return NULL;
3292
Barry Warsaw53699e91996-12-10 23:23:01 +00003293 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003294#ifdef MS_WIN64
3295 res = _lseeki64(fd, pos, how);
3296#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003297 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003298#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003299 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003300 if (res < 0)
3301 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003302
3303#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003304 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003305#else
3306 return PyLong_FromLongLong(res);
3307#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003308}
3309
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003310
3311static char posix_read__doc__[] =
3312"read(fd, buffersize) -> string\n\
3313Read a file descriptor.";
3314
Barry Warsaw53699e91996-12-10 23:23:01 +00003315static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003316posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003317{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003318 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003319 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003320 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003321 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003322 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003323 if (buffer == NULL)
3324 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003325 Py_BEGIN_ALLOW_THREADS
3326 n = read(fd, PyString_AsString(buffer), size);
3327 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003328 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003329 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003330 return posix_error();
3331 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003332 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003333 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003334 return buffer;
3335}
3336
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003337
3338static char posix_write__doc__[] =
3339"write(fd, string) -> byteswritten\n\
3340Write a string to a file descriptor.";
3341
Barry Warsaw53699e91996-12-10 23:23:01 +00003342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003343posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003344{
3345 int fd, size;
3346 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003347 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003348 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003349 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003350 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003351 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003352 if (size < 0)
3353 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003354 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003355}
3356
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003357
3358static char posix_fstat__doc__[]=
3359"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3360Like stat(), but for an open file descriptor.";
3361
Barry Warsaw53699e91996-12-10 23:23:01 +00003362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003363posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003364{
3365 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003366 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003367 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003368 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003369 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003370 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003371 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003372 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003373 if (res != 0)
3374 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003375
3376 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003377}
3378
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003379
3380static char posix_fdopen__doc__[] =
3381"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3382Return an open file object connected to a file descriptor.";
3383
Barry Warsaw53699e91996-12-10 23:23:01 +00003384static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003385posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003386{
Guido van Rossum687dd131993-05-17 08:34:16 +00003387 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003388 char *mode = "r";
3389 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003390 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003391 PyObject *f;
3392 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003393 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003394
Barry Warsaw53699e91996-12-10 23:23:01 +00003395 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003396 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003397 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003398 if (fp == NULL)
3399 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003400 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003401 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003402 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003403 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003404}
3405
Skip Montanaro1517d842000-07-19 14:34:14 +00003406static char posix_isatty__doc__[] =
3407"isatty(fd) -> Boolean\n\
3408Return true if the file descriptor 'fd' is an open file descriptor\n\
3409connected to a terminal.";
3410
3411static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003412posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003413{
3414 int fd;
3415 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3416 return NULL;
3417 return Py_BuildValue("i", isatty(fd));
3418}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003419
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003420#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003421static char posix_pipe__doc__[] =
3422"pipe() -> (read_end, write_end)\n\
3423Create a pipe.";
3424
Barry Warsaw53699e91996-12-10 23:23:01 +00003425static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003426posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003427{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003428#if defined(PYOS_OS2)
3429 HFILE read, write;
3430 APIRET rc;
3431
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003432 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003433 return NULL;
3434
3435 Py_BEGIN_ALLOW_THREADS
3436 rc = DosCreatePipe( &read, &write, 4096);
3437 Py_END_ALLOW_THREADS
3438 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003439 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003440
3441 return Py_BuildValue("(ii)", read, write);
3442#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003443#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003444 int fds[2];
3445 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003446 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003447 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003448 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003449 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003450 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003451 if (res != 0)
3452 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003453 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003454#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003455 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003456 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003457 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003458 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003459 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003460 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003461 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003462 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003463 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003464 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003465 read_fd = _open_osfhandle((intptr_t)read, 0);
3466 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003467 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003468#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003469#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003470}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003471#endif /* HAVE_PIPE */
3472
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003473
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003474#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003475static char posix_mkfifo__doc__[] =
3476"mkfifo(file, [, mode=0666]) -> None\n\
3477Create a FIFO (a POSIX named pipe).";
3478
Barry Warsaw53699e91996-12-10 23:23:01 +00003479static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003480posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003481{
3482 char *file;
3483 int mode = 0666;
3484 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003485 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003486 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003487 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003488 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003489 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003490 if (res < 0)
3491 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003492 Py_INCREF(Py_None);
3493 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003494}
3495#endif
3496
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003497
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003498#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003499static char posix_ftruncate__doc__[] =
3500"ftruncate(fd, length) -> None\n\
3501Truncate a file to a specified length.";
3502
Barry Warsaw53699e91996-12-10 23:23:01 +00003503static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003504posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003505{
3506 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003507 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003508 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003509 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003510
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003511 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003512 return NULL;
3513
3514#if !defined(HAVE_LARGEFILE_SUPPORT)
3515 length = PyInt_AsLong(lenobj);
3516#else
3517 length = PyLong_Check(lenobj) ?
3518 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3519#endif
3520 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003521 return NULL;
3522
Barry Warsaw53699e91996-12-10 23:23:01 +00003523 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003524 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003525 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003526 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003527 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003528 return NULL;
3529 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003530 Py_INCREF(Py_None);
3531 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003532}
3533#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003534
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003535#ifdef NeXT
3536#define HAVE_PUTENV
3537/* Steve Spicklemire got this putenv from NeXTAnswers */
3538static int
3539putenv(char *newval)
3540{
3541 extern char **environ;
3542
3543 static int firstTime = 1;
3544 char **ep;
3545 char *cp;
3546 int esiz;
3547 char *np;
3548
3549 if (!(np = strchr(newval, '=')))
3550 return 1;
3551 *np = '\0';
3552
3553 /* look it up */
3554 for (ep=environ ; *ep ; ep++)
3555 {
3556 /* this should always be true... */
3557 if (cp = strchr(*ep, '='))
3558 {
3559 *cp = '\0';
3560 if (!strcmp(*ep, newval))
3561 {
3562 /* got it! */
3563 *cp = '=';
3564 break;
3565 }
3566 *cp = '=';
3567 }
3568 else
3569 {
3570 *np = '=';
3571 return 1;
3572 }
3573 }
3574
3575 *np = '=';
3576 if (*ep)
3577 {
3578 /* the string was already there:
3579 just replace it with the new one */
3580 *ep = newval;
3581 return 0;
3582 }
3583
3584 /* expand environ by one */
3585 for (esiz=2, ep=environ ; *ep ; ep++)
3586 esiz++;
3587 if (firstTime)
3588 {
3589 char **epp;
3590 char **newenv;
3591 if (!(newenv = malloc(esiz * sizeof(char *))))
3592 return 1;
3593
3594 for (ep=environ, epp=newenv ; *ep ;)
3595 *epp++ = *ep++;
3596 *epp++ = newval;
3597 *epp = (char *) 0;
3598 environ = newenv;
3599 }
3600 else
3601 {
3602 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3603 return 1;
3604 environ[esiz - 2] = newval;
3605 environ[esiz - 1] = (char *) 0;
3606 firstTime = 0;
3607 }
3608
3609 return 0;
3610}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003611#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003612
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003613
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003614#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003615static char posix_putenv__doc__[] =
3616"putenv(key, value) -> None\n\
3617Change or add an environment variable.";
3618
Guido van Rossumbcc20741998-08-04 22:53:56 +00003619#ifdef __BEOS__
3620/* We have putenv(), but not in the headers (as of PR2). - [cjh] */
3621int putenv( const char *str );
3622#endif
3623
Fred Drake762e2061999-08-26 17:23:54 +00003624/* Save putenv() parameters as values here, so we can collect them when they
3625 * get re-set with another call for the same key. */
3626static PyObject *posix_putenv_garbage;
3627
Barry Warsaw53699e91996-12-10 23:23:01 +00003628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003629posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003630{
3631 char *s1, *s2;
3632 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003633 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003634
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003635 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003636 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003637
3638#if defined(PYOS_OS2)
3639 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3640 APIRET rc;
3641
3642 if (strlen(s2) == 0) /* If New Value is an Empty String */
3643 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3644
3645 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3646 if (rc != NO_ERROR)
3647 return os2_error(rc);
3648
3649 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3650 APIRET rc;
3651
3652 if (strlen(s2) == 0) /* If New Value is an Empty String */
3653 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3654
3655 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3656 if (rc != NO_ERROR)
3657 return os2_error(rc);
3658 } else {
3659#endif
3660
Fred Drake762e2061999-08-26 17:23:54 +00003661 /* XXX This can leak memory -- not easy to fix :-( */
3662 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3663 if (newstr == NULL)
3664 return PyErr_NoMemory();
3665 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003666 (void) sprintf(new, "%s=%s", s1, s2);
3667 if (putenv(new)) {
3668 posix_error();
3669 return NULL;
3670 }
Fred Drake762e2061999-08-26 17:23:54 +00003671 /* Install the first arg and newstr in posix_putenv_garbage;
3672 * this will cause previous value to be collected. This has to
3673 * happen after the real putenv() call because the old value
3674 * was still accessible until then. */
3675 if (PyDict_SetItem(posix_putenv_garbage,
3676 PyTuple_GET_ITEM(args, 0), newstr)) {
3677 /* really not much we can do; just leak */
3678 PyErr_Clear();
3679 }
3680 else {
3681 Py_DECREF(newstr);
3682 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003683
3684#if defined(PYOS_OS2)
3685 }
3686#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003687 Py_INCREF(Py_None);
3688 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003689}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003690#endif /* putenv */
3691
3692#ifdef HAVE_STRERROR
3693static char posix_strerror__doc__[] =
3694"strerror(code) -> string\n\
3695Translate an error code to a message string.";
3696
3697PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003698posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003699{
3700 int code;
3701 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003702 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003703 return NULL;
3704 message = strerror(code);
3705 if (message == NULL) {
3706 PyErr_SetString(PyExc_ValueError,
3707 "strerror code out of range");
3708 return NULL;
3709 }
3710 return PyString_FromString(message);
3711}
3712#endif /* strerror */
3713
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003714
Guido van Rossumc9641791998-08-04 15:26:23 +00003715#ifdef HAVE_SYS_WAIT_H
3716
3717#ifdef WIFSTOPPED
3718static char posix_WIFSTOPPED__doc__[] =
3719"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003720Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003721
3722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003723posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003724{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003725#ifdef UNION_WAIT
3726 union wait status;
3727#define status_i (status.w_status)
3728#else
3729 int status;
3730#define status_i status
3731#endif
3732 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003733
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003734 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003735 {
3736 return NULL;
3737 }
3738
3739 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003740#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003741}
3742#endif /* WIFSTOPPED */
3743
3744#ifdef WIFSIGNALED
3745static char posix_WIFSIGNALED__doc__[] =
3746"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003747Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003748
3749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003750posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003751{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003752#ifdef UNION_WAIT
3753 union wait status;
3754#define status_i (status.w_status)
3755#else
3756 int status;
3757#define status_i status
3758#endif
3759 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003760
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003761 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003762 {
3763 return NULL;
3764 }
3765
3766 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003767#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003768}
3769#endif /* WIFSIGNALED */
3770
3771#ifdef WIFEXITED
3772static char posix_WIFEXITED__doc__[] =
3773"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003774Return true if the process returning 'status' exited using the exit()\n\
3775system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003776
3777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003778posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003779{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003780#ifdef UNION_WAIT
3781 union wait status;
3782#define status_i (status.w_status)
3783#else
3784 int status;
3785#define status_i status
3786#endif
3787 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003788
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003789 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003790 {
3791 return NULL;
3792 }
3793
3794 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003795#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003796}
3797#endif /* WIFEXITED */
3798
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003799#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003800static char posix_WEXITSTATUS__doc__[] =
3801"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003802Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003803
3804static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003805posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003806{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003807#ifdef UNION_WAIT
3808 union wait status;
3809#define status_i (status.w_status)
3810#else
3811 int status;
3812#define status_i status
3813#endif
3814 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003815
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003816 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003817 {
3818 return NULL;
3819 }
3820
3821 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003822#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003823}
3824#endif /* WEXITSTATUS */
3825
3826#ifdef WTERMSIG
3827static char posix_WTERMSIG__doc__[] =
3828"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003829Return the signal that terminated the process that provided the 'status'\n\
3830value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003831
3832static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003833posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003834{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003835#ifdef UNION_WAIT
3836 union wait status;
3837#define status_i (status.w_status)
3838#else
3839 int status;
3840#define status_i status
3841#endif
3842 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003843
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003844 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003845 {
3846 return NULL;
3847 }
3848
3849 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003850#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003851}
3852#endif /* WTERMSIG */
3853
3854#ifdef WSTOPSIG
3855static char posix_WSTOPSIG__doc__[] =
3856"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003857Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003858
3859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003860posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003861{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003862#ifdef UNION_WAIT
3863 union wait status;
3864#define status_i (status.w_status)
3865#else
3866 int status;
3867#define status_i status
3868#endif
3869 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003870
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003871 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003872 {
3873 return NULL;
3874 }
3875
3876 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003877#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003878}
3879#endif /* WSTOPSIG */
3880
3881#endif /* HAVE_SYS_WAIT_H */
3882
3883
Guido van Rossum94f6f721999-01-06 18:42:14 +00003884#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003885#ifdef _SCO_DS
3886/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3887 needed definitions in sys/statvfs.h */
3888#define _SVID3
3889#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003890#include <sys/statvfs.h>
3891
3892static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003893"fstatvfs(fd) -> \n\
3894 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003895Perform an fstatvfs system call on the given fd.";
3896
3897static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003898posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003899{
3900 int fd, res;
3901 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003902 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003903 return NULL;
3904 Py_BEGIN_ALLOW_THREADS
3905 res = fstatvfs(fd, &st);
3906 Py_END_ALLOW_THREADS
3907 if (res != 0)
3908 return posix_error();
3909#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003910 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003911 (long) st.f_bsize,
3912 (long) st.f_frsize,
3913 (long) st.f_blocks,
3914 (long) st.f_bfree,
3915 (long) st.f_bavail,
3916 (long) st.f_files,
3917 (long) st.f_ffree,
3918 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003919 (long) st.f_flag,
3920 (long) st.f_namemax);
3921#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003922 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003923 (long) st.f_bsize,
3924 (long) st.f_frsize,
3925 (LONG_LONG) st.f_blocks,
3926 (LONG_LONG) st.f_bfree,
3927 (LONG_LONG) st.f_bavail,
3928 (LONG_LONG) st.f_files,
3929 (LONG_LONG) st.f_ffree,
3930 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003931 (long) st.f_flag,
3932 (long) st.f_namemax);
3933#endif
3934}
3935#endif /* HAVE_FSTATVFS */
3936
3937
3938#if defined(HAVE_STATVFS)
3939#include <sys/statvfs.h>
3940
3941static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003942"statvfs(path) -> \n\
3943 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003944Perform a statvfs system call on the given path.";
3945
3946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003947posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003948{
3949 char *path;
3950 int res;
3951 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003952 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003953 return NULL;
3954 Py_BEGIN_ALLOW_THREADS
3955 res = statvfs(path, &st);
3956 Py_END_ALLOW_THREADS
3957 if (res != 0)
3958 return posix_error_with_filename(path);
3959#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003960 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003961 (long) st.f_bsize,
3962 (long) st.f_frsize,
3963 (long) st.f_blocks,
3964 (long) st.f_bfree,
3965 (long) st.f_bavail,
3966 (long) st.f_files,
3967 (long) st.f_ffree,
3968 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003969 (long) st.f_flag,
3970 (long) st.f_namemax);
3971#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003972 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003973 (long) st.f_bsize,
3974 (long) st.f_frsize,
3975 (LONG_LONG) st.f_blocks,
3976 (LONG_LONG) st.f_bfree,
3977 (LONG_LONG) st.f_bavail,
3978 (LONG_LONG) st.f_files,
3979 (LONG_LONG) st.f_ffree,
3980 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003981 (long) st.f_flag,
3982 (long) st.f_namemax);
3983#endif
3984}
3985#endif /* HAVE_STATVFS */
3986
3987
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003988#ifdef HAVE_TEMPNAM
3989static char posix_tempnam__doc__[] = "\
3990tempnam([dir[, prefix]]) -> string\n\
3991Return a unique name for a temporary file.\n\
3992The directory and a short may be specified as strings; they may be omitted\n\
3993or None if not needed.";
3994
3995static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003996posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003997{
3998 PyObject *result = NULL;
3999 char *dir = NULL;
4000 char *pfx = NULL;
4001 char *name;
4002
4003 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4004 return NULL;
4005 name = tempnam(dir, pfx);
4006 if (name == NULL)
4007 return PyErr_NoMemory();
4008 result = PyString_FromString(name);
4009 free(name);
4010 return result;
4011}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004012#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004013
4014
4015#ifdef HAVE_TMPFILE
4016static char posix_tmpfile__doc__[] = "\
4017tmpfile() -> file object\n\
4018Create a temporary file with no directory entries.";
4019
4020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004021posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004022{
4023 FILE *fp;
4024
4025 if (!PyArg_ParseTuple(args, ":tmpfile"))
4026 return NULL;
4027 fp = tmpfile();
4028 if (fp == NULL)
4029 return posix_error();
4030 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4031}
4032#endif
4033
4034
4035#ifdef HAVE_TMPNAM
4036static char posix_tmpnam__doc__[] = "\
4037tmpnam() -> string\n\
4038Return a unique name for a temporary file.";
4039
4040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004041posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004042{
4043 char buffer[L_tmpnam];
4044 char *name;
4045
4046 if (!PyArg_ParseTuple(args, ":tmpnam"))
4047 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004048#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004049 name = tmpnam_r(buffer);
4050#else
4051 name = tmpnam(buffer);
4052#endif
4053 if (name == NULL) {
4054 PyErr_SetObject(PyExc_OSError,
4055 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004056#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004057 "unexpected NULL from tmpnam_r"
4058#else
4059 "unexpected NULL from tmpnam"
4060#endif
4061 ));
4062 return NULL;
4063 }
4064 return PyString_FromString(buffer);
4065}
4066#endif
4067
4068
Fred Drakec9680921999-12-13 16:37:25 +00004069/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4070 * It maps strings representing configuration variable names to
4071 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004072 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004073 * rarely-used constants. There are three separate tables that use
4074 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004075 *
4076 * This code is always included, even if none of the interfaces that
4077 * need it are included. The #if hackery needed to avoid it would be
4078 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004079 */
4080struct constdef {
4081 char *name;
4082 long value;
4083};
4084
Fred Drake12c6e2d1999-12-14 21:25:03 +00004085static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004086conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4087 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004088{
4089 if (PyInt_Check(arg)) {
4090 *valuep = PyInt_AS_LONG(arg);
4091 return 1;
4092 }
4093 if (PyString_Check(arg)) {
4094 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004095 size_t lo = 0;
4096 size_t mid;
4097 size_t hi = tablesize;
4098 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004099 char *confname = PyString_AS_STRING(arg);
4100 while (lo < hi) {
4101 mid = (lo + hi) / 2;
4102 cmp = strcmp(confname, table[mid].name);
4103 if (cmp < 0)
4104 hi = mid;
4105 else if (cmp > 0)
4106 lo = mid + 1;
4107 else {
4108 *valuep = table[mid].value;
4109 return 1;
4110 }
4111 }
4112 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4113 }
4114 else
4115 PyErr_SetString(PyExc_TypeError,
4116 "configuration names must be strings or integers");
4117 return 0;
4118}
4119
4120
4121#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4122static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004123#ifdef _PC_ABI_AIO_XFER_MAX
4124 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4125#endif
4126#ifdef _PC_ABI_ASYNC_IO
4127 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4128#endif
Fred Drakec9680921999-12-13 16:37:25 +00004129#ifdef _PC_ASYNC_IO
4130 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4131#endif
4132#ifdef _PC_CHOWN_RESTRICTED
4133 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4134#endif
4135#ifdef _PC_FILESIZEBITS
4136 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4137#endif
4138#ifdef _PC_LAST
4139 {"PC_LAST", _PC_LAST},
4140#endif
4141#ifdef _PC_LINK_MAX
4142 {"PC_LINK_MAX", _PC_LINK_MAX},
4143#endif
4144#ifdef _PC_MAX_CANON
4145 {"PC_MAX_CANON", _PC_MAX_CANON},
4146#endif
4147#ifdef _PC_MAX_INPUT
4148 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4149#endif
4150#ifdef _PC_NAME_MAX
4151 {"PC_NAME_MAX", _PC_NAME_MAX},
4152#endif
4153#ifdef _PC_NO_TRUNC
4154 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4155#endif
4156#ifdef _PC_PATH_MAX
4157 {"PC_PATH_MAX", _PC_PATH_MAX},
4158#endif
4159#ifdef _PC_PIPE_BUF
4160 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4161#endif
4162#ifdef _PC_PRIO_IO
4163 {"PC_PRIO_IO", _PC_PRIO_IO},
4164#endif
4165#ifdef _PC_SOCK_MAXBUF
4166 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4167#endif
4168#ifdef _PC_SYNC_IO
4169 {"PC_SYNC_IO", _PC_SYNC_IO},
4170#endif
4171#ifdef _PC_VDISABLE
4172 {"PC_VDISABLE", _PC_VDISABLE},
4173#endif
4174};
4175
Fred Drakec9680921999-12-13 16:37:25 +00004176static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004177conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004178{
4179 return conv_confname(arg, valuep, posix_constants_pathconf,
4180 sizeof(posix_constants_pathconf)
4181 / sizeof(struct constdef));
4182}
4183#endif
4184
4185#ifdef HAVE_FPATHCONF
4186static char posix_fpathconf__doc__[] = "\
4187fpathconf(fd, name) -> integer\n\
4188Return the configuration limit name for the file descriptor fd.\n\
4189If there is no limit, return -1.";
4190
4191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004192posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004193{
4194 PyObject *result = NULL;
4195 int name, fd;
4196
Fred Drake12c6e2d1999-12-14 21:25:03 +00004197 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4198 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004199 long limit;
4200
4201 errno = 0;
4202 limit = fpathconf(fd, name);
4203 if (limit == -1 && errno != 0)
4204 posix_error();
4205 else
4206 result = PyInt_FromLong(limit);
4207 }
4208 return result;
4209}
4210#endif
4211
4212
4213#ifdef HAVE_PATHCONF
4214static char posix_pathconf__doc__[] = "\
4215pathconf(path, name) -> integer\n\
4216Return the configuration limit name for the file or directory path.\n\
4217If there is no limit, return -1.";
4218
4219static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004220posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004221{
4222 PyObject *result = NULL;
4223 int name;
4224 char *path;
4225
4226 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4227 conv_path_confname, &name)) {
4228 long limit;
4229
4230 errno = 0;
4231 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004232 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004233 if (errno == EINVAL)
4234 /* could be a path or name problem */
4235 posix_error();
4236 else
4237 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004238 }
Fred Drakec9680921999-12-13 16:37:25 +00004239 else
4240 result = PyInt_FromLong(limit);
4241 }
4242 return result;
4243}
4244#endif
4245
4246#ifdef HAVE_CONFSTR
4247static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004248#ifdef _CS_ARCHITECTURE
4249 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4250#endif
4251#ifdef _CS_HOSTNAME
4252 {"CS_HOSTNAME", _CS_HOSTNAME},
4253#endif
4254#ifdef _CS_HW_PROVIDER
4255 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4256#endif
4257#ifdef _CS_HW_SERIAL
4258 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4259#endif
4260#ifdef _CS_INITTAB_NAME
4261 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4262#endif
Fred Drakec9680921999-12-13 16:37:25 +00004263#ifdef _CS_LFS64_CFLAGS
4264 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4265#endif
4266#ifdef _CS_LFS64_LDFLAGS
4267 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4268#endif
4269#ifdef _CS_LFS64_LIBS
4270 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4271#endif
4272#ifdef _CS_LFS64_LINTFLAGS
4273 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4274#endif
4275#ifdef _CS_LFS_CFLAGS
4276 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4277#endif
4278#ifdef _CS_LFS_LDFLAGS
4279 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4280#endif
4281#ifdef _CS_LFS_LIBS
4282 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4283#endif
4284#ifdef _CS_LFS_LINTFLAGS
4285 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4286#endif
Fred Draked86ed291999-12-15 15:34:33 +00004287#ifdef _CS_MACHINE
4288 {"CS_MACHINE", _CS_MACHINE},
4289#endif
Fred Drakec9680921999-12-13 16:37:25 +00004290#ifdef _CS_PATH
4291 {"CS_PATH", _CS_PATH},
4292#endif
Fred Draked86ed291999-12-15 15:34:33 +00004293#ifdef _CS_RELEASE
4294 {"CS_RELEASE", _CS_RELEASE},
4295#endif
4296#ifdef _CS_SRPC_DOMAIN
4297 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4298#endif
4299#ifdef _CS_SYSNAME
4300 {"CS_SYSNAME", _CS_SYSNAME},
4301#endif
4302#ifdef _CS_VERSION
4303 {"CS_VERSION", _CS_VERSION},
4304#endif
Fred Drakec9680921999-12-13 16:37:25 +00004305#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4306 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4307#endif
4308#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4309 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4310#endif
4311#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4312 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4313#endif
4314#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4315 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4316#endif
4317#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4318 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4319#endif
4320#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4321 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4322#endif
4323#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4324 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4325#endif
4326#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4327 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4328#endif
4329#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4330 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4331#endif
4332#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4333 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4334#endif
4335#ifdef _CS_XBS5_LP64_OFF64_LIBS
4336 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4337#endif
4338#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4339 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4340#endif
4341#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4342 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4343#endif
4344#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4345 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4346#endif
4347#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4348 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4349#endif
4350#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4351 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4352#endif
Fred Draked86ed291999-12-15 15:34:33 +00004353#ifdef _MIPS_CS_AVAIL_PROCESSORS
4354 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4355#endif
4356#ifdef _MIPS_CS_BASE
4357 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4358#endif
4359#ifdef _MIPS_CS_HOSTID
4360 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4361#endif
4362#ifdef _MIPS_CS_HW_NAME
4363 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4364#endif
4365#ifdef _MIPS_CS_NUM_PROCESSORS
4366 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4367#endif
4368#ifdef _MIPS_CS_OSREL_MAJ
4369 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4370#endif
4371#ifdef _MIPS_CS_OSREL_MIN
4372 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4373#endif
4374#ifdef _MIPS_CS_OSREL_PATCH
4375 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4376#endif
4377#ifdef _MIPS_CS_OS_NAME
4378 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4379#endif
4380#ifdef _MIPS_CS_OS_PROVIDER
4381 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4382#endif
4383#ifdef _MIPS_CS_PROCESSORS
4384 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4385#endif
4386#ifdef _MIPS_CS_SERIAL
4387 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4388#endif
4389#ifdef _MIPS_CS_VENDOR
4390 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4391#endif
Fred Drakec9680921999-12-13 16:37:25 +00004392};
4393
4394static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004395conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004396{
4397 return conv_confname(arg, valuep, posix_constants_confstr,
4398 sizeof(posix_constants_confstr)
4399 / sizeof(struct constdef));
4400}
4401
4402static char posix_confstr__doc__[] = "\
4403confstr(name) -> string\n\
4404Return a string-valued system configuration variable.";
4405
4406static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004407posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004408{
4409 PyObject *result = NULL;
4410 int name;
4411 char buffer[64];
4412
4413 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4414 int len = confstr(name, buffer, sizeof(buffer));
4415
Fred Drakec9680921999-12-13 16:37:25 +00004416 errno = 0;
4417 if (len == 0) {
4418 if (errno != 0)
4419 posix_error();
4420 else
4421 result = PyString_FromString("");
4422 }
4423 else {
4424 if (len >= sizeof(buffer)) {
4425 result = PyString_FromStringAndSize(NULL, len);
4426 if (result != NULL)
4427 confstr(name, PyString_AS_STRING(result), len+1);
4428 }
4429 else
4430 result = PyString_FromString(buffer);
4431 }
4432 }
4433 return result;
4434}
4435#endif
4436
4437
4438#ifdef HAVE_SYSCONF
4439static struct constdef posix_constants_sysconf[] = {
4440#ifdef _SC_2_CHAR_TERM
4441 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4442#endif
4443#ifdef _SC_2_C_BIND
4444 {"SC_2_C_BIND", _SC_2_C_BIND},
4445#endif
4446#ifdef _SC_2_C_DEV
4447 {"SC_2_C_DEV", _SC_2_C_DEV},
4448#endif
4449#ifdef _SC_2_C_VERSION
4450 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4451#endif
4452#ifdef _SC_2_FORT_DEV
4453 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4454#endif
4455#ifdef _SC_2_FORT_RUN
4456 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4457#endif
4458#ifdef _SC_2_LOCALEDEF
4459 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4460#endif
4461#ifdef _SC_2_SW_DEV
4462 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4463#endif
4464#ifdef _SC_2_UPE
4465 {"SC_2_UPE", _SC_2_UPE},
4466#endif
4467#ifdef _SC_2_VERSION
4468 {"SC_2_VERSION", _SC_2_VERSION},
4469#endif
Fred Draked86ed291999-12-15 15:34:33 +00004470#ifdef _SC_ABI_ASYNCHRONOUS_IO
4471 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4472#endif
4473#ifdef _SC_ACL
4474 {"SC_ACL", _SC_ACL},
4475#endif
Fred Drakec9680921999-12-13 16:37:25 +00004476#ifdef _SC_AIO_LISTIO_MAX
4477 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4478#endif
Fred Drakec9680921999-12-13 16:37:25 +00004479#ifdef _SC_AIO_MAX
4480 {"SC_AIO_MAX", _SC_AIO_MAX},
4481#endif
4482#ifdef _SC_AIO_PRIO_DELTA_MAX
4483 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4484#endif
4485#ifdef _SC_ARG_MAX
4486 {"SC_ARG_MAX", _SC_ARG_MAX},
4487#endif
4488#ifdef _SC_ASYNCHRONOUS_IO
4489 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4490#endif
4491#ifdef _SC_ATEXIT_MAX
4492 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4493#endif
Fred Draked86ed291999-12-15 15:34:33 +00004494#ifdef _SC_AUDIT
4495 {"SC_AUDIT", _SC_AUDIT},
4496#endif
Fred Drakec9680921999-12-13 16:37:25 +00004497#ifdef _SC_AVPHYS_PAGES
4498 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4499#endif
4500#ifdef _SC_BC_BASE_MAX
4501 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4502#endif
4503#ifdef _SC_BC_DIM_MAX
4504 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4505#endif
4506#ifdef _SC_BC_SCALE_MAX
4507 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4508#endif
4509#ifdef _SC_BC_STRING_MAX
4510 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4511#endif
Fred Draked86ed291999-12-15 15:34:33 +00004512#ifdef _SC_CAP
4513 {"SC_CAP", _SC_CAP},
4514#endif
Fred Drakec9680921999-12-13 16:37:25 +00004515#ifdef _SC_CHARCLASS_NAME_MAX
4516 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4517#endif
4518#ifdef _SC_CHAR_BIT
4519 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4520#endif
4521#ifdef _SC_CHAR_MAX
4522 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4523#endif
4524#ifdef _SC_CHAR_MIN
4525 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4526#endif
4527#ifdef _SC_CHILD_MAX
4528 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4529#endif
4530#ifdef _SC_CLK_TCK
4531 {"SC_CLK_TCK", _SC_CLK_TCK},
4532#endif
4533#ifdef _SC_COHER_BLKSZ
4534 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4535#endif
4536#ifdef _SC_COLL_WEIGHTS_MAX
4537 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4538#endif
4539#ifdef _SC_DCACHE_ASSOC
4540 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4541#endif
4542#ifdef _SC_DCACHE_BLKSZ
4543 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4544#endif
4545#ifdef _SC_DCACHE_LINESZ
4546 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4547#endif
4548#ifdef _SC_DCACHE_SZ
4549 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4550#endif
4551#ifdef _SC_DCACHE_TBLKSZ
4552 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4553#endif
4554#ifdef _SC_DELAYTIMER_MAX
4555 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4556#endif
4557#ifdef _SC_EQUIV_CLASS_MAX
4558 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4559#endif
4560#ifdef _SC_EXPR_NEST_MAX
4561 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4562#endif
4563#ifdef _SC_FSYNC
4564 {"SC_FSYNC", _SC_FSYNC},
4565#endif
4566#ifdef _SC_GETGR_R_SIZE_MAX
4567 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4568#endif
4569#ifdef _SC_GETPW_R_SIZE_MAX
4570 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4571#endif
4572#ifdef _SC_ICACHE_ASSOC
4573 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4574#endif
4575#ifdef _SC_ICACHE_BLKSZ
4576 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4577#endif
4578#ifdef _SC_ICACHE_LINESZ
4579 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4580#endif
4581#ifdef _SC_ICACHE_SZ
4582 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4583#endif
Fred Draked86ed291999-12-15 15:34:33 +00004584#ifdef _SC_INF
4585 {"SC_INF", _SC_INF},
4586#endif
Fred Drakec9680921999-12-13 16:37:25 +00004587#ifdef _SC_INT_MAX
4588 {"SC_INT_MAX", _SC_INT_MAX},
4589#endif
4590#ifdef _SC_INT_MIN
4591 {"SC_INT_MIN", _SC_INT_MIN},
4592#endif
4593#ifdef _SC_IOV_MAX
4594 {"SC_IOV_MAX", _SC_IOV_MAX},
4595#endif
Fred Draked86ed291999-12-15 15:34:33 +00004596#ifdef _SC_IP_SECOPTS
4597 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4598#endif
Fred Drakec9680921999-12-13 16:37:25 +00004599#ifdef _SC_JOB_CONTROL
4600 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4601#endif
Fred Draked86ed291999-12-15 15:34:33 +00004602#ifdef _SC_KERN_POINTERS
4603 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4604#endif
4605#ifdef _SC_KERN_SIM
4606 {"SC_KERN_SIM", _SC_KERN_SIM},
4607#endif
Fred Drakec9680921999-12-13 16:37:25 +00004608#ifdef _SC_LINE_MAX
4609 {"SC_LINE_MAX", _SC_LINE_MAX},
4610#endif
4611#ifdef _SC_LOGIN_NAME_MAX
4612 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4613#endif
4614#ifdef _SC_LOGNAME_MAX
4615 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4616#endif
4617#ifdef _SC_LONG_BIT
4618 {"SC_LONG_BIT", _SC_LONG_BIT},
4619#endif
Fred Draked86ed291999-12-15 15:34:33 +00004620#ifdef _SC_MAC
4621 {"SC_MAC", _SC_MAC},
4622#endif
Fred Drakec9680921999-12-13 16:37:25 +00004623#ifdef _SC_MAPPED_FILES
4624 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4625#endif
4626#ifdef _SC_MAXPID
4627 {"SC_MAXPID", _SC_MAXPID},
4628#endif
4629#ifdef _SC_MB_LEN_MAX
4630 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4631#endif
4632#ifdef _SC_MEMLOCK
4633 {"SC_MEMLOCK", _SC_MEMLOCK},
4634#endif
4635#ifdef _SC_MEMLOCK_RANGE
4636 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4637#endif
4638#ifdef _SC_MEMORY_PROTECTION
4639 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4640#endif
4641#ifdef _SC_MESSAGE_PASSING
4642 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4643#endif
Fred Draked86ed291999-12-15 15:34:33 +00004644#ifdef _SC_MMAP_FIXED_ALIGNMENT
4645 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4646#endif
Fred Drakec9680921999-12-13 16:37:25 +00004647#ifdef _SC_MQ_OPEN_MAX
4648 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4649#endif
4650#ifdef _SC_MQ_PRIO_MAX
4651 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4652#endif
Fred Draked86ed291999-12-15 15:34:33 +00004653#ifdef _SC_NACLS_MAX
4654 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4655#endif
Fred Drakec9680921999-12-13 16:37:25 +00004656#ifdef _SC_NGROUPS_MAX
4657 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4658#endif
4659#ifdef _SC_NL_ARGMAX
4660 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4661#endif
4662#ifdef _SC_NL_LANGMAX
4663 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4664#endif
4665#ifdef _SC_NL_MSGMAX
4666 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4667#endif
4668#ifdef _SC_NL_NMAX
4669 {"SC_NL_NMAX", _SC_NL_NMAX},
4670#endif
4671#ifdef _SC_NL_SETMAX
4672 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4673#endif
4674#ifdef _SC_NL_TEXTMAX
4675 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4676#endif
4677#ifdef _SC_NPROCESSORS_CONF
4678 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4679#endif
4680#ifdef _SC_NPROCESSORS_ONLN
4681 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4682#endif
Fred Draked86ed291999-12-15 15:34:33 +00004683#ifdef _SC_NPROC_CONF
4684 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4685#endif
4686#ifdef _SC_NPROC_ONLN
4687 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4688#endif
Fred Drakec9680921999-12-13 16:37:25 +00004689#ifdef _SC_NZERO
4690 {"SC_NZERO", _SC_NZERO},
4691#endif
4692#ifdef _SC_OPEN_MAX
4693 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4694#endif
4695#ifdef _SC_PAGESIZE
4696 {"SC_PAGESIZE", _SC_PAGESIZE},
4697#endif
4698#ifdef _SC_PAGE_SIZE
4699 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4700#endif
4701#ifdef _SC_PASS_MAX
4702 {"SC_PASS_MAX", _SC_PASS_MAX},
4703#endif
4704#ifdef _SC_PHYS_PAGES
4705 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4706#endif
4707#ifdef _SC_PII
4708 {"SC_PII", _SC_PII},
4709#endif
4710#ifdef _SC_PII_INTERNET
4711 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4712#endif
4713#ifdef _SC_PII_INTERNET_DGRAM
4714 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4715#endif
4716#ifdef _SC_PII_INTERNET_STREAM
4717 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4718#endif
4719#ifdef _SC_PII_OSI
4720 {"SC_PII_OSI", _SC_PII_OSI},
4721#endif
4722#ifdef _SC_PII_OSI_CLTS
4723 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4724#endif
4725#ifdef _SC_PII_OSI_COTS
4726 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4727#endif
4728#ifdef _SC_PII_OSI_M
4729 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4730#endif
4731#ifdef _SC_PII_SOCKET
4732 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4733#endif
4734#ifdef _SC_PII_XTI
4735 {"SC_PII_XTI", _SC_PII_XTI},
4736#endif
4737#ifdef _SC_POLL
4738 {"SC_POLL", _SC_POLL},
4739#endif
4740#ifdef _SC_PRIORITIZED_IO
4741 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4742#endif
4743#ifdef _SC_PRIORITY_SCHEDULING
4744 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4745#endif
4746#ifdef _SC_REALTIME_SIGNALS
4747 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4748#endif
4749#ifdef _SC_RE_DUP_MAX
4750 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4751#endif
4752#ifdef _SC_RTSIG_MAX
4753 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4754#endif
4755#ifdef _SC_SAVED_IDS
4756 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4757#endif
4758#ifdef _SC_SCHAR_MAX
4759 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4760#endif
4761#ifdef _SC_SCHAR_MIN
4762 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4763#endif
4764#ifdef _SC_SELECT
4765 {"SC_SELECT", _SC_SELECT},
4766#endif
4767#ifdef _SC_SEMAPHORES
4768 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4769#endif
4770#ifdef _SC_SEM_NSEMS_MAX
4771 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4772#endif
4773#ifdef _SC_SEM_VALUE_MAX
4774 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4775#endif
4776#ifdef _SC_SHARED_MEMORY_OBJECTS
4777 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4778#endif
4779#ifdef _SC_SHRT_MAX
4780 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4781#endif
4782#ifdef _SC_SHRT_MIN
4783 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4784#endif
4785#ifdef _SC_SIGQUEUE_MAX
4786 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4787#endif
4788#ifdef _SC_SIGRT_MAX
4789 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4790#endif
4791#ifdef _SC_SIGRT_MIN
4792 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4793#endif
Fred Draked86ed291999-12-15 15:34:33 +00004794#ifdef _SC_SOFTPOWER
4795 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4796#endif
Fred Drakec9680921999-12-13 16:37:25 +00004797#ifdef _SC_SPLIT_CACHE
4798 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4799#endif
4800#ifdef _SC_SSIZE_MAX
4801 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4802#endif
4803#ifdef _SC_STACK_PROT
4804 {"SC_STACK_PROT", _SC_STACK_PROT},
4805#endif
4806#ifdef _SC_STREAM_MAX
4807 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4808#endif
4809#ifdef _SC_SYNCHRONIZED_IO
4810 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4811#endif
4812#ifdef _SC_THREADS
4813 {"SC_THREADS", _SC_THREADS},
4814#endif
4815#ifdef _SC_THREAD_ATTR_STACKADDR
4816 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4817#endif
4818#ifdef _SC_THREAD_ATTR_STACKSIZE
4819 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4820#endif
4821#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4822 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4823#endif
4824#ifdef _SC_THREAD_KEYS_MAX
4825 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4826#endif
4827#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4828 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4829#endif
4830#ifdef _SC_THREAD_PRIO_INHERIT
4831 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4832#endif
4833#ifdef _SC_THREAD_PRIO_PROTECT
4834 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4835#endif
4836#ifdef _SC_THREAD_PROCESS_SHARED
4837 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4838#endif
4839#ifdef _SC_THREAD_SAFE_FUNCTIONS
4840 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4841#endif
4842#ifdef _SC_THREAD_STACK_MIN
4843 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4844#endif
4845#ifdef _SC_THREAD_THREADS_MAX
4846 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4847#endif
4848#ifdef _SC_TIMERS
4849 {"SC_TIMERS", _SC_TIMERS},
4850#endif
4851#ifdef _SC_TIMER_MAX
4852 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4853#endif
4854#ifdef _SC_TTY_NAME_MAX
4855 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4856#endif
4857#ifdef _SC_TZNAME_MAX
4858 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4859#endif
4860#ifdef _SC_T_IOV_MAX
4861 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4862#endif
4863#ifdef _SC_UCHAR_MAX
4864 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4865#endif
4866#ifdef _SC_UINT_MAX
4867 {"SC_UINT_MAX", _SC_UINT_MAX},
4868#endif
4869#ifdef _SC_UIO_MAXIOV
4870 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4871#endif
4872#ifdef _SC_ULONG_MAX
4873 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4874#endif
4875#ifdef _SC_USHRT_MAX
4876 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4877#endif
4878#ifdef _SC_VERSION
4879 {"SC_VERSION", _SC_VERSION},
4880#endif
4881#ifdef _SC_WORD_BIT
4882 {"SC_WORD_BIT", _SC_WORD_BIT},
4883#endif
4884#ifdef _SC_XBS5_ILP32_OFF32
4885 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4886#endif
4887#ifdef _SC_XBS5_ILP32_OFFBIG
4888 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4889#endif
4890#ifdef _SC_XBS5_LP64_OFF64
4891 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4892#endif
4893#ifdef _SC_XBS5_LPBIG_OFFBIG
4894 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
4895#endif
4896#ifdef _SC_XOPEN_CRYPT
4897 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
4898#endif
4899#ifdef _SC_XOPEN_ENH_I18N
4900 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
4901#endif
4902#ifdef _SC_XOPEN_LEGACY
4903 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
4904#endif
4905#ifdef _SC_XOPEN_REALTIME
4906 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
4907#endif
4908#ifdef _SC_XOPEN_REALTIME_THREADS
4909 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
4910#endif
4911#ifdef _SC_XOPEN_SHM
4912 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
4913#endif
4914#ifdef _SC_XOPEN_UNIX
4915 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
4916#endif
4917#ifdef _SC_XOPEN_VERSION
4918 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
4919#endif
4920#ifdef _SC_XOPEN_XCU_VERSION
4921 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
4922#endif
4923#ifdef _SC_XOPEN_XPG2
4924 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
4925#endif
4926#ifdef _SC_XOPEN_XPG3
4927 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
4928#endif
4929#ifdef _SC_XOPEN_XPG4
4930 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
4931#endif
4932};
4933
4934static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004935conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004936{
4937 return conv_confname(arg, valuep, posix_constants_sysconf,
4938 sizeof(posix_constants_sysconf)
4939 / sizeof(struct constdef));
4940}
4941
4942static char posix_sysconf__doc__[] = "\
4943sysconf(name) -> integer\n\
4944Return an integer-valued system configuration variable.";
4945
4946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004947posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004948{
4949 PyObject *result = NULL;
4950 int name;
4951
4952 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
4953 int value;
4954
4955 errno = 0;
4956 value = sysconf(name);
4957 if (value == -1 && errno != 0)
4958 posix_error();
4959 else
4960 result = PyInt_FromLong(value);
4961 }
4962 return result;
4963}
4964#endif
4965
4966
Fred Drakebec628d1999-12-15 18:31:10 +00004967/* This code is used to ensure that the tables of configuration value names
4968 * are in sorted order as required by conv_confname(), and also to build the
4969 * the exported dictionaries that are used to publish information about the
4970 * names available on the host platform.
4971 *
4972 * Sorting the table at runtime ensures that the table is properly ordered
4973 * when used, even for platforms we're not able to test on. It also makes
4974 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00004975 */
Fred Drakebec628d1999-12-15 18:31:10 +00004976
4977static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004978cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00004979{
4980 const struct constdef *c1 =
4981 (const struct constdef *) v1;
4982 const struct constdef *c2 =
4983 (const struct constdef *) v2;
4984
4985 return strcmp(c1->name, c2->name);
4986}
4987
4988static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004989setup_confname_table(struct constdef *table, size_t tablesize,
4990 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00004991{
Fred Drakebec628d1999-12-15 18:31:10 +00004992 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00004993 size_t i;
4994 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00004995
4996 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
4997 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00004998 if (d == NULL)
4999 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005000
Barry Warsaw3155db32000-04-13 15:20:40 +00005001 for (i=0; i < tablesize; ++i) {
5002 PyObject *o = PyInt_FromLong(table[i].value);
5003 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5004 Py_XDECREF(o);
5005 Py_DECREF(d);
5006 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005007 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005008 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005009 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005010 status = PyDict_SetItemString(moddict, tablename, d);
5011 Py_DECREF(d);
5012 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005013}
5014
Fred Drakebec628d1999-12-15 18:31:10 +00005015/* Return -1 on failure, 0 on success. */
5016static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005017setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005018{
5019#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005020 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005021 sizeof(posix_constants_pathconf)
5022 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005023 "pathconf_names", moddict))
5024 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005025#endif
5026#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005027 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005028 sizeof(posix_constants_confstr)
5029 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005030 "confstr_names", moddict))
5031 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005032#endif
5033#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005034 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005035 sizeof(posix_constants_sysconf)
5036 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005037 "sysconf_names", moddict))
5038 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005039#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005040 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005041}
Fred Draked86ed291999-12-15 15:34:33 +00005042
5043
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005044static char posix_abort__doc__[] = "\
5045abort() -> does not return!\n\
5046Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5047in the hardest way possible on the hosting operating system.";
5048
5049static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005050posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005051{
5052 if (!PyArg_ParseTuple(args, ":abort"))
5053 return NULL;
5054 abort();
5055 /*NOTREACHED*/
5056 Py_FatalError("abort() called from Python code didn't abort!");
5057 return NULL;
5058}
Fred Drakebec628d1999-12-15 18:31:10 +00005059
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005060
5061static PyMethodDef posix_methods[] = {
5062 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5063#ifdef HAVE_TTYNAME
5064 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5065#endif
5066 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5067 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005068#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005069 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005070#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005071#ifdef HAVE_CTERMID
5072 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5073#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005074#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005075 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005076#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005077#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005078 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005079#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005080 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5081 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5082 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005083#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005084 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005085#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005086#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005087 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005088#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005089 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5090 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5091 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005092#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005093 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005094#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005095#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005096 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005097#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005098 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005099#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005100 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005101#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005102 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5103 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5104 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005105#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005106 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005107#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005108 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005109#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005110 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5111 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005112#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005113#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005114 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5115 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005116#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005117#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005118 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005119#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005120#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005121 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005122#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005123#ifdef HAVE_FORKPTY
5124 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5125#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005126#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005127 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005128#endif /* HAVE_GETEGID */
5129#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005130 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005131#endif /* HAVE_GETEUID */
5132#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005133 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005134#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005135#ifdef HAVE_GETGROUPS
5136 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5137#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005138 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005139#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005140 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005141#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005142#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005143 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005144#endif /* HAVE_GETPPID */
5145#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005146 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005147#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005148#ifdef HAVE_GETLOGIN
5149 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5150#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005151#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005152 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005153#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005154#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005155 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005156#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005157#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005158 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005159#ifdef MS_WIN32
5160 {"popen2", win32_popen2, METH_VARARGS},
5161 {"popen3", win32_popen3, METH_VARARGS},
5162 {"popen4", win32_popen4, METH_VARARGS},
5163#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005164#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005165#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005166 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005167#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005168#ifdef HAVE_SETEUID
5169 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5170#endif /* HAVE_SETEUID */
5171#ifdef HAVE_SETEGID
5172 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5173#endif /* HAVE_SETEGID */
5174#ifdef HAVE_SETREUID
5175 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5176#endif /* HAVE_SETREUID */
5177#ifdef HAVE_SETREGID
5178 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5179#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005180#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005181 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005182#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005183#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005184 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005185#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005186#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005187 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005188#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005189#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005190 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005191#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005192#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005193 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005194#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005195#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005196 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005197#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005198#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005199 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005200#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005201#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005202 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005203#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005204 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5205 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5206 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5207 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5208 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5209 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5210 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5211 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5212 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005213 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005214#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005215 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005216#endif
5217#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005218 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005219#endif
5220#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005221 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005222#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005223#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005224 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005225#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005226#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005227 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005228#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005229#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005230 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005231#endif
5232#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005233 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005234#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005235#ifdef HAVE_SYS_WAIT_H
5236#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005237 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005238#endif /* WIFSTOPPED */
5239#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005240 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005241#endif /* WIFSIGNALED */
5242#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005243 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005244#endif /* WIFEXITED */
5245#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005246 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005247#endif /* WEXITSTATUS */
5248#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005249 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005250#endif /* WTERMSIG */
5251#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005252 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005253#endif /* WSTOPSIG */
5254#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005255#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005256 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005257#endif
5258#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005259 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005260#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005261#ifdef HAVE_TMPNAM
5262 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5263#endif
5264#ifdef HAVE_TEMPNAM
5265 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5266#endif
5267#ifdef HAVE_TMPNAM
5268 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5269#endif
Fred Drakec9680921999-12-13 16:37:25 +00005270#ifdef HAVE_CONFSTR
5271 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5272#endif
5273#ifdef HAVE_SYSCONF
5274 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5275#endif
5276#ifdef HAVE_FPATHCONF
5277 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5278#endif
5279#ifdef HAVE_PATHCONF
5280 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5281#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005282 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005283 {NULL, NULL} /* Sentinel */
5284};
5285
5286
Barry Warsaw4a342091996-12-19 23:50:02 +00005287static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005288ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005289{
5290 PyObject* v = PyInt_FromLong(value);
5291 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5292 return -1; /* triggers fatal error */
5293
5294 Py_DECREF(v);
5295 return 0;
5296}
5297
Guido van Rossumd48f2521997-12-05 22:19:34 +00005298#if defined(PYOS_OS2)
5299/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5300static int insertvalues(PyObject *d)
5301{
5302 APIRET rc;
5303 ULONG values[QSV_MAX+1];
5304 PyObject *v;
5305 char *ver, tmp[10];
5306
5307 Py_BEGIN_ALLOW_THREADS
5308 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5309 Py_END_ALLOW_THREADS
5310
5311 if (rc != NO_ERROR) {
5312 os2_error(rc);
5313 return -1;
5314 }
5315
5316 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5317 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5318 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5319 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5320 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5321 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5322 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5323
5324 switch (values[QSV_VERSION_MINOR]) {
5325 case 0: ver = "2.00"; break;
5326 case 10: ver = "2.10"; break;
5327 case 11: ver = "2.11"; break;
5328 case 30: ver = "3.00"; break;
5329 case 40: ver = "4.00"; break;
5330 case 50: ver = "5.00"; break;
5331 default:
5332 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5333 values[QSV_VERSION_MINOR]);
5334 ver = &tmp[0];
5335 }
5336
5337 /* Add Indicator of the Version of the Operating System */
5338 v = PyString_FromString(ver);
5339 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5340 return -1;
5341 Py_DECREF(v);
5342
5343 /* Add Indicator of Which Drive was Used to Boot the System */
5344 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5345 tmp[1] = ':';
5346 tmp[2] = '\0';
5347
5348 v = PyString_FromString(tmp);
5349 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5350 return -1;
5351 Py_DECREF(v);
5352
5353 return 0;
5354}
5355#endif
5356
Barry Warsaw4a342091996-12-19 23:50:02 +00005357static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005358all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005359{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005360#ifdef F_OK
5361 if (ins(d, "F_OK", (long)F_OK)) return -1;
5362#endif
5363#ifdef R_OK
5364 if (ins(d, "R_OK", (long)R_OK)) return -1;
5365#endif
5366#ifdef W_OK
5367 if (ins(d, "W_OK", (long)W_OK)) return -1;
5368#endif
5369#ifdef X_OK
5370 if (ins(d, "X_OK", (long)X_OK)) return -1;
5371#endif
Fred Drakec9680921999-12-13 16:37:25 +00005372#ifdef NGROUPS_MAX
5373 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5374#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005375#ifdef TMP_MAX
5376 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5377#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005378#ifdef WNOHANG
5379 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5380#endif
5381#ifdef O_RDONLY
5382 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5383#endif
5384#ifdef O_WRONLY
5385 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5386#endif
5387#ifdef O_RDWR
5388 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5389#endif
5390#ifdef O_NDELAY
5391 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5392#endif
5393#ifdef O_NONBLOCK
5394 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5395#endif
5396#ifdef O_APPEND
5397 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5398#endif
5399#ifdef O_DSYNC
5400 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5401#endif
5402#ifdef O_RSYNC
5403 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5404#endif
5405#ifdef O_SYNC
5406 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5407#endif
5408#ifdef O_NOCTTY
5409 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5410#endif
5411#ifdef O_CREAT
5412 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5413#endif
5414#ifdef O_EXCL
5415 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5416#endif
5417#ifdef O_TRUNC
5418 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5419#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005420#ifdef O_BINARY
5421 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5422#endif
5423#ifdef O_TEXT
5424 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5425#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005426
Guido van Rossum246bc171999-02-01 23:54:31 +00005427#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005428 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5429 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5430 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5431 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5432 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005433#endif
5434
Guido van Rossumd48f2521997-12-05 22:19:34 +00005435#if defined(PYOS_OS2)
5436 if (insertvalues(d)) return -1;
5437#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005438 return 0;
5439}
5440
5441
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005442#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005443#define INITFUNC initnt
5444#define MODNAME "nt"
5445#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005446#if defined(PYOS_OS2)
5447#define INITFUNC initos2
5448#define MODNAME "os2"
5449#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005450#define INITFUNC initposix
5451#define MODNAME "posix"
5452#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005453#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005454
Guido van Rossum3886bb61998-12-04 18:50:17 +00005455DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005456INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005457{
Barry Warsaw53699e91996-12-10 23:23:01 +00005458 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005459
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005460 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005461 posix_methods,
5462 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005463 (PyObject *)NULL,
5464 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005465 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005466
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005467 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005468 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005469 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005470 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005471 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005472
Barry Warsaw4a342091996-12-19 23:50:02 +00005473 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005474 return;
5475
Fred Drakebec628d1999-12-15 18:31:10 +00005476 if (setup_confname_tables(d))
5477 return;
5478
Barry Warsawca74da41999-02-09 19:31:45 +00005479 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005480
Guido van Rossumb3d39562000-01-31 18:41:26 +00005481#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00005482 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005483#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005484}