This commit was manufactured by cvs2svn to create tag 'r212c1'.
[python/dscho.git] / Modules / posixmodule.c
blob1733d870ce3d67f66ec52c82a30483b7f345131a
2 /* POSIX module implementation */
4 /* This file is also used for Windows NT and MS-Win. In that case the module
5 actually calls itself 'nt', not 'posix', and a few functions are
6 either unimplemented or implemented differently. The source
7 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
8 of the compiler used. Different compilers define their own feature
9 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
11 /* See also ../Dos/dosmodule.c */
13 static char posix__doc__ [] =
14 "This module provides access to operating system functionality that is\n\
15 standardized by the C Standard and the POSIX standard (a thinly\n\
16 disguised Unix interface). Refer to the library manual and\n\
17 corresponding Unix manual entries for more information on calls.";
19 #include "Python.h"
21 #if defined(PYOS_OS2)
22 #define INCL_DOS
23 #define INCL_DOSERRORS
24 #define INCL_DOSPROCESS
25 #define INCL_NOPMAPI
26 #include <os2.h>
27 #endif
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #ifdef HAVE_SYS_WAIT_H
32 #include <sys/wait.h> /* For WNOHANG */
33 #endif
35 #ifdef HAVE_SIGNAL_H
36 #include <signal.h>
37 #endif
39 #ifdef HAVE_FCNTL_H
40 #include <fcntl.h>
41 #endif /* HAVE_FCNTL_H */
43 /* pick up declaration of confstr on some systems? */
44 #ifdef HAVE_UNISTD_H
45 #include <unistd.h>
46 #endif /* HAVE_UNISTD_H */
48 /* Various compilers have only certain posix functions */
49 /* XXX Gosh I wish these were all moved into config.h */
50 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
51 #include <process.h>
52 #else
53 #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
54 #define HAVE_GETCWD 1
55 #define HAVE_OPENDIR 1
56 #define HAVE_SYSTEM 1
57 #if defined(__OS2__)
58 #define HAVE_EXECV 1
59 #define HAVE_WAIT 1
60 #endif
61 #include <process.h>
62 #else
63 #ifdef __BORLANDC__ /* Borland compiler */
64 #define HAVE_EXECV 1
65 #define HAVE_GETCWD 1
66 #define HAVE_OPENDIR 1
67 #define HAVE_PIPE 1
68 #define HAVE_POPEN 1
69 #define HAVE_SYSTEM 1
70 #define HAVE_WAIT 1
71 #else
72 #ifdef _MSC_VER /* Microsoft compiler */
73 #define HAVE_GETCWD 1
74 #ifdef MS_WIN32
75 #define HAVE_SPAWNV 1
76 #define HAVE_EXECV 1
77 #define HAVE_PIPE 1
78 #define HAVE_POPEN 1
79 #define HAVE_SYSTEM 1
80 #else /* 16-bit Windows */
81 #endif /* !MS_WIN32 */
82 #else /* all other compilers */
83 /* Unix functions that the configure script doesn't check for */
84 #define HAVE_EXECV 1
85 #define HAVE_FORK 1
86 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
87 #define HAVE_FORK1 1
88 #endif
89 #define HAVE_GETCWD 1
90 #define HAVE_GETEGID 1
91 #define HAVE_GETEUID 1
92 #define HAVE_GETGID 1
93 #define HAVE_GETPPID 1
94 #define HAVE_GETUID 1
95 #define HAVE_KILL 1
96 #define HAVE_OPENDIR 1
97 #define HAVE_PIPE 1
98 #define HAVE_POPEN 1
99 #define HAVE_SYSTEM 1
100 #define HAVE_WAIT 1
101 #define HAVE_TTYNAME 1
102 #endif /* _MSC_VER */
103 #endif /* __BORLANDC__ */
104 #endif /* ! __WATCOMC__ || __QNX__ */
105 #endif /* ! __IBMC__ */
107 #ifndef _MSC_VER
109 #ifdef HAVE_UNISTD_H
110 #include <unistd.h>
111 #endif
113 #if defined(sun) && !defined(__SVR4)
114 /* SunOS 4.1.4 doesn't have prototypes for these: */
115 extern int rename(const char *, const char *);
116 extern int pclose(FILE *);
117 extern int fclose(FILE *);
118 extern int fsync(int);
119 extern int lstat(const char *, struct stat *);
120 extern int symlink(const char *, const char *);
121 #endif
123 #ifdef NeXT
124 /* NeXT's <unistd.h> and <utime.h> aren't worth much */
125 #undef HAVE_UNISTD_H
126 #undef HAVE_UTIME_H
127 #define HAVE_WAITPID
128 /* #undef HAVE_GETCWD */
129 #define UNION_WAIT /* This should really be checked for by autoconf */
130 #endif
132 #ifndef HAVE_UNISTD_H
133 #if defined(PYCC_VACPP)
134 extern int mkdir(char *);
135 #else
136 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
137 extern int mkdir(const char *);
138 #else
139 extern int mkdir(const char *, mode_t);
140 #endif
141 #endif
142 #if defined(__IBMC__) || defined(__IBMCPP__)
143 extern int chdir(char *);
144 extern int rmdir(char *);
145 #else
146 extern int chdir(const char *);
147 extern int rmdir(const char *);
148 #endif
149 #ifdef __BORLANDC__
150 extern int chmod(const char *, int);
151 #else
152 extern int chmod(const char *, mode_t);
153 #endif
154 extern int chown(const char *, uid_t, gid_t);
155 extern char *getcwd(char *, int);
156 extern char *strerror(int);
157 extern int link(const char *, const char *);
158 extern int rename(const char *, const char *);
159 extern int stat(const char *, struct stat *);
160 extern int unlink(const char *);
161 extern int pclose(FILE *);
162 #ifdef HAVE_SYMLINK
163 extern int symlink(const char *, const char *);
164 #endif /* HAVE_SYMLINK */
165 #ifdef HAVE_LSTAT
166 extern int lstat(const char *, struct stat *);
167 #endif /* HAVE_LSTAT */
168 #endif /* !HAVE_UNISTD_H */
170 #endif /* !_MSC_VER */
172 #ifdef HAVE_UTIME_H
173 #include <utime.h>
174 #endif /* HAVE_UTIME_H */
176 #ifdef HAVE_SYS_UTIME_H
177 #include <sys/utime.h>
178 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
179 #endif /* HAVE_SYS_UTIME_H */
181 #ifdef HAVE_SYS_TIMES_H
182 #include <sys/times.h>
183 #endif /* HAVE_SYS_TIMES_H */
185 #ifdef HAVE_SYS_PARAM_H
186 #include <sys/param.h>
187 #endif /* HAVE_SYS_PARAM_H */
189 #ifdef HAVE_SYS_UTSNAME_H
190 #include <sys/utsname.h>
191 #endif /* HAVE_SYS_UTSNAME_H */
193 #ifndef MAXPATHLEN
194 #define MAXPATHLEN 1024
195 #endif /* MAXPATHLEN */
197 #ifdef HAVE_DIRENT_H
198 #include <dirent.h>
199 #define NAMLEN(dirent) strlen((dirent)->d_name)
200 #else
201 #if defined(__WATCOMC__) && !defined(__QNX__)
202 #include <direct.h>
203 #define NAMLEN(dirent) strlen((dirent)->d_name)
204 #else
205 #define dirent direct
206 #define NAMLEN(dirent) (dirent)->d_namlen
207 #endif
208 #ifdef HAVE_SYS_NDIR_H
209 #include <sys/ndir.h>
210 #endif
211 #ifdef HAVE_SYS_DIR_H
212 #include <sys/dir.h>
213 #endif
214 #ifdef HAVE_NDIR_H
215 #include <ndir.h>
216 #endif
217 #endif
219 #ifdef _MSC_VER
220 #include <direct.h>
221 #include <io.h>
222 #include <process.h>
223 #define WINDOWS_LEAN_AND_MEAN
224 #include <windows.h>
225 #ifdef MS_WIN32
226 #define popen _popen
227 #define pclose _pclose
228 #else /* 16-bit Windows */
229 #include <dos.h>
230 #include <ctype.h>
231 #endif /* MS_WIN32 */
232 #endif /* _MSC_VER */
234 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
235 #include <io.h>
236 #endif /* OS2 */
238 #ifdef UNION_WAIT
239 /* Emulate some macros on systems that have a union instead of macros */
241 #ifndef WIFEXITED
242 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
243 #endif
245 #ifndef WEXITSTATUS
246 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
247 #endif
249 #ifndef WTERMSIG
250 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
251 #endif
253 #endif /* UNION_WAIT */
255 /* Don't use the "_r" form if we don't need it (also, won't have a
256 prototype for it, at least on Solaris -- maybe others as well?). */
257 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
258 #define USE_CTERMID_R
259 #endif
261 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
262 #define USE_TMPNAM_R
263 #endif
265 /* choose the appropriate stat and fstat functions and return structs */
266 #undef STAT
267 #ifdef MS_WIN64
268 # define STAT _stati64
269 # define FSTAT _fstati64
270 # define STRUCT_STAT struct _stati64
271 #else
272 # define STAT stat
273 # define FSTAT fstat
274 # define STRUCT_STAT struct stat
275 #endif
278 /* Return a dictionary corresponding to the POSIX environment table */
280 #if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
281 extern char **environ;
282 #endif /* !_MSC_VER */
284 static PyObject *
285 convertenviron(void)
287 PyObject *d;
288 char **e;
289 d = PyDict_New();
290 if (d == NULL)
291 return NULL;
292 if (environ == NULL)
293 return d;
294 /* This part ignores errors */
295 for (e = environ; *e != NULL; e++) {
296 PyObject *k;
297 PyObject *v;
298 char *p = strchr(*e, '=');
299 if (p == NULL)
300 continue;
301 k = PyString_FromStringAndSize(*e, (int)(p-*e));
302 if (k == NULL) {
303 PyErr_Clear();
304 continue;
306 v = PyString_FromString(p+1);
307 if (v == NULL) {
308 PyErr_Clear();
309 Py_DECREF(k);
310 continue;
312 if (PyDict_GetItem(d, k) == NULL) {
313 if (PyDict_SetItem(d, k, v) != 0)
314 PyErr_Clear();
316 Py_DECREF(k);
317 Py_DECREF(v);
319 #if defined(PYOS_OS2)
321 APIRET rc;
322 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
324 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
325 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
326 PyObject *v = PyString_FromString(buffer);
327 PyDict_SetItemString(d, "BEGINLIBPATH", v);
328 Py_DECREF(v);
330 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
331 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
332 PyObject *v = PyString_FromString(buffer);
333 PyDict_SetItemString(d, "ENDLIBPATH", v);
334 Py_DECREF(v);
337 #endif
338 return d;
342 /* Set a POSIX-specific error from errno, and return NULL */
344 static PyObject *
345 posix_error(void)
347 return PyErr_SetFromErrno(PyExc_OSError);
349 static PyObject *
350 posix_error_with_filename(char* name)
352 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
355 #ifdef MS_WIN32
356 static PyObject *
357 win32_error(char* function, char* filename)
359 /* XXX We should pass the function name along in the future.
360 (_winreg.c also wants to pass the function name.)
361 This would however require an additional param to the
362 Windows error object, which is non-trivial.
364 errno = GetLastError();
365 if (filename)
366 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
367 else
368 return PyErr_SetFromWindowsErr(errno);
370 #endif
372 #if defined(PYOS_OS2)
373 /**********************************************************************
374 * Helper Function to Trim and Format OS/2 Messages
375 **********************************************************************/
376 static void
377 os2_formatmsg(char *msgbuf, int msglen, char *reason)
379 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
381 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
382 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
384 while (lastc > msgbuf && isspace(*lastc))
385 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
388 /* Add Optional Reason Text */
389 if (reason) {
390 strcat(msgbuf, " : ");
391 strcat(msgbuf, reason);
395 /**********************************************************************
396 * Decode an OS/2 Operating System Error Code
398 * A convenience function to lookup an OS/2 error code and return a
399 * text message we can use to raise a Python exception.
401 * Notes:
402 * The messages for errors returned from the OS/2 kernel reside in
403 * the file OSO001.MSG in the \OS2 directory hierarchy.
405 **********************************************************************/
406 static char *
407 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
409 APIRET rc;
410 ULONG msglen;
412 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
413 Py_BEGIN_ALLOW_THREADS
414 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
415 errorcode, "oso001.msg", &msglen);
416 Py_END_ALLOW_THREADS
418 if (rc == NO_ERROR)
419 os2_formatmsg(msgbuf, msglen, reason);
420 else
421 sprintf(msgbuf, "unknown OS error #%d", errorcode);
423 return msgbuf;
426 /* Set an OS/2-specific error and return NULL. OS/2 kernel
427 errors are not in a global variable e.g. 'errno' nor are
428 they congruent with posix error numbers. */
430 static PyObject * os2_error(int code)
432 char text[1024];
433 PyObject *v;
435 os2_strerror(text, sizeof(text), code, "");
437 v = Py_BuildValue("(is)", code, text);
438 if (v != NULL) {
439 PyErr_SetObject(PyExc_OSError, v);
440 Py_DECREF(v);
442 return NULL; /* Signal to Python that an Exception is Pending */
445 #endif /* OS2 */
447 /* POSIX generic methods */
449 static PyObject *
450 posix_int(PyObject *args, char *format, int (*func)(int))
452 int fd;
453 int res;
454 if (!PyArg_ParseTuple(args, format, &fd))
455 return NULL;
456 Py_BEGIN_ALLOW_THREADS
457 res = (*func)(fd);
458 Py_END_ALLOW_THREADS
459 if (res < 0)
460 return posix_error();
461 Py_INCREF(Py_None);
462 return Py_None;
466 static PyObject *
467 posix_1str(PyObject *args, char *format, int (*func)(const char*))
469 char *path1;
470 int res;
471 if (!PyArg_ParseTuple(args, format, &path1))
472 return NULL;
473 Py_BEGIN_ALLOW_THREADS
474 res = (*func)(path1);
475 Py_END_ALLOW_THREADS
476 if (res < 0)
477 return posix_error_with_filename(path1);
478 Py_INCREF(Py_None);
479 return Py_None;
482 static PyObject *
483 posix_2str(PyObject *args, char *format,
484 int (*func)(const char *, const char *))
486 char *path1, *path2;
487 int res;
488 if (!PyArg_ParseTuple(args, format, &path1, &path2))
489 return NULL;
490 Py_BEGIN_ALLOW_THREADS
491 res = (*func)(path1, path2);
492 Py_END_ALLOW_THREADS
493 if (res != 0)
494 /* XXX how to report both path1 and path2??? */
495 return posix_error();
496 Py_INCREF(Py_None);
497 return Py_None;
500 /* pack a system stat C structure into the Python stat tuple
501 (used by posix_stat() and posix_fstat()) */
502 static PyObject*
503 _pystat_fromstructstat(STRUCT_STAT st)
505 PyObject *v = PyTuple_New(10);
506 if (v == NULL)
507 return NULL;
509 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
510 #ifdef HAVE_LARGEFILE_SUPPORT
511 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
512 #else
513 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
514 #endif
515 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
516 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
517 #else
518 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
519 #endif
520 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
521 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
522 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
523 #ifdef HAVE_LARGEFILE_SUPPORT
524 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
525 #else
526 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
527 #endif
528 #if SIZEOF_TIME_T > SIZEOF_LONG
529 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
530 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
531 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
532 #else
533 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
534 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
535 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
536 #endif
538 if (PyErr_Occurred()) {
539 Py_DECREF(v);
540 return NULL;
543 return v;
547 static PyObject *
548 posix_do_stat(PyObject *self, PyObject *args, char *format,
549 int (*statfunc)(const char *, STRUCT_STAT *))
551 STRUCT_STAT st;
552 char *path;
553 int res;
555 #ifdef MS_WIN32
556 int pathlen;
557 char pathcopy[MAX_PATH];
558 #endif /* MS_WIN32 */
560 if (!PyArg_ParseTuple(args, format, &path))
561 return NULL;
563 #ifdef MS_WIN32
564 pathlen = strlen(path);
565 /* the library call can blow up if the file name is too long! */
566 if (pathlen > MAX_PATH) {
567 errno = ENAMETOOLONG;
568 return posix_error();
571 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
572 /* exception for specific or current drive root */
573 if (!((pathlen == 1) ||
574 ((pathlen == 3) &&
575 (path[1] == ':') &&
576 (path[2] == '\\' || path[2] == '/'))))
578 strncpy(pathcopy, path, pathlen);
579 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
580 path = pathcopy;
583 #endif /* MS_WIN32 */
585 Py_BEGIN_ALLOW_THREADS
586 res = (*statfunc)(path, &st);
587 Py_END_ALLOW_THREADS
588 if (res != 0)
589 return posix_error_with_filename(path);
591 return _pystat_fromstructstat(st);
595 /* POSIX methods */
597 static char posix_access__doc__[] =
598 "access(path, mode) -> 1 if granted, 0 otherwise\n\
599 Test for access to a file.";
601 static PyObject *
602 posix_access(PyObject *self, PyObject *args)
604 char *path;
605 int mode;
606 int res;
608 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
609 return NULL;
610 Py_BEGIN_ALLOW_THREADS
611 res = access(path, mode);
612 Py_END_ALLOW_THREADS
613 return(PyInt_FromLong(res == 0 ? 1L : 0L));
616 #ifndef F_OK
617 #define F_OK 0
618 #endif
619 #ifndef R_OK
620 #define R_OK 4
621 #endif
622 #ifndef W_OK
623 #define W_OK 2
624 #endif
625 #ifndef X_OK
626 #define X_OK 1
627 #endif
629 #ifdef HAVE_TTYNAME
630 static char posix_ttyname__doc__[] =
631 "ttyname(fd) -> String\n\
632 Return the name of the terminal device connected to 'fd'.";
634 static PyObject *
635 posix_ttyname(PyObject *self, PyObject *args)
637 int id;
638 char *ret;
640 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
641 return NULL;
643 ret = ttyname(id);
644 if (ret == NULL)
645 return(posix_error());
646 return(PyString_FromString(ret));
648 #endif
650 #ifdef HAVE_CTERMID
651 static char posix_ctermid__doc__[] =
652 "ctermid() -> String\n\
653 Return the name of the controlling terminal for this process.";
655 static PyObject *
656 posix_ctermid(PyObject *self, PyObject *args)
658 char *ret;
659 char buffer[L_ctermid];
661 if (!PyArg_ParseTuple(args, ":ctermid"))
662 return NULL;
664 #ifdef USE_CTERMID_R
665 ret = ctermid_r(buffer);
666 #else
667 ret = ctermid(buffer);
668 #endif
669 if (ret == NULL)
670 return(posix_error());
671 return(PyString_FromString(buffer));
673 #endif
675 static char posix_chdir__doc__[] =
676 "chdir(path) -> None\n\
677 Change the current working directory to the specified path.";
679 static PyObject *
680 posix_chdir(PyObject *self, PyObject *args)
682 return posix_1str(args, "s:chdir", chdir);
686 static char posix_chmod__doc__[] =
687 "chmod(path, mode) -> None\n\
688 Change the access permissions of a file.";
690 static PyObject *
691 posix_chmod(PyObject *self, PyObject *args)
693 char *path;
694 int i;
695 int res;
696 if (!PyArg_ParseTuple(args, "si", &path, &i))
697 return NULL;
698 Py_BEGIN_ALLOW_THREADS
699 res = chmod(path, i);
700 Py_END_ALLOW_THREADS
701 if (res < 0)
702 return posix_error_with_filename(path);
703 Py_INCREF(Py_None);
704 return Py_None;
708 #ifdef HAVE_FSYNC
709 static char posix_fsync__doc__[] =
710 "fsync(fildes) -> None\n\
711 force write of file with filedescriptor to disk.";
713 static PyObject *
714 posix_fsync(PyObject *self, PyObject *args)
716 return posix_int(args, "i:fsync", fsync);
718 #endif /* HAVE_FSYNC */
720 #ifdef HAVE_FDATASYNC
722 #ifdef __hpux
723 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
724 #endif
726 static char posix_fdatasync__doc__[] =
727 "fdatasync(fildes) -> None\n\
728 force write of file with filedescriptor to disk.\n\
729 does not force update of metadata.";
731 static PyObject *
732 posix_fdatasync(PyObject *self, PyObject *args)
734 return posix_int(args, "i:fdatasync", fdatasync);
736 #endif /* HAVE_FDATASYNC */
739 #ifdef HAVE_CHOWN
740 static char posix_chown__doc__[] =
741 "chown(path, uid, gid) -> None\n\
742 Change the owner and group id of path to the numeric uid and gid.";
744 static PyObject *
745 posix_chown(PyObject *self, PyObject *args)
747 char *path;
748 int uid, gid;
749 int res;
750 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
751 return NULL;
752 Py_BEGIN_ALLOW_THREADS
753 res = chown(path, (uid_t) uid, (gid_t) gid);
754 Py_END_ALLOW_THREADS
755 if (res < 0)
756 return posix_error_with_filename(path);
757 Py_INCREF(Py_None);
758 return Py_None;
760 #endif /* HAVE_CHOWN */
763 #ifdef HAVE_GETCWD
764 static char posix_getcwd__doc__[] =
765 "getcwd() -> path\n\
766 Return a string representing the current working directory.";
768 static PyObject *
769 posix_getcwd(PyObject *self, PyObject *args)
771 char buf[1026];
772 char *res;
773 if (!PyArg_ParseTuple(args, ":getcwd"))
774 return NULL;
775 Py_BEGIN_ALLOW_THREADS
776 res = getcwd(buf, sizeof buf);
777 Py_END_ALLOW_THREADS
778 if (res == NULL)
779 return posix_error();
780 return PyString_FromString(buf);
782 #endif
785 #ifdef HAVE_LINK
786 static char posix_link__doc__[] =
787 "link(src, dst) -> None\n\
788 Create a hard link to a file.";
790 static PyObject *
791 posix_link(PyObject *self, PyObject *args)
793 return posix_2str(args, "ss:link", link);
795 #endif /* HAVE_LINK */
798 static char posix_listdir__doc__[] =
799 "listdir(path) -> list_of_strings\n\
800 Return a list containing the names of the entries in the directory.\n\
802 path: path of directory to list\n\
804 The list is in arbitrary order. It does not include the special\n\
805 entries '.' and '..' even if they are present in the directory.";
807 static PyObject *
808 posix_listdir(PyObject *self, PyObject *args)
810 /* XXX Should redo this putting the (now four) versions of opendir
811 in separate files instead of having them all here... */
812 #if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
814 char *name;
815 int len;
816 PyObject *d, *v;
817 HANDLE hFindFile;
818 WIN32_FIND_DATA FileData;
819 char namebuf[MAX_PATH+5];
820 char ch;
822 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
823 return NULL;
824 if (len >= MAX_PATH) {
825 PyErr_SetString(PyExc_ValueError, "path too long");
826 return NULL;
828 strcpy(namebuf, name);
829 ch = namebuf[len-1];
830 if (ch != '/' && ch != '\\' && ch != ':')
831 namebuf[len++] = '/';
832 strcpy(namebuf + len, "*.*");
834 if ((d = PyList_New(0)) == NULL)
835 return NULL;
837 hFindFile = FindFirstFile(namebuf, &FileData);
838 if (hFindFile == INVALID_HANDLE_VALUE) {
839 errno = GetLastError();
840 if (errno == ERROR_FILE_NOT_FOUND)
841 return PyList_New(0);
842 return win32_error("FindFirstFile", name);
844 do {
845 if (FileData.cFileName[0] == '.' &&
846 (FileData.cFileName[1] == '\0' ||
847 FileData.cFileName[1] == '.' &&
848 FileData.cFileName[2] == '\0'))
849 continue;
850 v = PyString_FromString(FileData.cFileName);
851 if (v == NULL) {
852 Py_DECREF(d);
853 d = NULL;
854 break;
856 if (PyList_Append(d, v) != 0) {
857 Py_DECREF(v);
858 Py_DECREF(d);
859 d = NULL;
860 break;
862 Py_DECREF(v);
863 } while (FindNextFile(hFindFile, &FileData) == TRUE);
865 if (FindClose(hFindFile) == FALSE)
866 return win32_error("FindClose", name);
868 return d;
870 #elif defined(_MSC_VER) /* 16-bit Windows */
872 #ifndef MAX_PATH
873 #define MAX_PATH 250
874 #endif
875 char *name, *pt;
876 int len;
877 PyObject *d, *v;
878 char namebuf[MAX_PATH+5];
879 struct _find_t ep;
881 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
882 return NULL;
883 if (len >= MAX_PATH) {
884 PyErr_SetString(PyExc_ValueError, "path too long");
885 return NULL;
887 strcpy(namebuf, name);
888 for (pt = namebuf; *pt; pt++)
889 if (*pt == '/')
890 *pt = '\\';
891 if (namebuf[len-1] != '\\')
892 namebuf[len++] = '\\';
893 strcpy(namebuf + len, "*.*");
895 if ((d = PyList_New(0)) == NULL)
896 return NULL;
898 if (_dos_findfirst(namebuf, _A_RDONLY |
899 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
901 errno = ENOENT;
902 return posix_error_with_filename(name);
904 do {
905 if (ep.name[0] == '.' &&
906 (ep.name[1] == '\0' ||
907 ep.name[1] == '.' &&
908 ep.name[2] == '\0'))
909 continue;
910 strcpy(namebuf, ep.name);
911 for (pt = namebuf; *pt; pt++)
912 if (isupper(*pt))
913 *pt = tolower(*pt);
914 v = PyString_FromString(namebuf);
915 if (v == NULL) {
916 Py_DECREF(d);
917 d = NULL;
918 break;
920 if (PyList_Append(d, v) != 0) {
921 Py_DECREF(v);
922 Py_DECREF(d);
923 d = NULL;
924 break;
926 Py_DECREF(v);
927 } while (_dos_findnext(&ep) == 0);
929 return d;
931 #elif defined(PYOS_OS2)
933 #ifndef MAX_PATH
934 #define MAX_PATH CCHMAXPATH
935 #endif
936 char *name, *pt;
937 int len;
938 PyObject *d, *v;
939 char namebuf[MAX_PATH+5];
940 HDIR hdir = 1;
941 ULONG srchcnt = 1;
942 FILEFINDBUF3 ep;
943 APIRET rc;
945 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
946 return NULL;
947 if (len >= MAX_PATH) {
948 PyErr_SetString(PyExc_ValueError, "path too long");
949 return NULL;
951 strcpy(namebuf, name);
952 for (pt = namebuf; *pt; pt++)
953 if (*pt == '/')
954 *pt = '\\';
955 if (namebuf[len-1] != '\\')
956 namebuf[len++] = '\\';
957 strcpy(namebuf + len, "*.*");
959 if ((d = PyList_New(0)) == NULL)
960 return NULL;
962 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
963 &hdir, /* Handle to Use While Search Directory */
964 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
965 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
966 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
967 FIL_STANDARD); /* Format of Entry (EAs or Not) */
969 if (rc != NO_ERROR) {
970 errno = ENOENT;
971 return posix_error_with_filename(name);
974 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
975 do {
976 if (ep.achName[0] == '.'
977 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
978 continue; /* Skip Over "." and ".." Names */
980 strcpy(namebuf, ep.achName);
982 /* Leave Case of Name Alone -- In Native Form */
983 /* (Removed Forced Lowercasing Code) */
985 v = PyString_FromString(namebuf);
986 if (v == NULL) {
987 Py_DECREF(d);
988 d = NULL;
989 break;
991 if (PyList_Append(d, v) != 0) {
992 Py_DECREF(v);
993 Py_DECREF(d);
994 d = NULL;
995 break;
997 Py_DECREF(v);
998 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1001 return d;
1002 #else
1004 char *name;
1005 PyObject *d, *v;
1006 DIR *dirp;
1007 struct dirent *ep;
1008 if (!PyArg_ParseTuple(args, "s:listdir", &name))
1009 return NULL;
1010 if ((dirp = opendir(name)) == NULL) {
1011 return posix_error_with_filename(name);
1013 if ((d = PyList_New(0)) == NULL) {
1014 closedir(dirp);
1015 return NULL;
1017 while ((ep = readdir(dirp)) != NULL) {
1018 if (ep->d_name[0] == '.' &&
1019 (NAMLEN(ep) == 1 ||
1020 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
1021 continue;
1022 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
1023 if (v == NULL) {
1024 Py_DECREF(d);
1025 d = NULL;
1026 break;
1028 if (PyList_Append(d, v) != 0) {
1029 Py_DECREF(v);
1030 Py_DECREF(d);
1031 d = NULL;
1032 break;
1034 Py_DECREF(v);
1036 closedir(dirp);
1038 return d;
1040 #endif /* which OS */
1041 } /* end of posix_listdir */
1043 static char posix_mkdir__doc__[] =
1044 "mkdir(path [, mode=0777]) -> None\n\
1045 Create a directory.";
1047 static PyObject *
1048 posix_mkdir(PyObject *self, PyObject *args)
1050 int res;
1051 char *path;
1052 int mode = 0777;
1053 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
1054 return NULL;
1055 Py_BEGIN_ALLOW_THREADS
1056 #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1057 res = mkdir(path);
1058 #else
1059 res = mkdir(path, mode);
1060 #endif
1061 Py_END_ALLOW_THREADS
1062 if (res < 0)
1063 return posix_error_with_filename(path);
1064 Py_INCREF(Py_None);
1065 return Py_None;
1069 #ifdef HAVE_NICE
1070 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1071 #if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1072 #include <sys/resource.h>
1073 #endif
1074 #endif
1076 static char posix_nice__doc__[] =
1077 "nice(inc) -> new_priority\n\
1078 Decrease the priority of process and return new priority.";
1080 static PyObject *
1081 posix_nice(PyObject *self, PyObject *args)
1083 int increment, value;
1085 if (!PyArg_ParseTuple(args, "i:nice", &increment))
1086 return NULL;
1088 /* There are two flavours of 'nice': one that returns the new
1089 priority (as required by almost all standards out there) and the
1090 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1091 the use of getpriority() to get the new priority.
1093 If we are of the nice family that returns the new priority, we
1094 need to clear errno before the call, and check if errno is filled
1095 before calling posix_error() on a returnvalue of -1, because the
1096 -1 may be the actual new priority! */
1098 errno = 0;
1099 value = nice(increment);
1100 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
1101 if (value == 0)
1102 value = getpriority(PRIO_PROCESS, 0);
1103 #endif
1104 if (value == -1 && errno != 0)
1105 /* either nice() or getpriority() returned an error */
1106 return posix_error();
1107 return PyInt_FromLong((long) value);
1109 #endif /* HAVE_NICE */
1112 static char posix_rename__doc__[] =
1113 "rename(old, new) -> None\n\
1114 Rename a file or directory.";
1116 static PyObject *
1117 posix_rename(PyObject *self, PyObject *args)
1119 return posix_2str(args, "ss:rename", rename);
1123 static char posix_rmdir__doc__[] =
1124 "rmdir(path) -> None\n\
1125 Remove a directory.";
1127 static PyObject *
1128 posix_rmdir(PyObject *self, PyObject *args)
1130 return posix_1str(args, "s:rmdir", rmdir);
1134 static char posix_stat__doc__[] =
1135 "stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1136 Perform a stat system call on the given path.";
1138 static PyObject *
1139 posix_stat(PyObject *self, PyObject *args)
1141 return posix_do_stat(self, args, "s:stat", STAT);
1145 #ifdef HAVE_SYSTEM
1146 static char posix_system__doc__[] =
1147 "system(command) -> exit_status\n\
1148 Execute the command (a string) in a subshell.";
1150 static PyObject *
1151 posix_system(PyObject *self, PyObject *args)
1153 char *command;
1154 long sts;
1155 if (!PyArg_ParseTuple(args, "s:system", &command))
1156 return NULL;
1157 Py_BEGIN_ALLOW_THREADS
1158 sts = system(command);
1159 Py_END_ALLOW_THREADS
1160 return PyInt_FromLong(sts);
1162 #endif
1165 static char posix_umask__doc__[] =
1166 "umask(new_mask) -> old_mask\n\
1167 Set the current numeric umask and return the previous umask.";
1169 static PyObject *
1170 posix_umask(PyObject *self, PyObject *args)
1172 int i;
1173 if (!PyArg_ParseTuple(args, "i:umask", &i))
1174 return NULL;
1175 i = umask(i);
1176 if (i < 0)
1177 return posix_error();
1178 return PyInt_FromLong((long)i);
1182 static char posix_unlink__doc__[] =
1183 "unlink(path) -> None\n\
1184 Remove a file (same as remove(path)).";
1186 static char posix_remove__doc__[] =
1187 "remove(path) -> None\n\
1188 Remove a file (same as unlink(path)).";
1190 static PyObject *
1191 posix_unlink(PyObject *self, PyObject *args)
1193 return posix_1str(args, "s:remove", unlink);
1197 #ifdef HAVE_UNAME
1198 static char posix_uname__doc__[] =
1199 "uname() -> (sysname, nodename, release, version, machine)\n\
1200 Return a tuple identifying the current operating system.";
1202 static PyObject *
1203 posix_uname(PyObject *self, PyObject *args)
1205 struct utsname u;
1206 int res;
1207 if (!PyArg_ParseTuple(args, ":uname"))
1208 return NULL;
1209 Py_BEGIN_ALLOW_THREADS
1210 res = uname(&u);
1211 Py_END_ALLOW_THREADS
1212 if (res < 0)
1213 return posix_error();
1214 return Py_BuildValue("(sssss)",
1215 u.sysname,
1216 u.nodename,
1217 u.release,
1218 u.version,
1219 u.machine);
1221 #endif /* HAVE_UNAME */
1224 static char posix_utime__doc__[] =
1225 "utime(path, (atime, utime)) -> None\n\
1226 utime(path, None) -> None\n\
1227 Set the access and modified time of the file to the given values. If the\n\
1228 second form is used, set the access and modified times to the current time.";
1230 static PyObject *
1231 posix_utime(PyObject *self, PyObject *args)
1233 char *path;
1234 long atime, mtime;
1235 int res;
1236 PyObject* arg;
1238 /* XXX should define struct utimbuf instead, above */
1239 #ifdef HAVE_UTIME_H
1240 struct utimbuf buf;
1241 #define ATIME buf.actime
1242 #define MTIME buf.modtime
1243 #define UTIME_ARG &buf
1244 #else /* HAVE_UTIME_H */
1245 time_t buf[2];
1246 #define ATIME buf[0]
1247 #define MTIME buf[1]
1248 #define UTIME_ARG buf
1249 #endif /* HAVE_UTIME_H */
1251 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
1252 return NULL;
1253 if (arg == Py_None) {
1254 /* optional time values not given */
1255 Py_BEGIN_ALLOW_THREADS
1256 res = utime(path, NULL);
1257 Py_END_ALLOW_THREADS
1259 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1260 PyErr_SetString(PyExc_TypeError,
1261 "utime() arg 2 must be a tuple (atime, mtime)");
1262 return NULL;
1264 else {
1265 ATIME = atime;
1266 MTIME = mtime;
1267 Py_BEGIN_ALLOW_THREADS
1268 res = utime(path, UTIME_ARG);
1269 Py_END_ALLOW_THREADS
1271 if (res < 0)
1272 return posix_error_with_filename(path);
1273 Py_INCREF(Py_None);
1274 return Py_None;
1275 #undef UTIME_ARG
1276 #undef ATIME
1277 #undef MTIME
1281 /* Process operations */
1283 static char posix__exit__doc__[] =
1284 "_exit(status)\n\
1285 Exit to the system with specified status, without normal exit processing.";
1287 static PyObject *
1288 posix__exit(PyObject *self, PyObject *args)
1290 int sts;
1291 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
1292 return NULL;
1293 _exit(sts);
1294 return NULL; /* Make gcc -Wall happy */
1298 #ifdef HAVE_EXECV
1299 static char posix_execv__doc__[] =
1300 "execv(path, args)\n\
1301 Execute an executable path with arguments, replacing current process.\n\
1303 path: path of executable file\n\
1304 args: tuple or list of strings";
1306 static PyObject *
1307 posix_execv(PyObject *self, PyObject *args)
1309 char *path;
1310 PyObject *argv;
1311 char **argvlist;
1312 int i, argc;
1313 PyObject *(*getitem)(PyObject *, int);
1315 /* execv has two arguments: (path, argv), where
1316 argv is a list or tuple of strings. */
1318 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
1319 return NULL;
1320 if (PyList_Check(argv)) {
1321 argc = PyList_Size(argv);
1322 getitem = PyList_GetItem;
1324 else if (PyTuple_Check(argv)) {
1325 argc = PyTuple_Size(argv);
1326 getitem = PyTuple_GetItem;
1328 else {
1329 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
1330 return NULL;
1333 if (argc == 0) {
1334 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
1335 return NULL;
1338 argvlist = PyMem_NEW(char *, argc+1);
1339 if (argvlist == NULL)
1340 return NULL;
1341 for (i = 0; i < argc; i++) {
1342 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1343 PyMem_DEL(argvlist);
1344 PyErr_SetString(PyExc_TypeError,
1345 "execv() arg 2 must contain only strings");
1346 return NULL;
1350 argvlist[argc] = NULL;
1352 #ifdef BAD_EXEC_PROTOTYPES
1353 execv(path, (const char **) argvlist);
1354 #else /* BAD_EXEC_PROTOTYPES */
1355 execv(path, argvlist);
1356 #endif /* BAD_EXEC_PROTOTYPES */
1358 /* If we get here it's definitely an error */
1360 PyMem_DEL(argvlist);
1361 return posix_error();
1365 static char posix_execve__doc__[] =
1366 "execve(path, args, env)\n\
1367 Execute a path with arguments and environment, replacing current process.\n\
1369 path: path of executable file\n\
1370 args: tuple or list of arguments\n\
1371 env: dictionary of strings mapping to strings";
1373 static PyObject *
1374 posix_execve(PyObject *self, PyObject *args)
1376 char *path;
1377 PyObject *argv, *env;
1378 char **argvlist;
1379 char **envlist;
1380 PyObject *key, *val, *keys=NULL, *vals=NULL;
1381 int i, pos, argc, envc;
1382 PyObject *(*getitem)(PyObject *, int);
1384 /* execve has three arguments: (path, argv, env), where
1385 argv is a list or tuple of strings and env is a dictionary
1386 like posix.environ. */
1388 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
1389 return NULL;
1390 if (PyList_Check(argv)) {
1391 argc = PyList_Size(argv);
1392 getitem = PyList_GetItem;
1394 else if (PyTuple_Check(argv)) {
1395 argc = PyTuple_Size(argv);
1396 getitem = PyTuple_GetItem;
1398 else {
1399 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
1400 return NULL;
1402 if (!PyMapping_Check(env)) {
1403 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
1404 return NULL;
1407 if (argc == 0) {
1408 PyErr_SetString(PyExc_ValueError,
1409 "execve() arg 2 must not be empty");
1410 return NULL;
1413 argvlist = PyMem_NEW(char *, argc+1);
1414 if (argvlist == NULL) {
1415 PyErr_NoMemory();
1416 return NULL;
1418 for (i = 0; i < argc; i++) {
1419 if (!PyArg_Parse((*getitem)(argv, i),
1420 "s;execve() arg 2 must contain only strings",
1421 &argvlist[i]))
1423 goto fail_1;
1426 argvlist[argc] = NULL;
1428 i = PyMapping_Size(env);
1429 envlist = PyMem_NEW(char *, i + 1);
1430 if (envlist == NULL) {
1431 PyErr_NoMemory();
1432 goto fail_1;
1434 envc = 0;
1435 keys = PyMapping_Keys(env);
1436 vals = PyMapping_Values(env);
1437 if (!keys || !vals)
1438 goto fail_2;
1440 for (pos = 0; pos < i; pos++) {
1441 char *p, *k, *v;
1443 key = PyList_GetItem(keys, pos);
1444 val = PyList_GetItem(vals, pos);
1445 if (!key || !val)
1446 goto fail_2;
1448 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1449 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
1451 goto fail_2;
1454 #if defined(PYOS_OS2)
1455 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1456 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1457 #endif
1458 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1459 if (p == NULL) {
1460 PyErr_NoMemory();
1461 goto fail_2;
1463 sprintf(p, "%s=%s", k, v);
1464 envlist[envc++] = p;
1465 #if defined(PYOS_OS2)
1467 #endif
1469 envlist[envc] = 0;
1472 #ifdef BAD_EXEC_PROTOTYPES
1473 execve(path, (const char **)argvlist, envlist);
1474 #else /* BAD_EXEC_PROTOTYPES */
1475 execve(path, argvlist, envlist);
1476 #endif /* BAD_EXEC_PROTOTYPES */
1478 /* If we get here it's definitely an error */
1480 (void) posix_error();
1482 fail_2:
1483 while (--envc >= 0)
1484 PyMem_DEL(envlist[envc]);
1485 PyMem_DEL(envlist);
1486 fail_1:
1487 PyMem_DEL(argvlist);
1488 Py_XDECREF(vals);
1489 Py_XDECREF(keys);
1490 return NULL;
1492 #endif /* HAVE_EXECV */
1495 #ifdef HAVE_SPAWNV
1496 static char posix_spawnv__doc__[] =
1497 "spawnv(mode, path, args)\n\
1498 Execute an executable path with arguments, replacing current process.\n\
1500 mode: mode of process creation\n\
1501 path: path of executable file\n\
1502 args: tuple or list of strings";
1504 static PyObject *
1505 posix_spawnv(PyObject *self, PyObject *args)
1507 char *path;
1508 PyObject *argv;
1509 char **argvlist;
1510 int mode, i, argc;
1511 intptr_t spawnval;
1512 PyObject *(*getitem)(PyObject *, int);
1514 /* spawnv has three arguments: (mode, path, argv), where
1515 argv is a list or tuple of strings. */
1517 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
1518 return NULL;
1519 if (PyList_Check(argv)) {
1520 argc = PyList_Size(argv);
1521 getitem = PyList_GetItem;
1523 else if (PyTuple_Check(argv)) {
1524 argc = PyTuple_Size(argv);
1525 getitem = PyTuple_GetItem;
1527 else {
1528 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
1529 return NULL;
1532 argvlist = PyMem_NEW(char *, argc+1);
1533 if (argvlist == NULL)
1534 return NULL;
1535 for (i = 0; i < argc; i++) {
1536 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1537 PyMem_DEL(argvlist);
1538 PyErr_SetString(PyExc_TypeError,
1539 "spawnv() arg 2 must contain only strings");
1540 return NULL;
1543 argvlist[argc] = NULL;
1545 if (mode == _OLD_P_OVERLAY)
1546 mode = _P_OVERLAY;
1547 spawnval = _spawnv(mode, path, argvlist);
1549 PyMem_DEL(argvlist);
1551 if (spawnval == -1)
1552 return posix_error();
1553 else
1554 #if SIZEOF_LONG == SIZEOF_VOID_P
1555 return Py_BuildValue("l", (long) spawnval);
1556 #else
1557 return Py_BuildValue("L", (LONG_LONG) spawnval);
1558 #endif
1562 static char posix_spawnve__doc__[] =
1563 "spawnve(mode, path, args, env)\n\
1564 Execute a path with arguments and environment, replacing current process.\n\
1566 mode: mode of process creation\n\
1567 path: path of executable file\n\
1568 args: tuple or list of arguments\n\
1569 env: dictionary of strings mapping to strings";
1571 static PyObject *
1572 posix_spawnve(PyObject *self, PyObject *args)
1574 char *path;
1575 PyObject *argv, *env;
1576 char **argvlist;
1577 char **envlist;
1578 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1579 int mode, i, pos, argc, envc;
1580 intptr_t spawnval;
1581 PyObject *(*getitem)(PyObject *, int);
1583 /* spawnve has four arguments: (mode, path, argv, env), where
1584 argv is a list or tuple of strings and env is a dictionary
1585 like posix.environ. */
1587 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
1588 return NULL;
1589 if (PyList_Check(argv)) {
1590 argc = PyList_Size(argv);
1591 getitem = PyList_GetItem;
1593 else if (PyTuple_Check(argv)) {
1594 argc = PyTuple_Size(argv);
1595 getitem = PyTuple_GetItem;
1597 else {
1598 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
1599 return NULL;
1601 if (!PyMapping_Check(env)) {
1602 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
1603 return NULL;
1606 argvlist = PyMem_NEW(char *, argc+1);
1607 if (argvlist == NULL) {
1608 PyErr_NoMemory();
1609 return NULL;
1611 for (i = 0; i < argc; i++) {
1612 if (!PyArg_Parse((*getitem)(argv, i),
1613 "s;spawnve() arg 2 must contain only strings",
1614 &argvlist[i]))
1616 goto fail_1;
1619 argvlist[argc] = NULL;
1621 i = PyMapping_Size(env);
1622 envlist = PyMem_NEW(char *, i + 1);
1623 if (envlist == NULL) {
1624 PyErr_NoMemory();
1625 goto fail_1;
1627 envc = 0;
1628 keys = PyMapping_Keys(env);
1629 vals = PyMapping_Values(env);
1630 if (!keys || !vals)
1631 goto fail_2;
1633 for (pos = 0; pos < i; pos++) {
1634 char *p, *k, *v;
1636 key = PyList_GetItem(keys, pos);
1637 val = PyList_GetItem(vals, pos);
1638 if (!key || !val)
1639 goto fail_2;
1641 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1642 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
1644 goto fail_2;
1646 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1647 if (p == NULL) {
1648 PyErr_NoMemory();
1649 goto fail_2;
1651 sprintf(p, "%s=%s", k, v);
1652 envlist[envc++] = p;
1654 envlist[envc] = 0;
1656 if (mode == _OLD_P_OVERLAY)
1657 mode = _P_OVERLAY;
1658 spawnval = _spawnve(mode, path, argvlist, envlist);
1659 if (spawnval == -1)
1660 (void) posix_error();
1661 else
1662 #if SIZEOF_LONG == SIZEOF_VOID_P
1663 res = Py_BuildValue("l", (long) spawnval);
1664 #else
1665 res = Py_BuildValue("L", (LONG_LONG) spawnval);
1666 #endif
1668 fail_2:
1669 while (--envc >= 0)
1670 PyMem_DEL(envlist[envc]);
1671 PyMem_DEL(envlist);
1672 fail_1:
1673 PyMem_DEL(argvlist);
1674 Py_XDECREF(vals);
1675 Py_XDECREF(keys);
1676 return res;
1678 #endif /* HAVE_SPAWNV */
1681 #ifdef HAVE_FORK1
1682 static char posix_fork1__doc__[] =
1683 "fork1() -> pid\n\
1684 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1686 Return 0 to child process and PID of child to parent process.";
1688 static PyObject *
1689 posix_fork1(self, args)
1690 PyObject *self;
1691 PyObject *args;
1693 int pid;
1694 if (!PyArg_ParseTuple(args, ":fork1"))
1695 return NULL;
1696 pid = fork1();
1697 if (pid == -1)
1698 return posix_error();
1699 PyOS_AfterFork();
1700 return PyInt_FromLong((long)pid);
1702 #endif
1705 #ifdef HAVE_FORK
1706 static char posix_fork__doc__[] =
1707 "fork() -> pid\n\
1708 Fork a child process.\n\
1710 Return 0 to child process and PID of child to parent process.";
1712 static PyObject *
1713 posix_fork(PyObject *self, PyObject *args)
1715 int pid;
1716 if (!PyArg_ParseTuple(args, ":fork"))
1717 return NULL;
1718 pid = fork();
1719 if (pid == -1)
1720 return posix_error();
1721 if (pid == 0)
1722 PyOS_AfterFork();
1723 return PyInt_FromLong((long)pid);
1725 #endif
1727 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1728 #ifdef HAVE_PTY_H
1729 #include <pty.h>
1730 #else
1731 #ifdef HAVE_LIBUTIL_H
1732 #include <libutil.h>
1733 #endif /* HAVE_LIBUTIL_H */
1734 #endif /* HAVE_PTY_H */
1735 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
1737 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
1738 static char posix_openpty__doc__[] =
1739 "openpty() -> (master_fd, slave_fd)\n\
1740 Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1742 static PyObject *
1743 posix_openpty(PyObject *self, PyObject *args)
1745 int master_fd, slave_fd;
1746 #ifndef HAVE_OPENPTY
1747 char * slave_name;
1748 #endif
1750 if (!PyArg_ParseTuple(args, ":openpty"))
1751 return NULL;
1753 #ifdef HAVE_OPENPTY
1754 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1755 return posix_error();
1756 #else
1757 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1758 if (slave_name == NULL)
1759 return posix_error();
1761 slave_fd = open(slave_name, O_RDWR);
1762 if (slave_fd < 0)
1763 return posix_error();
1764 #endif /* HAVE_OPENPTY */
1766 return Py_BuildValue("(ii)", master_fd, slave_fd);
1769 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
1771 #ifdef HAVE_FORKPTY
1772 static char posix_forkpty__doc__[] =
1773 "forkpty() -> (pid, master_fd)\n\
1774 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1775 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1776 To both, return fd of newly opened pseudo-terminal.\n";
1778 static PyObject *
1779 posix_forkpty(PyObject *self, PyObject *args)
1781 int master_fd, pid;
1783 if (!PyArg_ParseTuple(args, ":forkpty"))
1784 return NULL;
1785 pid = forkpty(&master_fd, NULL, NULL, NULL);
1786 if (pid == -1)
1787 return posix_error();
1788 if (pid == 0)
1789 PyOS_AfterFork();
1790 return Py_BuildValue("(ii)", pid, master_fd);
1792 #endif
1794 #ifdef HAVE_GETEGID
1795 static char posix_getegid__doc__[] =
1796 "getegid() -> egid\n\
1797 Return the current process's effective group id.";
1799 static PyObject *
1800 posix_getegid(PyObject *self, PyObject *args)
1802 if (!PyArg_ParseTuple(args, ":getegid"))
1803 return NULL;
1804 return PyInt_FromLong((long)getegid());
1806 #endif
1809 #ifdef HAVE_GETEUID
1810 static char posix_geteuid__doc__[] =
1811 "geteuid() -> euid\n\
1812 Return the current process's effective user id.";
1814 static PyObject *
1815 posix_geteuid(PyObject *self, PyObject *args)
1817 if (!PyArg_ParseTuple(args, ":geteuid"))
1818 return NULL;
1819 return PyInt_FromLong((long)geteuid());
1821 #endif
1824 #ifdef HAVE_GETGID
1825 static char posix_getgid__doc__[] =
1826 "getgid() -> gid\n\
1827 Return the current process's group id.";
1829 static PyObject *
1830 posix_getgid(PyObject *self, PyObject *args)
1832 if (!PyArg_ParseTuple(args, ":getgid"))
1833 return NULL;
1834 return PyInt_FromLong((long)getgid());
1836 #endif
1839 static char posix_getpid__doc__[] =
1840 "getpid() -> pid\n\
1841 Return the current process id";
1843 static PyObject *
1844 posix_getpid(PyObject *self, PyObject *args)
1846 if (!PyArg_ParseTuple(args, ":getpid"))
1847 return NULL;
1848 return PyInt_FromLong((long)getpid());
1852 #ifdef HAVE_GETGROUPS
1853 static char posix_getgroups__doc__[] = "\
1854 getgroups() -> list of group IDs\n\
1855 Return list of supplemental group IDs for the process.";
1857 static PyObject *
1858 posix_getgroups(PyObject *self, PyObject *args)
1860 PyObject *result = NULL;
1862 if (PyArg_ParseTuple(args, ":getgroups")) {
1863 #ifdef NGROUPS_MAX
1864 #define MAX_GROUPS NGROUPS_MAX
1865 #else
1866 /* defined to be 16 on Solaris7, so this should be a small number */
1867 #define MAX_GROUPS 64
1868 #endif
1869 gid_t grouplist[MAX_GROUPS];
1870 int n;
1872 n = getgroups(MAX_GROUPS, grouplist);
1873 if (n < 0)
1874 posix_error();
1875 else {
1876 result = PyList_New(n);
1877 if (result != NULL) {
1878 PyObject *o;
1879 int i;
1880 for (i = 0; i < n; ++i) {
1881 o = PyInt_FromLong((long)grouplist[i]);
1882 if (o == NULL) {
1883 Py_DECREF(result);
1884 result = NULL;
1885 break;
1887 PyList_SET_ITEM(result, i, o);
1892 return result;
1894 #endif
1896 #ifdef HAVE_GETPGRP
1897 static char posix_getpgrp__doc__[] =
1898 "getpgrp() -> pgrp\n\
1899 Return the current process group id.";
1901 static PyObject *
1902 posix_getpgrp(PyObject *self, PyObject *args)
1904 if (!PyArg_ParseTuple(args, ":getpgrp"))
1905 return NULL;
1906 #ifdef GETPGRP_HAVE_ARG
1907 return PyInt_FromLong((long)getpgrp(0));
1908 #else /* GETPGRP_HAVE_ARG */
1909 return PyInt_FromLong((long)getpgrp());
1910 #endif /* GETPGRP_HAVE_ARG */
1912 #endif /* HAVE_GETPGRP */
1915 #ifdef HAVE_SETPGRP
1916 static char posix_setpgrp__doc__[] =
1917 "setpgrp() -> None\n\
1918 Make this process a session leader.";
1920 static PyObject *
1921 posix_setpgrp(PyObject *self, PyObject *args)
1923 if (!PyArg_ParseTuple(args, ":setpgrp"))
1924 return NULL;
1925 #ifdef SETPGRP_HAVE_ARG
1926 if (setpgrp(0, 0) < 0)
1927 #else /* SETPGRP_HAVE_ARG */
1928 if (setpgrp() < 0)
1929 #endif /* SETPGRP_HAVE_ARG */
1930 return posix_error();
1931 Py_INCREF(Py_None);
1932 return Py_None;
1935 #endif /* HAVE_SETPGRP */
1937 #ifdef HAVE_GETPPID
1938 static char posix_getppid__doc__[] =
1939 "getppid() -> ppid\n\
1940 Return the parent's process id.";
1942 static PyObject *
1943 posix_getppid(PyObject *self, PyObject *args)
1945 if (!PyArg_ParseTuple(args, ":getppid"))
1946 return NULL;
1947 return PyInt_FromLong((long)getppid());
1949 #endif
1952 #ifdef HAVE_GETLOGIN
1953 static char posix_getlogin__doc__[] = "\
1954 getlogin() -> string\n\
1955 Return the actual login name.";
1957 static PyObject *
1958 posix_getlogin(PyObject *self, PyObject *args)
1960 PyObject *result = NULL;
1962 if (PyArg_ParseTuple(args, ":getlogin")) {
1963 char *name;
1964 int old_errno = errno;
1966 errno = 0;
1967 name = getlogin();
1968 if (name == NULL) {
1969 if (errno)
1970 posix_error();
1971 else
1972 PyErr_SetString(PyExc_OSError,
1973 "unable to determine login name");
1975 else
1976 result = PyString_FromString(name);
1977 errno = old_errno;
1979 return result;
1981 #endif
1983 #ifdef HAVE_GETUID
1984 static char posix_getuid__doc__[] =
1985 "getuid() -> uid\n\
1986 Return the current process's user id.";
1988 static PyObject *
1989 posix_getuid(PyObject *self, PyObject *args)
1991 if (!PyArg_ParseTuple(args, ":getuid"))
1992 return NULL;
1993 return PyInt_FromLong((long)getuid());
1995 #endif
1998 #ifdef HAVE_KILL
1999 static char posix_kill__doc__[] =
2000 "kill(pid, sig) -> None\n\
2001 Kill a process with a signal.";
2003 static PyObject *
2004 posix_kill(PyObject *self, PyObject *args)
2006 int pid, sig;
2007 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
2008 return NULL;
2009 #if defined(PYOS_OS2)
2010 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2011 APIRET rc;
2012 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
2013 return os2_error(rc);
2015 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2016 APIRET rc;
2017 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
2018 return os2_error(rc);
2020 } else
2021 return NULL; /* Unrecognized Signal Requested */
2022 #else
2023 if (kill(pid, sig) == -1)
2024 return posix_error();
2025 #endif
2026 Py_INCREF(Py_None);
2027 return Py_None;
2029 #endif
2031 #ifdef HAVE_PLOCK
2033 #ifdef HAVE_SYS_LOCK_H
2034 #include <sys/lock.h>
2035 #endif
2037 static char posix_plock__doc__[] =
2038 "plock(op) -> None\n\
2039 Lock program segments into memory.";
2041 static PyObject *
2042 posix_plock(PyObject *self, PyObject *args)
2044 int op;
2045 if (!PyArg_ParseTuple(args, "i:plock", &op))
2046 return NULL;
2047 if (plock(op) == -1)
2048 return posix_error();
2049 Py_INCREF(Py_None);
2050 return Py_None;
2052 #endif
2055 #ifdef HAVE_POPEN
2056 static char posix_popen__doc__[] =
2057 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2058 Open a pipe to/from a command returning a file object.";
2060 #if defined(PYOS_OS2)
2061 static int
2062 async_system(const char *command)
2064 char *p, errormsg[256], args[1024];
2065 RESULTCODES rcodes;
2066 APIRET rc;
2067 char *shell = getenv("COMSPEC");
2068 if (!shell)
2069 shell = "cmd";
2071 strcpy(args, shell);
2072 p = &args[ strlen(args)+1 ];
2073 strcpy(p, "/c ");
2074 strcat(p, command);
2075 p += strlen(p) + 1;
2076 *p = '\0';
2078 rc = DosExecPgm(errormsg, sizeof(errormsg),
2079 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
2080 args,
2081 NULL, /* Inherit Parent's Environment */
2082 &rcodes, shell);
2083 return rc;
2086 static FILE *
2087 popen(const char *command, const char *mode, int pipesize, int *err)
2089 HFILE rhan, whan;
2090 FILE *retfd = NULL;
2091 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2093 if (rc != NO_ERROR) {
2094 *err = rc;
2095 return NULL; /* ERROR - Unable to Create Anon Pipe */
2098 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2099 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
2101 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2102 close(1); /* Make STDOUT Available for Reallocation */
2104 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2105 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
2107 if (async_system(command) == NO_ERROR)
2108 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2111 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2112 DosExitCritSec(); /* Now Allow Other Threads to Run */
2114 close(oldfd); /* And Close Saved STDOUT Handle */
2115 return retfd; /* Return fd of Pipe or NULL if Error */
2117 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2118 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
2120 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2121 close(0); /* Make STDIN Available for Reallocation */
2123 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2124 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
2126 if (async_system(command) == NO_ERROR)
2127 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2130 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2131 DosExitCritSec(); /* Now Allow Other Threads to Run */
2133 close(oldfd); /* And Close Saved STDIN Handle */
2134 return retfd; /* Return fd of Pipe or NULL if Error */
2136 } else {
2137 *err = ERROR_INVALID_ACCESS;
2138 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
2142 static PyObject *
2143 posix_popen(PyObject *self, PyObject *args)
2145 char *name;
2146 char *mode = "r";
2147 int err, bufsize = -1;
2148 FILE *fp;
2149 PyObject *f;
2150 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2151 return NULL;
2152 Py_BEGIN_ALLOW_THREADS
2153 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
2154 Py_END_ALLOW_THREADS
2155 if (fp == NULL)
2156 return os2_error(err);
2158 f = PyFile_FromFile(fp, name, mode, fclose);
2159 if (f != NULL)
2160 PyFile_SetBufSize(f, bufsize);
2161 return f;
2164 #elif defined(MS_WIN32)
2167 * Portable 'popen' replacement for Win32.
2169 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2170 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
2171 * Return code handling by David Bolen <db3l@fitlinxx.com>.
2174 #include <malloc.h>
2175 #include <io.h>
2176 #include <fcntl.h>
2178 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2179 #define POPEN_1 1
2180 #define POPEN_2 2
2181 #define POPEN_3 3
2182 #define POPEN_4 4
2184 static PyObject *_PyPopen(char *, int, int);
2185 static int _PyPclose(FILE *file);
2188 * Internal dictionary mapping popen* file pointers to process handles,
2189 * for use when retrieving the process exit code. See _PyPclose() below
2190 * for more information on this dictionary's use.
2192 static PyObject *_PyPopenProcs = NULL;
2195 /* popen that works from a GUI.
2197 * The result of this function is a pipe (file) connected to the
2198 * processes stdin or stdout, depending on the requested mode.
2201 static PyObject *
2202 posix_popen(PyObject *self, PyObject *args)
2204 PyObject *f, *s;
2205 int tm = 0;
2207 char *cmdstring;
2208 char *mode = "r";
2209 int bufsize = -1;
2210 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
2211 return NULL;
2213 s = PyTuple_New(0);
2215 if (*mode == 'r')
2216 tm = _O_RDONLY;
2217 else if (*mode != 'w') {
2218 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
2219 return NULL;
2220 } else
2221 tm = _O_WRONLY;
2223 if (bufsize != -1) {
2224 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
2225 return NULL;
2228 if (*(mode+1) == 't')
2229 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2230 else if (*(mode+1) == 'b')
2231 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
2232 else
2233 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2235 return f;
2238 /* Variation on win32pipe.popen
2240 * The result of this function is a pipe (file) connected to the
2241 * process's stdin, and a pipe connected to the process's stdout.
2244 static PyObject *
2245 win32_popen2(PyObject *self, PyObject *args)
2247 PyObject *f;
2248 int tm=0;
2250 char *cmdstring;
2251 char *mode = "t";
2252 int bufsize = -1;
2253 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2254 return NULL;
2256 if (*mode == 't')
2257 tm = _O_TEXT;
2258 else if (*mode != 'b') {
2259 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
2260 return NULL;
2261 } else
2262 tm = _O_BINARY;
2264 if (bufsize != -1) {
2265 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
2266 return NULL;
2269 f = _PyPopen(cmdstring, tm, POPEN_2);
2271 return f;
2275 * Variation on <om win32pipe.popen>
2277 * The result of this function is 3 pipes - the process's stdin,
2278 * stdout and stderr
2281 static PyObject *
2282 win32_popen3(PyObject *self, PyObject *args)
2284 PyObject *f;
2285 int tm = 0;
2287 char *cmdstring;
2288 char *mode = "t";
2289 int bufsize = -1;
2290 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2291 return NULL;
2293 if (*mode == 't')
2294 tm = _O_TEXT;
2295 else if (*mode != 'b') {
2296 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
2297 return NULL;
2298 } else
2299 tm = _O_BINARY;
2301 if (bufsize != -1) {
2302 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
2303 return NULL;
2306 f = _PyPopen(cmdstring, tm, POPEN_3);
2308 return f;
2312 * Variation on win32pipe.popen
2314 * The result of this function is 2 pipes - the processes stdin,
2315 * and stdout+stderr combined as a single pipe.
2318 static PyObject *
2319 win32_popen4(PyObject *self, PyObject *args)
2321 PyObject *f;
2322 int tm = 0;
2324 char *cmdstring;
2325 char *mode = "t";
2326 int bufsize = -1;
2327 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2328 return NULL;
2330 if (*mode == 't')
2331 tm = _O_TEXT;
2332 else if (*mode != 'b') {
2333 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
2334 return NULL;
2335 } else
2336 tm = _O_BINARY;
2338 if (bufsize != -1) {
2339 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
2340 return NULL;
2343 f = _PyPopen(cmdstring, tm, POPEN_4);
2345 return f;
2348 static BOOL
2349 _PyPopenCreateProcess(char *cmdstring,
2350 HANDLE hStdin,
2351 HANDLE hStdout,
2352 HANDLE hStderr,
2353 HANDLE *hProcess)
2355 PROCESS_INFORMATION piProcInfo;
2356 STARTUPINFO siStartInfo;
2357 char *s1,*s2, *s3 = " /c ";
2358 const char *szConsoleSpawn = "w9xpopen.exe";
2359 int i;
2360 int x;
2362 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2363 s1 = (char *)_alloca(i);
2364 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2365 return x;
2366 if (GetVersion() < 0x80000000) {
2368 * NT/2000
2370 x = i + strlen(s3) + strlen(cmdstring) + 1;
2371 s2 = (char *)_alloca(x);
2372 ZeroMemory(s2, x);
2373 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2375 else {
2377 * Oh gag, we're on Win9x. Use the workaround listed in
2378 * KB: Q150956
2380 char modulepath[_MAX_PATH];
2381 struct stat statinfo;
2382 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2383 for (i = x = 0; modulepath[i]; i++)
2384 if (modulepath[i] == '\\')
2385 x = i+1;
2386 modulepath[x] = '\0';
2387 /* Create the full-name to w9xpopen, so we can test it exists */
2388 strncat(modulepath,
2389 szConsoleSpawn,
2390 (sizeof(modulepath)/sizeof(modulepath[0]))
2391 -strlen(modulepath));
2392 if (stat(modulepath, &statinfo) != 0) {
2393 /* Eeek - file-not-found - possibly an embedding
2394 situation - see if we can locate it in sys.prefix
2396 strncpy(modulepath,
2397 Py_GetExecPrefix(),
2398 sizeof(modulepath)/sizeof(modulepath[0]));
2399 if (modulepath[strlen(modulepath)-1] != '\\')
2400 strcat(modulepath, "\\");
2401 strncat(modulepath,
2402 szConsoleSpawn,
2403 (sizeof(modulepath)/sizeof(modulepath[0]))
2404 -strlen(modulepath));
2405 /* No where else to look - raise an easily identifiable
2406 error, rather than leaving Windows to report
2407 "file not found" - as the user is probably blissfully
2408 unaware this shim EXE is used, and it will confuse them.
2409 (well, it confused me for a while ;-)
2411 if (stat(modulepath, &statinfo) != 0) {
2412 PyErr_Format(PyExc_RuntimeError,
2413 "Can not locate '%s' which is needed "
2414 "for popen to work on this platform.",
2415 szConsoleSpawn);
2416 return FALSE;
2419 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2420 strlen(modulepath) +
2421 strlen(szConsoleSpawn) + 1;
2423 s2 = (char *)_alloca(x);
2424 ZeroMemory(s2, x);
2425 sprintf(
2427 "%s \"%s%s%s\"",
2428 modulepath,
2431 cmdstring);
2435 /* Could be an else here to try cmd.exe / command.com in the path
2436 Now we'll just error out.. */
2437 else {
2438 PyErr_SetString(PyExc_RuntimeError, "Can not locate a COMSPEC environment variable to use as the shell");
2439 return FALSE;
2442 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2443 siStartInfo.cb = sizeof(STARTUPINFO);
2444 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2445 siStartInfo.hStdInput = hStdin;
2446 siStartInfo.hStdOutput = hStdout;
2447 siStartInfo.hStdError = hStderr;
2448 siStartInfo.wShowWindow = SW_HIDE;
2450 if (CreateProcess(NULL,
2452 NULL,
2453 NULL,
2454 TRUE,
2455 CREATE_NEW_CONSOLE,
2456 NULL,
2457 NULL,
2458 &siStartInfo,
2459 &piProcInfo) ) {
2460 /* Close the handles now so anyone waiting is woken. */
2461 CloseHandle(piProcInfo.hThread);
2463 /* Return process handle */
2464 *hProcess = piProcInfo.hProcess;
2465 return TRUE;
2467 win32_error("CreateProcess", NULL);
2468 return FALSE;
2471 /* The following code is based off of KB: Q190351 */
2473 static PyObject *
2474 _PyPopen(char *cmdstring, int mode, int n)
2476 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2477 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
2478 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
2480 SECURITY_ATTRIBUTES saAttr;
2481 BOOL fSuccess;
2482 int fd1, fd2, fd3;
2483 FILE *f1, *f2, *f3;
2484 long file_count;
2485 PyObject *f;
2487 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2488 saAttr.bInheritHandle = TRUE;
2489 saAttr.lpSecurityDescriptor = NULL;
2491 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2492 return win32_error("CreatePipe", NULL);
2494 /* Create new output read handle and the input write handle. Set
2495 * the inheritance properties to FALSE. Otherwise, the child inherits
2496 * the these handles; resulting in non-closeable handles to the pipes
2497 * being created. */
2498 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
2499 GetCurrentProcess(), &hChildStdinWrDup, 0,
2500 FALSE,
2501 DUPLICATE_SAME_ACCESS);
2502 if (!fSuccess)
2503 return win32_error("DuplicateHandle", NULL);
2505 /* Close the inheritable version of ChildStdin
2506 that we're using. */
2507 CloseHandle(hChildStdinWr);
2509 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2510 return win32_error("CreatePipe", NULL);
2512 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
2513 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2514 FALSE, DUPLICATE_SAME_ACCESS);
2515 if (!fSuccess)
2516 return win32_error("DuplicateHandle", NULL);
2518 /* Close the inheritable version of ChildStdout
2519 that we're using. */
2520 CloseHandle(hChildStdoutRd);
2522 if (n != POPEN_4) {
2523 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2524 return win32_error("CreatePipe", NULL);
2525 fSuccess = DuplicateHandle(GetCurrentProcess(),
2526 hChildStderrRd,
2527 GetCurrentProcess(),
2528 &hChildStderrRdDup, 0,
2529 FALSE, DUPLICATE_SAME_ACCESS);
2530 if (!fSuccess)
2531 return win32_error("DuplicateHandle", NULL);
2532 /* Close the inheritable version of ChildStdErr that we're using. */
2533 CloseHandle(hChildStderrRd);
2536 switch (n) {
2537 case POPEN_1:
2538 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2539 case _O_WRONLY | _O_TEXT:
2540 /* Case for writing to child Stdin in text mode. */
2541 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2542 f1 = _fdopen(fd1, "w");
2543 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
2544 PyFile_SetBufSize(f, 0);
2545 /* We don't care about these pipes anymore, so close them. */
2546 CloseHandle(hChildStdoutRdDup);
2547 CloseHandle(hChildStderrRdDup);
2548 break;
2550 case _O_RDONLY | _O_TEXT:
2551 /* Case for reading from child Stdout in text mode. */
2552 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2553 f1 = _fdopen(fd1, "r");
2554 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
2555 PyFile_SetBufSize(f, 0);
2556 /* We don't care about these pipes anymore, so close them. */
2557 CloseHandle(hChildStdinWrDup);
2558 CloseHandle(hChildStderrRdDup);
2559 break;
2561 case _O_RDONLY | _O_BINARY:
2562 /* Case for readinig from child Stdout in binary mode. */
2563 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2564 f1 = _fdopen(fd1, "rb");
2565 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
2566 PyFile_SetBufSize(f, 0);
2567 /* We don't care about these pipes anymore, so close them. */
2568 CloseHandle(hChildStdinWrDup);
2569 CloseHandle(hChildStderrRdDup);
2570 break;
2572 case _O_WRONLY | _O_BINARY:
2573 /* Case for writing to child Stdin in binary mode. */
2574 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2575 f1 = _fdopen(fd1, "wb");
2576 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
2577 PyFile_SetBufSize(f, 0);
2578 /* We don't care about these pipes anymore, so close them. */
2579 CloseHandle(hChildStdoutRdDup);
2580 CloseHandle(hChildStderrRdDup);
2581 break;
2583 file_count = 1;
2584 break;
2586 case POPEN_2:
2587 case POPEN_4:
2589 char *m1, *m2;
2590 PyObject *p1, *p2;
2592 if (mode && _O_TEXT) {
2593 m1 = "r";
2594 m2 = "w";
2595 } else {
2596 m1 = "rb";
2597 m2 = "wb";
2600 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2601 f1 = _fdopen(fd1, m2);
2602 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2603 f2 = _fdopen(fd2, m1);
2604 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
2605 PyFile_SetBufSize(p1, 0);
2606 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2607 PyFile_SetBufSize(p2, 0);
2609 if (n != 4)
2610 CloseHandle(hChildStderrRdDup);
2612 f = Py_BuildValue("OO",p1,p2);
2613 Py_XDECREF(p1);
2614 Py_XDECREF(p2);
2615 file_count = 2;
2616 break;
2619 case POPEN_3:
2621 char *m1, *m2;
2622 PyObject *p1, *p2, *p3;
2624 if (mode && _O_TEXT) {
2625 m1 = "r";
2626 m2 = "w";
2627 } else {
2628 m1 = "rb";
2629 m2 = "wb";
2632 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2633 f1 = _fdopen(fd1, m2);
2634 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2635 f2 = _fdopen(fd2, m1);
2636 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2637 f3 = _fdopen(fd3, m1);
2638 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
2639 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2640 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
2641 PyFile_SetBufSize(p1, 0);
2642 PyFile_SetBufSize(p2, 0);
2643 PyFile_SetBufSize(p3, 0);
2644 f = Py_BuildValue("OOO",p1,p2,p3);
2645 Py_XDECREF(p1);
2646 Py_XDECREF(p2);
2647 Py_XDECREF(p3);
2648 file_count = 3;
2649 break;
2653 if (n == POPEN_4) {
2654 if (!_PyPopenCreateProcess(cmdstring,
2655 hChildStdinRd,
2656 hChildStdoutWr,
2657 hChildStdoutWr,
2658 &hProcess))
2659 return NULL;
2661 else {
2662 if (!_PyPopenCreateProcess(cmdstring,
2663 hChildStdinRd,
2664 hChildStdoutWr,
2665 hChildStderrWr,
2666 &hProcess))
2667 return NULL;
2671 * Insert the files we've created into the process dictionary
2672 * all referencing the list with the process handle and the
2673 * initial number of files (see description below in _PyPclose).
2674 * Since if _PyPclose later tried to wait on a process when all
2675 * handles weren't closed, it could create a deadlock with the
2676 * child, we spend some energy here to try to ensure that we
2677 * either insert all file handles into the dictionary or none
2678 * at all. It's a little clumsy with the various popen modes
2679 * and variable number of files involved.
2681 if (!_PyPopenProcs) {
2682 _PyPopenProcs = PyDict_New();
2685 if (_PyPopenProcs) {
2686 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2687 int ins_rc[3];
2689 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2690 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2692 procObj = PyList_New(2);
2693 hProcessObj = PyLong_FromVoidPtr(hProcess);
2694 intObj = PyInt_FromLong(file_count);
2696 if (procObj && hProcessObj && intObj) {
2697 PyList_SetItem(procObj,0,hProcessObj);
2698 PyList_SetItem(procObj,1,intObj);
2700 fileObj[0] = PyLong_FromVoidPtr(f1);
2701 if (fileObj[0]) {
2702 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2703 fileObj[0],
2704 procObj);
2706 if (file_count >= 2) {
2707 fileObj[1] = PyLong_FromVoidPtr(f2);
2708 if (fileObj[1]) {
2709 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2710 fileObj[1],
2711 procObj);
2714 if (file_count >= 3) {
2715 fileObj[2] = PyLong_FromVoidPtr(f3);
2716 if (fileObj[2]) {
2717 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2718 fileObj[2],
2719 procObj);
2723 if (ins_rc[0] < 0 || !fileObj[0] ||
2724 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2725 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2726 /* Something failed - remove any dictionary
2727 * entries that did make it.
2729 if (!ins_rc[0] && fileObj[0]) {
2730 PyDict_DelItem(_PyPopenProcs,
2731 fileObj[0]);
2733 if (!ins_rc[1] && fileObj[1]) {
2734 PyDict_DelItem(_PyPopenProcs,
2735 fileObj[1]);
2737 if (!ins_rc[2] && fileObj[2]) {
2738 PyDict_DelItem(_PyPopenProcs,
2739 fileObj[2]);
2745 * Clean up our localized references for the dictionary keys
2746 * and value since PyDict_SetItem will Py_INCREF any copies
2747 * that got placed in the dictionary.
2749 Py_XDECREF(procObj);
2750 Py_XDECREF(fileObj[0]);
2751 Py_XDECREF(fileObj[1]);
2752 Py_XDECREF(fileObj[2]);
2755 /* Child is launched. Close the parents copy of those pipe
2756 * handles that only the child should have open. You need to
2757 * make sure that no handles to the write end of the output pipe
2758 * are maintained in this process or else the pipe will not close
2759 * when the child process exits and the ReadFile will hang. */
2761 if (!CloseHandle(hChildStdinRd))
2762 return win32_error("CloseHandle", NULL);
2764 if (!CloseHandle(hChildStdoutWr))
2765 return win32_error("CloseHandle", NULL);
2767 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2768 return win32_error("CloseHandle", NULL);
2770 return f;
2774 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2775 * exit code for the child process and return as a result of the close.
2777 * This function uses the _PyPopenProcs dictionary in order to map the
2778 * input file pointer to information about the process that was
2779 * originally created by the popen* call that created the file pointer.
2780 * The dictionary uses the file pointer as a key (with one entry
2781 * inserted for each file returned by the original popen* call) and a
2782 * single list object as the value for all files from a single call.
2783 * The list object contains the Win32 process handle at [0], and a file
2784 * count at [1], which is initialized to the total number of file
2785 * handles using that list.
2787 * This function closes whichever handle it is passed, and decrements
2788 * the file count in the dictionary for the process handle pointed to
2789 * by this file. On the last close (when the file count reaches zero),
2790 * this function will wait for the child process and then return its
2791 * exit code as the result of the close() operation. This permits the
2792 * files to be closed in any order - it is always the close() of the
2793 * final handle that will return the exit code.
2796 /* RED_FLAG 31-Aug-2000 Tim
2797 * This is always called (today!) between a pair of
2798 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2799 * macros. So the thread running this has no valid thread state, as
2800 * far as Python is concerned. However, this calls some Python API
2801 * functions that cannot be called safely without a valid thread
2802 * state, in particular PyDict_GetItem.
2803 * As a temporary hack (although it may last for years ...), we
2804 * *rely* on not having a valid thread state in this function, in
2805 * order to create our own "from scratch".
2806 * This will deadlock if _PyPclose is ever called by a thread
2807 * holding the global lock.
2810 static int _PyPclose(FILE *file)
2812 int result;
2813 DWORD exit_code;
2814 HANDLE hProcess;
2815 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2816 long file_count;
2817 #ifdef WITH_THREAD
2818 PyInterpreterState* pInterpreterState;
2819 PyThreadState* pThreadState;
2820 #endif
2822 /* Close the file handle first, to ensure it can't block the
2823 * child from exiting if it's the last handle.
2825 result = fclose(file);
2827 #ifdef WITH_THREAD
2828 /* Bootstrap a valid thread state into existence. */
2829 pInterpreterState = PyInterpreterState_New();
2830 if (!pInterpreterState) {
2831 /* Well, we're hosed now! We don't have a thread
2832 * state, so can't call a nice error routine, or raise
2833 * an exception. Just die.
2835 Py_FatalError("unable to allocate interpreter state "
2836 "when closing popen object");
2837 return -1; /* unreachable */
2839 pThreadState = PyThreadState_New(pInterpreterState);
2840 if (!pThreadState) {
2841 Py_FatalError("unable to allocate thread state "
2842 "when closing popen object");
2843 return -1; /* unreachable */
2845 /* Grab the global lock. Note that this will deadlock if the
2846 * current thread already has the lock! (see RED_FLAG comments
2847 * before this function)
2849 PyEval_RestoreThread(pThreadState);
2850 #endif
2852 if (_PyPopenProcs) {
2853 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2854 (procObj = PyDict_GetItem(_PyPopenProcs,
2855 fileObj)) != NULL &&
2856 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2857 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2859 hProcess = PyLong_AsVoidPtr(hProcessObj);
2860 file_count = PyInt_AsLong(intObj);
2862 if (file_count > 1) {
2863 /* Still other files referencing process */
2864 file_count--;
2865 PyList_SetItem(procObj,1,
2866 PyInt_FromLong(file_count));
2867 } else {
2868 /* Last file for this process */
2869 if (result != EOF &&
2870 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2871 GetExitCodeProcess(hProcess, &exit_code)) {
2872 /* Possible truncation here in 16-bit environments, but
2873 * real exit codes are just the lower byte in any event.
2875 result = exit_code;
2876 } else {
2877 /* Indicate failure - this will cause the file object
2878 * to raise an I/O error and translate the last Win32
2879 * error code from errno. We do have a problem with
2880 * last errors that overlap the normal errno table,
2881 * but that's a consistent problem with the file object.
2883 if (result != EOF) {
2884 /* If the error wasn't from the fclose(), then
2885 * set errno for the file object error handling.
2887 errno = GetLastError();
2889 result = -1;
2892 /* Free up the native handle at this point */
2893 CloseHandle(hProcess);
2896 /* Remove this file pointer from dictionary */
2897 PyDict_DelItem(_PyPopenProcs, fileObj);
2899 if (PyDict_Size(_PyPopenProcs) == 0) {
2900 Py_DECREF(_PyPopenProcs);
2901 _PyPopenProcs = NULL;
2904 } /* if object retrieval ok */
2906 Py_XDECREF(fileObj);
2907 } /* if _PyPopenProcs */
2909 #ifdef WITH_THREAD
2910 /* Tear down the thread & interpreter states.
2911 * Note that interpreter state clear & delete functions automatically
2912 * call the thread clear & delete functions, and indeed insist on
2913 * doing that themselves. The lock must be held during the clear, but
2914 * need not be held during the delete.
2916 PyInterpreterState_Clear(pInterpreterState);
2917 PyEval_ReleaseThread(pThreadState);
2918 PyInterpreterState_Delete(pInterpreterState);
2919 #endif
2921 return result;
2924 #else /* which OS? */
2925 static PyObject *
2926 posix_popen(PyObject *self, PyObject *args)
2928 char *name;
2929 char *mode = "r";
2930 int bufsize = -1;
2931 FILE *fp;
2932 PyObject *f;
2933 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2934 return NULL;
2935 Py_BEGIN_ALLOW_THREADS
2936 fp = popen(name, mode);
2937 Py_END_ALLOW_THREADS
2938 if (fp == NULL)
2939 return posix_error();
2940 f = PyFile_FromFile(fp, name, mode, pclose);
2941 if (f != NULL)
2942 PyFile_SetBufSize(f, bufsize);
2943 return f;
2945 #endif
2947 #endif /* HAVE_POPEN */
2950 #ifdef HAVE_SETUID
2951 static char posix_setuid__doc__[] =
2952 "setuid(uid) -> None\n\
2953 Set the current process's user id.";
2954 static PyObject *
2955 posix_setuid(PyObject *self, PyObject *args)
2957 int uid;
2958 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
2959 return NULL;
2960 if (setuid(uid) < 0)
2961 return posix_error();
2962 Py_INCREF(Py_None);
2963 return Py_None;
2965 #endif /* HAVE_SETUID */
2968 #ifdef HAVE_SETEUID
2969 static char posix_seteuid__doc__[] =
2970 "seteuid(uid) -> None\n\
2971 Set the current process's effective user id.";
2972 static PyObject *
2973 posix_seteuid (PyObject *self, PyObject *args)
2975 int euid;
2976 if (!PyArg_ParseTuple(args, "i", &euid)) {
2977 return NULL;
2978 } else if (seteuid(euid) < 0) {
2979 return posix_error();
2980 } else {
2981 Py_INCREF(Py_None);
2982 return Py_None;
2985 #endif /* HAVE_SETEUID */
2987 #ifdef HAVE_SETEGID
2988 static char posix_setegid__doc__[] =
2989 "setegid(gid) -> None\n\
2990 Set the current process's effective group id.";
2991 static PyObject *
2992 posix_setegid (PyObject *self, PyObject *args)
2994 int egid;
2995 if (!PyArg_ParseTuple(args, "i", &egid)) {
2996 return NULL;
2997 } else if (setegid(egid) < 0) {
2998 return posix_error();
2999 } else {
3000 Py_INCREF(Py_None);
3001 return Py_None;
3004 #endif /* HAVE_SETEGID */
3006 #ifdef HAVE_SETREUID
3007 static char posix_setreuid__doc__[] =
3008 "seteuid(ruid, euid) -> None\n\
3009 Set the current process's real and effective user ids.";
3010 static PyObject *
3011 posix_setreuid (PyObject *self, PyObject *args)
3013 int ruid, euid;
3014 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3015 return NULL;
3016 } else if (setreuid(ruid, euid) < 0) {
3017 return posix_error();
3018 } else {
3019 Py_INCREF(Py_None);
3020 return Py_None;
3023 #endif /* HAVE_SETREUID */
3025 #ifdef HAVE_SETREGID
3026 static char posix_setregid__doc__[] =
3027 "setegid(rgid, egid) -> None\n\
3028 Set the current process's real and effective group ids.";
3029 static PyObject *
3030 posix_setregid (PyObject *self, PyObject *args)
3032 int rgid, egid;
3033 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3034 return NULL;
3035 } else if (setregid(rgid, egid) < 0) {
3036 return posix_error();
3037 } else {
3038 Py_INCREF(Py_None);
3039 return Py_None;
3042 #endif /* HAVE_SETREGID */
3044 #ifdef HAVE_SETGID
3045 static char posix_setgid__doc__[] =
3046 "setgid(gid) -> None\n\
3047 Set the current process's group id.";
3049 static PyObject *
3050 posix_setgid(PyObject *self, PyObject *args)
3052 int gid;
3053 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
3054 return NULL;
3055 if (setgid(gid) < 0)
3056 return posix_error();
3057 Py_INCREF(Py_None);
3058 return Py_None;
3060 #endif /* HAVE_SETGID */
3063 #ifdef HAVE_WAITPID
3064 static char posix_waitpid__doc__[] =
3065 "waitpid(pid, options) -> (pid, status)\n\
3066 Wait for completion of a given child process.";
3068 static PyObject *
3069 posix_waitpid(PyObject *self, PyObject *args)
3071 int pid, options;
3072 #ifdef UNION_WAIT
3073 union wait status;
3074 #define status_i (status.w_status)
3075 #else
3076 int status;
3077 #define status_i status
3078 #endif
3079 status_i = 0;
3081 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
3082 return NULL;
3083 Py_BEGIN_ALLOW_THREADS
3084 #ifdef NeXT
3085 pid = wait4(pid, &status, options, NULL);
3086 #else
3087 pid = waitpid(pid, &status, options);
3088 #endif
3089 Py_END_ALLOW_THREADS
3090 if (pid == -1)
3091 return posix_error();
3092 else
3093 return Py_BuildValue("ii", pid, status_i);
3095 #endif /* HAVE_WAITPID */
3098 #ifdef HAVE_WAIT
3099 static char posix_wait__doc__[] =
3100 "wait() -> (pid, status)\n\
3101 Wait for completion of a child process.";
3103 static PyObject *
3104 posix_wait(PyObject *self, PyObject *args)
3106 int pid;
3107 #ifdef UNION_WAIT
3108 union wait status;
3109 #define status_i (status.w_status)
3110 #else
3111 int status;
3112 #define status_i status
3113 #endif
3114 if (!PyArg_ParseTuple(args, ":wait"))
3115 return NULL;
3116 status_i = 0;
3117 Py_BEGIN_ALLOW_THREADS
3118 pid = wait(&status);
3119 Py_END_ALLOW_THREADS
3120 if (pid == -1)
3121 return posix_error();
3122 else
3123 return Py_BuildValue("ii", pid, status_i);
3124 #undef status_i
3126 #endif
3129 static char posix_lstat__doc__[] =
3130 "lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3131 Like stat(path), but do not follow symbolic links.";
3133 static PyObject *
3134 posix_lstat(PyObject *self, PyObject *args)
3136 #ifdef HAVE_LSTAT
3137 return posix_do_stat(self, args, "s:lstat", lstat);
3138 #else /* !HAVE_LSTAT */
3139 return posix_do_stat(self, args, "s:lstat", STAT);
3140 #endif /* !HAVE_LSTAT */
3144 #ifdef HAVE_READLINK
3145 static char posix_readlink__doc__[] =
3146 "readlink(path) -> path\n\
3147 Return a string representing the path to which the symbolic link points.";
3149 static PyObject *
3150 posix_readlink(PyObject *self, PyObject *args)
3152 char buf[MAXPATHLEN];
3153 char *path;
3154 int n;
3155 if (!PyArg_ParseTuple(args, "s:readlink", &path))
3156 return NULL;
3157 Py_BEGIN_ALLOW_THREADS
3158 n = readlink(path, buf, (int) sizeof buf);
3159 Py_END_ALLOW_THREADS
3160 if (n < 0)
3161 return posix_error_with_filename(path);
3162 return PyString_FromStringAndSize(buf, n);
3164 #endif /* HAVE_READLINK */
3167 #ifdef HAVE_SYMLINK
3168 static char posix_symlink__doc__[] =
3169 "symlink(src, dst) -> None\n\
3170 Create a symbolic link.";
3172 static PyObject *
3173 posix_symlink(PyObject *self, PyObject *args)
3175 return posix_2str(args, "ss:symlink", symlink);
3177 #endif /* HAVE_SYMLINK */
3180 #ifdef HAVE_TIMES
3181 #ifndef HZ
3182 #define HZ 60 /* Universal constant :-) */
3183 #endif /* HZ */
3185 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
3186 static long
3187 system_uptime(void)
3189 ULONG value = 0;
3191 Py_BEGIN_ALLOW_THREADS
3192 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3193 Py_END_ALLOW_THREADS
3195 return value;
3198 static PyObject *
3199 posix_times(PyObject *self, PyObject *args)
3201 if (!PyArg_ParseTuple(args, ":times"))
3202 return NULL;
3204 /* Currently Only Uptime is Provided -- Others Later */
3205 return Py_BuildValue("ddddd",
3206 (double)0 /* t.tms_utime / HZ */,
3207 (double)0 /* t.tms_stime / HZ */,
3208 (double)0 /* t.tms_cutime / HZ */,
3209 (double)0 /* t.tms_cstime / HZ */,
3210 (double)system_uptime() / 1000);
3212 #else /* not OS2 */
3213 static PyObject *
3214 posix_times(PyObject *self, PyObject *args)
3216 struct tms t;
3217 clock_t c;
3218 if (!PyArg_ParseTuple(args, ":times"))
3219 return NULL;
3220 errno = 0;
3221 c = times(&t);
3222 if (c == (clock_t) -1)
3223 return posix_error();
3224 return Py_BuildValue("ddddd",
3225 (double)t.tms_utime / HZ,
3226 (double)t.tms_stime / HZ,
3227 (double)t.tms_cutime / HZ,
3228 (double)t.tms_cstime / HZ,
3229 (double)c / HZ);
3231 #endif /* not OS2 */
3232 #endif /* HAVE_TIMES */
3235 #ifdef MS_WIN32
3236 #define HAVE_TIMES /* so the method table will pick it up */
3237 static PyObject *
3238 posix_times(PyObject *self, PyObject *args)
3240 FILETIME create, exit, kernel, user;
3241 HANDLE hProc;
3242 if (!PyArg_ParseTuple(args, ":times"))
3243 return NULL;
3244 hProc = GetCurrentProcess();
3245 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3246 /* The fields of a FILETIME structure are the hi and lo part
3247 of a 64-bit value expressed in 100 nanosecond units.
3248 1e7 is one second in such units; 1e-7 the inverse.
3249 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3251 return Py_BuildValue(
3252 "ddddd",
3253 (double)(kernel.dwHighDateTime*429.4967296 +
3254 kernel.dwLowDateTime*1e-7),
3255 (double)(user.dwHighDateTime*429.4967296 +
3256 user.dwLowDateTime*1e-7),
3257 (double)0,
3258 (double)0,
3259 (double)0);
3261 #endif /* MS_WIN32 */
3263 #ifdef HAVE_TIMES
3264 static char posix_times__doc__[] =
3265 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3266 Return a tuple of floating point numbers indicating process times.";
3267 #endif
3270 #ifdef HAVE_SETSID
3271 static char posix_setsid__doc__[] =
3272 "setsid() -> None\n\
3273 Call the system call setsid().";
3275 static PyObject *
3276 posix_setsid(PyObject *self, PyObject *args)
3278 if (!PyArg_ParseTuple(args, ":setsid"))
3279 return NULL;
3280 if (setsid() < 0)
3281 return posix_error();
3282 Py_INCREF(Py_None);
3283 return Py_None;
3285 #endif /* HAVE_SETSID */
3287 #ifdef HAVE_SETPGID
3288 static char posix_setpgid__doc__[] =
3289 "setpgid(pid, pgrp) -> None\n\
3290 Call the system call setpgid().";
3292 static PyObject *
3293 posix_setpgid(PyObject *self, PyObject *args)
3295 int pid, pgrp;
3296 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
3297 return NULL;
3298 if (setpgid(pid, pgrp) < 0)
3299 return posix_error();
3300 Py_INCREF(Py_None);
3301 return Py_None;
3303 #endif /* HAVE_SETPGID */
3306 #ifdef HAVE_TCGETPGRP
3307 static char posix_tcgetpgrp__doc__[] =
3308 "tcgetpgrp(fd) -> pgid\n\
3309 Return the process group associated with the terminal given by a fd.";
3311 static PyObject *
3312 posix_tcgetpgrp(PyObject *self, PyObject *args)
3314 int fd, pgid;
3315 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
3316 return NULL;
3317 pgid = tcgetpgrp(fd);
3318 if (pgid < 0)
3319 return posix_error();
3320 return PyInt_FromLong((long)pgid);
3322 #endif /* HAVE_TCGETPGRP */
3325 #ifdef HAVE_TCSETPGRP
3326 static char posix_tcsetpgrp__doc__[] =
3327 "tcsetpgrp(fd, pgid) -> None\n\
3328 Set the process group associated with the terminal given by a fd.";
3330 static PyObject *
3331 posix_tcsetpgrp(PyObject *self, PyObject *args)
3333 int fd, pgid;
3334 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
3335 return NULL;
3336 if (tcsetpgrp(fd, pgid) < 0)
3337 return posix_error();
3338 Py_INCREF(Py_None);
3339 return Py_None;
3341 #endif /* HAVE_TCSETPGRP */
3343 /* Functions acting on file descriptors */
3345 static char posix_open__doc__[] =
3346 "open(filename, flag [, mode=0777]) -> fd\n\
3347 Open a file (for low level IO).";
3349 static PyObject *
3350 posix_open(PyObject *self, PyObject *args)
3352 char *file;
3353 int flag;
3354 int mode = 0777;
3355 int fd;
3356 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3357 return NULL;
3359 Py_BEGIN_ALLOW_THREADS
3360 fd = open(file, flag, mode);
3361 Py_END_ALLOW_THREADS
3362 if (fd < 0)
3363 return posix_error_with_filename(file);
3364 return PyInt_FromLong((long)fd);
3368 static char posix_close__doc__[] =
3369 "close(fd) -> None\n\
3370 Close a file descriptor (for low level IO).";
3372 static PyObject *
3373 posix_close(PyObject *self, PyObject *args)
3375 int fd, res;
3376 if (!PyArg_ParseTuple(args, "i:close", &fd))
3377 return NULL;
3378 Py_BEGIN_ALLOW_THREADS
3379 res = close(fd);
3380 Py_END_ALLOW_THREADS
3381 if (res < 0)
3382 return posix_error();
3383 Py_INCREF(Py_None);
3384 return Py_None;
3388 static char posix_dup__doc__[] =
3389 "dup(fd) -> fd2\n\
3390 Return a duplicate of a file descriptor.";
3392 static PyObject *
3393 posix_dup(PyObject *self, PyObject *args)
3395 int fd;
3396 if (!PyArg_ParseTuple(args, "i:dup", &fd))
3397 return NULL;
3398 Py_BEGIN_ALLOW_THREADS
3399 fd = dup(fd);
3400 Py_END_ALLOW_THREADS
3401 if (fd < 0)
3402 return posix_error();
3403 return PyInt_FromLong((long)fd);
3407 static char posix_dup2__doc__[] =
3408 "dup2(fd, fd2) -> None\n\
3409 Duplicate file descriptor.";
3411 static PyObject *
3412 posix_dup2(PyObject *self, PyObject *args)
3414 int fd, fd2, res;
3415 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
3416 return NULL;
3417 Py_BEGIN_ALLOW_THREADS
3418 res = dup2(fd, fd2);
3419 Py_END_ALLOW_THREADS
3420 if (res < 0)
3421 return posix_error();
3422 Py_INCREF(Py_None);
3423 return Py_None;
3427 static char posix_lseek__doc__[] =
3428 "lseek(fd, pos, how) -> newpos\n\
3429 Set the current position of a file descriptor.";
3431 static PyObject *
3432 posix_lseek(PyObject *self, PyObject *args)
3434 int fd, how;
3435 #ifdef MS_WIN64
3436 LONG_LONG pos, res;
3437 #else
3438 off_t pos, res;
3439 #endif
3440 PyObject *posobj;
3441 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
3442 return NULL;
3443 #ifdef SEEK_SET
3444 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3445 switch (how) {
3446 case 0: how = SEEK_SET; break;
3447 case 1: how = SEEK_CUR; break;
3448 case 2: how = SEEK_END; break;
3450 #endif /* SEEK_END */
3452 #if !defined(HAVE_LARGEFILE_SUPPORT)
3453 pos = PyInt_AsLong(posobj);
3454 #else
3455 pos = PyLong_Check(posobj) ?
3456 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3457 #endif
3458 if (PyErr_Occurred())
3459 return NULL;
3461 Py_BEGIN_ALLOW_THREADS
3462 #ifdef MS_WIN64
3463 res = _lseeki64(fd, pos, how);
3464 #else
3465 res = lseek(fd, pos, how);
3466 #endif
3467 Py_END_ALLOW_THREADS
3468 if (res < 0)
3469 return posix_error();
3471 #if !defined(HAVE_LARGEFILE_SUPPORT)
3472 return PyInt_FromLong(res);
3473 #else
3474 return PyLong_FromLongLong(res);
3475 #endif
3479 static char posix_read__doc__[] =
3480 "read(fd, buffersize) -> string\n\
3481 Read a file descriptor.";
3483 static PyObject *
3484 posix_read(PyObject *self, PyObject *args)
3486 int fd, size, n;
3487 PyObject *buffer;
3488 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
3489 return NULL;
3490 buffer = PyString_FromStringAndSize((char *)NULL, size);
3491 if (buffer == NULL)
3492 return NULL;
3493 Py_BEGIN_ALLOW_THREADS
3494 n = read(fd, PyString_AsString(buffer), size);
3495 Py_END_ALLOW_THREADS
3496 if (n < 0) {
3497 Py_DECREF(buffer);
3498 return posix_error();
3500 if (n != size)
3501 _PyString_Resize(&buffer, n);
3502 return buffer;
3506 static char posix_write__doc__[] =
3507 "write(fd, string) -> byteswritten\n\
3508 Write a string to a file descriptor.";
3510 static PyObject *
3511 posix_write(PyObject *self, PyObject *args)
3513 int fd, size;
3514 char *buffer;
3515 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
3516 return NULL;
3517 Py_BEGIN_ALLOW_THREADS
3518 size = write(fd, buffer, size);
3519 Py_END_ALLOW_THREADS
3520 if (size < 0)
3521 return posix_error();
3522 return PyInt_FromLong((long)size);
3526 static char posix_fstat__doc__[]=
3527 "fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3528 Like stat(), but for an open file descriptor.";
3530 static PyObject *
3531 posix_fstat(PyObject *self, PyObject *args)
3533 int fd;
3534 STRUCT_STAT st;
3535 int res;
3536 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
3537 return NULL;
3538 Py_BEGIN_ALLOW_THREADS
3539 res = FSTAT(fd, &st);
3540 Py_END_ALLOW_THREADS
3541 if (res != 0)
3542 return posix_error();
3544 return _pystat_fromstructstat(st);
3548 static char posix_fdopen__doc__[] =
3549 "fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3550 Return an open file object connected to a file descriptor.";
3552 static PyObject *
3553 posix_fdopen(PyObject *self, PyObject *args)
3555 int fd;
3556 char *mode = "r";
3557 int bufsize = -1;
3558 FILE *fp;
3559 PyObject *f;
3560 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
3561 return NULL;
3563 Py_BEGIN_ALLOW_THREADS
3564 fp = fdopen(fd, mode);
3565 Py_END_ALLOW_THREADS
3566 if (fp == NULL)
3567 return posix_error();
3568 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
3569 if (f != NULL)
3570 PyFile_SetBufSize(f, bufsize);
3571 return f;
3574 static char posix_isatty__doc__[] =
3575 "isatty(fd) -> Boolean\n\
3576 Return true if the file descriptor 'fd' is an open file descriptor\n\
3577 connected to the slave end of a terminal.";
3579 static PyObject *
3580 posix_isatty(PyObject *self, PyObject *args)
3582 int fd;
3583 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3584 return NULL;
3585 return Py_BuildValue("i", isatty(fd));
3588 #ifdef HAVE_PIPE
3589 static char posix_pipe__doc__[] =
3590 "pipe() -> (read_end, write_end)\n\
3591 Create a pipe.";
3593 static PyObject *
3594 posix_pipe(PyObject *self, PyObject *args)
3596 #if defined(PYOS_OS2)
3597 HFILE read, write;
3598 APIRET rc;
3600 if (!PyArg_ParseTuple(args, ":pipe"))
3601 return NULL;
3603 Py_BEGIN_ALLOW_THREADS
3604 rc = DosCreatePipe( &read, &write, 4096);
3605 Py_END_ALLOW_THREADS
3606 if (rc != NO_ERROR)
3607 return os2_error(rc);
3609 return Py_BuildValue("(ii)", read, write);
3610 #else
3611 #if !defined(MS_WIN32)
3612 int fds[2];
3613 int res;
3614 if (!PyArg_ParseTuple(args, ":pipe"))
3615 return NULL;
3616 Py_BEGIN_ALLOW_THREADS
3617 res = pipe(fds);
3618 Py_END_ALLOW_THREADS
3619 if (res != 0)
3620 return posix_error();
3621 return Py_BuildValue("(ii)", fds[0], fds[1]);
3622 #else /* MS_WIN32 */
3623 HANDLE read, write;
3624 int read_fd, write_fd;
3625 BOOL ok;
3626 if (!PyArg_ParseTuple(args, ":pipe"))
3627 return NULL;
3628 Py_BEGIN_ALLOW_THREADS
3629 ok = CreatePipe(&read, &write, NULL, 0);
3630 Py_END_ALLOW_THREADS
3631 if (!ok)
3632 return win32_error("CreatePipe", NULL);
3633 read_fd = _open_osfhandle((intptr_t)read, 0);
3634 write_fd = _open_osfhandle((intptr_t)write, 1);
3635 return Py_BuildValue("(ii)", read_fd, write_fd);
3636 #endif /* MS_WIN32 */
3637 #endif
3639 #endif /* HAVE_PIPE */
3642 #ifdef HAVE_MKFIFO
3643 static char posix_mkfifo__doc__[] =
3644 "mkfifo(file, [, mode=0666]) -> None\n\
3645 Create a FIFO (a POSIX named pipe).";
3647 static PyObject *
3648 posix_mkfifo(PyObject *self, PyObject *args)
3650 char *file;
3651 int mode = 0666;
3652 int res;
3653 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
3654 return NULL;
3655 Py_BEGIN_ALLOW_THREADS
3656 res = mkfifo(file, mode);
3657 Py_END_ALLOW_THREADS
3658 if (res < 0)
3659 return posix_error();
3660 Py_INCREF(Py_None);
3661 return Py_None;
3663 #endif
3666 #ifdef HAVE_FTRUNCATE
3667 static char posix_ftruncate__doc__[] =
3668 "ftruncate(fd, length) -> None\n\
3669 Truncate a file to a specified length.";
3671 static PyObject *
3672 posix_ftruncate(PyObject *self, PyObject *args)
3674 int fd;
3675 off_t length;
3676 int res;
3677 PyObject *lenobj;
3679 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
3680 return NULL;
3682 #if !defined(HAVE_LARGEFILE_SUPPORT)
3683 length = PyInt_AsLong(lenobj);
3684 #else
3685 length = PyLong_Check(lenobj) ?
3686 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3687 #endif
3688 if (PyErr_Occurred())
3689 return NULL;
3691 Py_BEGIN_ALLOW_THREADS
3692 res = ftruncate(fd, length);
3693 Py_END_ALLOW_THREADS
3694 if (res < 0) {
3695 PyErr_SetFromErrno(PyExc_IOError);
3696 return NULL;
3698 Py_INCREF(Py_None);
3699 return Py_None;
3701 #endif
3703 #ifdef NeXT
3704 #define HAVE_PUTENV
3705 /* Steve Spicklemire got this putenv from NeXTAnswers */
3706 static int
3707 putenv(char *newval)
3709 extern char **environ;
3711 static int firstTime = 1;
3712 char **ep;
3713 char *cp;
3714 int esiz;
3715 char *np;
3717 if (!(np = strchr(newval, '=')))
3718 return 1;
3719 *np = '\0';
3721 /* look it up */
3722 for (ep=environ ; *ep ; ep++)
3724 /* this should always be true... */
3725 if (cp = strchr(*ep, '='))
3727 *cp = '\0';
3728 if (!strcmp(*ep, newval))
3730 /* got it! */
3731 *cp = '=';
3732 break;
3734 *cp = '=';
3736 else
3738 *np = '=';
3739 return 1;
3743 *np = '=';
3744 if (*ep)
3746 /* the string was already there:
3747 just replace it with the new one */
3748 *ep = newval;
3749 return 0;
3752 /* expand environ by one */
3753 for (esiz=2, ep=environ ; *ep ; ep++)
3754 esiz++;
3755 if (firstTime)
3757 char **epp;
3758 char **newenv;
3759 if (!(newenv = malloc(esiz * sizeof(char *))))
3760 return 1;
3762 for (ep=environ, epp=newenv ; *ep ;)
3763 *epp++ = *ep++;
3764 *epp++ = newval;
3765 *epp = (char *) 0;
3766 environ = newenv;
3768 else
3770 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3771 return 1;
3772 environ[esiz - 2] = newval;
3773 environ[esiz - 1] = (char *) 0;
3774 firstTime = 0;
3777 return 0;
3779 #endif /* NeXT */
3782 #ifdef HAVE_PUTENV
3783 static char posix_putenv__doc__[] =
3784 "putenv(key, value) -> None\n\
3785 Change or add an environment variable.";
3787 /* Save putenv() parameters as values here, so we can collect them when they
3788 * get re-set with another call for the same key. */
3789 static PyObject *posix_putenv_garbage;
3791 static PyObject *
3792 posix_putenv(PyObject *self, PyObject *args)
3794 char *s1, *s2;
3795 char *new;
3796 PyObject *newstr;
3798 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
3799 return NULL;
3801 #if defined(PYOS_OS2)
3802 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3803 APIRET rc;
3805 if (strlen(s2) == 0) /* If New Value is an Empty String */
3806 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3808 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3809 if (rc != NO_ERROR)
3810 return os2_error(rc);
3812 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3813 APIRET rc;
3815 if (strlen(s2) == 0) /* If New Value is an Empty String */
3816 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3818 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3819 if (rc != NO_ERROR)
3820 return os2_error(rc);
3821 } else {
3822 #endif
3824 /* XXX This can leak memory -- not easy to fix :-( */
3825 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3826 if (newstr == NULL)
3827 return PyErr_NoMemory();
3828 new = PyString_AS_STRING(newstr);
3829 (void) sprintf(new, "%s=%s", s1, s2);
3830 if (putenv(new)) {
3831 posix_error();
3832 return NULL;
3834 /* Install the first arg and newstr in posix_putenv_garbage;
3835 * this will cause previous value to be collected. This has to
3836 * happen after the real putenv() call because the old value
3837 * was still accessible until then. */
3838 if (PyDict_SetItem(posix_putenv_garbage,
3839 PyTuple_GET_ITEM(args, 0), newstr)) {
3840 /* really not much we can do; just leak */
3841 PyErr_Clear();
3843 else {
3844 Py_DECREF(newstr);
3847 #if defined(PYOS_OS2)
3849 #endif
3850 Py_INCREF(Py_None);
3851 return Py_None;
3853 #endif /* putenv */
3855 #ifdef HAVE_STRERROR
3856 static char posix_strerror__doc__[] =
3857 "strerror(code) -> string\n\
3858 Translate an error code to a message string.";
3860 static PyObject *
3861 posix_strerror(PyObject *self, PyObject *args)
3863 int code;
3864 char *message;
3865 if (!PyArg_ParseTuple(args, "i:strerror", &code))
3866 return NULL;
3867 message = strerror(code);
3868 if (message == NULL) {
3869 PyErr_SetString(PyExc_ValueError,
3870 "strerror() argument out of range");
3871 return NULL;
3873 return PyString_FromString(message);
3875 #endif /* strerror */
3878 #ifdef HAVE_SYS_WAIT_H
3880 #ifdef WIFSTOPPED
3881 static char posix_WIFSTOPPED__doc__[] =
3882 "WIFSTOPPED(status) -> Boolean\n\
3883 Return true if the process returning 'status' was stopped.";
3885 static PyObject *
3886 posix_WIFSTOPPED(PyObject *self, PyObject *args)
3888 #ifdef UNION_WAIT
3889 union wait status;
3890 #define status_i (status.w_status)
3891 #else
3892 int status;
3893 #define status_i status
3894 #endif
3895 status_i = 0;
3897 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
3899 return NULL;
3902 return Py_BuildValue("i", WIFSTOPPED(status));
3903 #undef status_i
3905 #endif /* WIFSTOPPED */
3907 #ifdef WIFSIGNALED
3908 static char posix_WIFSIGNALED__doc__[] =
3909 "WIFSIGNALED(status) -> Boolean\n\
3910 Return true if the process returning 'status' was terminated by a signal.";
3912 static PyObject *
3913 posix_WIFSIGNALED(PyObject *self, PyObject *args)
3915 #ifdef UNION_WAIT
3916 union wait status;
3917 #define status_i (status.w_status)
3918 #else
3919 int status;
3920 #define status_i status
3921 #endif
3922 status_i = 0;
3924 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
3926 return NULL;
3929 return Py_BuildValue("i", WIFSIGNALED(status));
3930 #undef status_i
3932 #endif /* WIFSIGNALED */
3934 #ifdef WIFEXITED
3935 static char posix_WIFEXITED__doc__[] =
3936 "WIFEXITED(status) -> Boolean\n\
3937 Return true if the process returning 'status' exited using the exit()\n\
3938 system call.";
3940 static PyObject *
3941 posix_WIFEXITED(PyObject *self, PyObject *args)
3943 #ifdef UNION_WAIT
3944 union wait status;
3945 #define status_i (status.w_status)
3946 #else
3947 int status;
3948 #define status_i status
3949 #endif
3950 status_i = 0;
3952 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
3954 return NULL;
3957 return Py_BuildValue("i", WIFEXITED(status));
3958 #undef status_i
3960 #endif /* WIFEXITED */
3962 #ifdef WEXITSTATUS
3963 static char posix_WEXITSTATUS__doc__[] =
3964 "WEXITSTATUS(status) -> integer\n\
3965 Return the process return code from 'status'.";
3967 static PyObject *
3968 posix_WEXITSTATUS(PyObject *self, PyObject *args)
3970 #ifdef UNION_WAIT
3971 union wait status;
3972 #define status_i (status.w_status)
3973 #else
3974 int status;
3975 #define status_i status
3976 #endif
3977 status_i = 0;
3979 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
3981 return NULL;
3984 return Py_BuildValue("i", WEXITSTATUS(status));
3985 #undef status_i
3987 #endif /* WEXITSTATUS */
3989 #ifdef WTERMSIG
3990 static char posix_WTERMSIG__doc__[] =
3991 "WTERMSIG(status) -> integer\n\
3992 Return the signal that terminated the process that provided the 'status'\n\
3993 value.";
3995 static PyObject *
3996 posix_WTERMSIG(PyObject *self, PyObject *args)
3998 #ifdef UNION_WAIT
3999 union wait status;
4000 #define status_i (status.w_status)
4001 #else
4002 int status;
4003 #define status_i status
4004 #endif
4005 status_i = 0;
4007 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
4009 return NULL;
4012 return Py_BuildValue("i", WTERMSIG(status));
4013 #undef status_i
4015 #endif /* WTERMSIG */
4017 #ifdef WSTOPSIG
4018 static char posix_WSTOPSIG__doc__[] =
4019 "WSTOPSIG(status) -> integer\n\
4020 Return the signal that stopped the process that provided the 'status' value.";
4022 static PyObject *
4023 posix_WSTOPSIG(PyObject *self, PyObject *args)
4025 #ifdef UNION_WAIT
4026 union wait status;
4027 #define status_i (status.w_status)
4028 #else
4029 int status;
4030 #define status_i status
4031 #endif
4032 status_i = 0;
4034 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
4036 return NULL;
4039 return Py_BuildValue("i", WSTOPSIG(status));
4040 #undef status_i
4042 #endif /* WSTOPSIG */
4044 #endif /* HAVE_SYS_WAIT_H */
4047 #if defined(HAVE_FSTATVFS)
4048 #ifdef _SCO_DS
4049 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4050 needed definitions in sys/statvfs.h */
4051 #define _SVID3
4052 #endif
4053 #include <sys/statvfs.h>
4055 static char posix_fstatvfs__doc__[] =
4056 "fstatvfs(fd) -> \n\
4057 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
4058 Perform an fstatvfs system call on the given fd.";
4060 static PyObject *
4061 posix_fstatvfs(PyObject *self, PyObject *args)
4063 int fd, res;
4064 struct statvfs st;
4065 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
4066 return NULL;
4067 Py_BEGIN_ALLOW_THREADS
4068 res = fstatvfs(fd, &st);
4069 Py_END_ALLOW_THREADS
4070 if (res != 0)
4071 return posix_error();
4072 #if !defined(HAVE_LARGEFILE_SUPPORT)
4073 return Py_BuildValue("(llllllllll)",
4074 (long) st.f_bsize,
4075 (long) st.f_frsize,
4076 (long) st.f_blocks,
4077 (long) st.f_bfree,
4078 (long) st.f_bavail,
4079 (long) st.f_files,
4080 (long) st.f_ffree,
4081 (long) st.f_favail,
4082 (long) st.f_flag,
4083 (long) st.f_namemax);
4084 #else
4085 return Py_BuildValue("(llLLLLLLll)",
4086 (long) st.f_bsize,
4087 (long) st.f_frsize,
4088 (LONG_LONG) st.f_blocks,
4089 (LONG_LONG) st.f_bfree,
4090 (LONG_LONG) st.f_bavail,
4091 (LONG_LONG) st.f_files,
4092 (LONG_LONG) st.f_ffree,
4093 (LONG_LONG) st.f_favail,
4094 (long) st.f_flag,
4095 (long) st.f_namemax);
4096 #endif
4098 #endif /* HAVE_FSTATVFS */
4101 #if defined(HAVE_STATVFS)
4102 #include <sys/statvfs.h>
4104 static char posix_statvfs__doc__[] =
4105 "statvfs(path) -> \n\
4106 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
4107 Perform a statvfs system call on the given path.";
4109 static PyObject *
4110 posix_statvfs(PyObject *self, PyObject *args)
4112 char *path;
4113 int res;
4114 struct statvfs st;
4115 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
4116 return NULL;
4117 Py_BEGIN_ALLOW_THREADS
4118 res = statvfs(path, &st);
4119 Py_END_ALLOW_THREADS
4120 if (res != 0)
4121 return posix_error_with_filename(path);
4122 #if !defined(HAVE_LARGEFILE_SUPPORT)
4123 return Py_BuildValue("(llllllllll)",
4124 (long) st.f_bsize,
4125 (long) st.f_frsize,
4126 (long) st.f_blocks,
4127 (long) st.f_bfree,
4128 (long) st.f_bavail,
4129 (long) st.f_files,
4130 (long) st.f_ffree,
4131 (long) st.f_favail,
4132 (long) st.f_flag,
4133 (long) st.f_namemax);
4134 #else /* HAVE_LARGEFILE_SUPPORT */
4135 return Py_BuildValue("(llLLLLLLll)",
4136 (long) st.f_bsize,
4137 (long) st.f_frsize,
4138 (LONG_LONG) st.f_blocks,
4139 (LONG_LONG) st.f_bfree,
4140 (LONG_LONG) st.f_bavail,
4141 (LONG_LONG) st.f_files,
4142 (LONG_LONG) st.f_ffree,
4143 (LONG_LONG) st.f_favail,
4144 (long) st.f_flag,
4145 (long) st.f_namemax);
4146 #endif
4148 #endif /* HAVE_STATVFS */
4151 #ifdef HAVE_TEMPNAM
4152 static char posix_tempnam__doc__[] = "\
4153 tempnam([dir[, prefix]]) -> string\n\
4154 Return a unique name for a temporary file.\n\
4155 The directory and a short may be specified as strings; they may be omitted\n\
4156 or None if not needed.";
4158 static PyObject *
4159 posix_tempnam(PyObject *self, PyObject *args)
4161 PyObject *result = NULL;
4162 char *dir = NULL;
4163 char *pfx = NULL;
4164 char *name;
4166 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4167 return NULL;
4168 name = tempnam(dir, pfx);
4169 if (name == NULL)
4170 return PyErr_NoMemory();
4171 result = PyString_FromString(name);
4172 free(name);
4173 return result;
4175 #endif
4178 #ifdef HAVE_TMPFILE
4179 static char posix_tmpfile__doc__[] = "\
4180 tmpfile() -> file object\n\
4181 Create a temporary file with no directory entries.";
4183 static PyObject *
4184 posix_tmpfile(PyObject *self, PyObject *args)
4186 FILE *fp;
4188 if (!PyArg_ParseTuple(args, ":tmpfile"))
4189 return NULL;
4190 fp = tmpfile();
4191 if (fp == NULL)
4192 return posix_error();
4193 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4195 #endif
4198 #ifdef HAVE_TMPNAM
4199 static char posix_tmpnam__doc__[] = "\
4200 tmpnam() -> string\n\
4201 Return a unique name for a temporary file.";
4203 static PyObject *
4204 posix_tmpnam(PyObject *self, PyObject *args)
4206 char buffer[L_tmpnam];
4207 char *name;
4209 if (!PyArg_ParseTuple(args, ":tmpnam"))
4210 return NULL;
4211 #ifdef USE_TMPNAM_R
4212 name = tmpnam_r(buffer);
4213 #else
4214 name = tmpnam(buffer);
4215 #endif
4216 if (name == NULL) {
4217 PyErr_SetObject(PyExc_OSError,
4218 Py_BuildValue("is", 0,
4219 #ifdef USE_TMPNAM_R
4220 "unexpected NULL from tmpnam_r"
4221 #else
4222 "unexpected NULL from tmpnam"
4223 #endif
4225 return NULL;
4227 return PyString_FromString(buffer);
4229 #endif
4232 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4233 * It maps strings representing configuration variable names to
4234 * integer values, allowing those functions to be called with the
4235 * magic names instead of polluting the module's namespace with tons of
4236 * rarely-used constants. There are three separate tables that use
4237 * these definitions.
4239 * This code is always included, even if none of the interfaces that
4240 * need it are included. The #if hackery needed to avoid it would be
4241 * sufficiently pervasive that it's not worth the loss of readability.
4243 struct constdef {
4244 char *name;
4245 long value;
4248 static int
4249 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4250 size_t tablesize)
4252 if (PyInt_Check(arg)) {
4253 *valuep = PyInt_AS_LONG(arg);
4254 return 1;
4256 if (PyString_Check(arg)) {
4257 /* look up the value in the table using a binary search */
4258 size_t lo = 0;
4259 size_t mid;
4260 size_t hi = tablesize;
4261 int cmp;
4262 char *confname = PyString_AS_STRING(arg);
4263 while (lo < hi) {
4264 mid = (lo + hi) / 2;
4265 cmp = strcmp(confname, table[mid].name);
4266 if (cmp < 0)
4267 hi = mid;
4268 else if (cmp > 0)
4269 lo = mid + 1;
4270 else {
4271 *valuep = table[mid].value;
4272 return 1;
4275 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4277 else
4278 PyErr_SetString(PyExc_TypeError,
4279 "configuration names must be strings or integers");
4280 return 0;
4284 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4285 static struct constdef posix_constants_pathconf[] = {
4286 #ifdef _PC_ABI_AIO_XFER_MAX
4287 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4288 #endif
4289 #ifdef _PC_ABI_ASYNC_IO
4290 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4291 #endif
4292 #ifdef _PC_ASYNC_IO
4293 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4294 #endif
4295 #ifdef _PC_CHOWN_RESTRICTED
4296 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4297 #endif
4298 #ifdef _PC_FILESIZEBITS
4299 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4300 #endif
4301 #ifdef _PC_LAST
4302 {"PC_LAST", _PC_LAST},
4303 #endif
4304 #ifdef _PC_LINK_MAX
4305 {"PC_LINK_MAX", _PC_LINK_MAX},
4306 #endif
4307 #ifdef _PC_MAX_CANON
4308 {"PC_MAX_CANON", _PC_MAX_CANON},
4309 #endif
4310 #ifdef _PC_MAX_INPUT
4311 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4312 #endif
4313 #ifdef _PC_NAME_MAX
4314 {"PC_NAME_MAX", _PC_NAME_MAX},
4315 #endif
4316 #ifdef _PC_NO_TRUNC
4317 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4318 #endif
4319 #ifdef _PC_PATH_MAX
4320 {"PC_PATH_MAX", _PC_PATH_MAX},
4321 #endif
4322 #ifdef _PC_PIPE_BUF
4323 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4324 #endif
4325 #ifdef _PC_PRIO_IO
4326 {"PC_PRIO_IO", _PC_PRIO_IO},
4327 #endif
4328 #ifdef _PC_SOCK_MAXBUF
4329 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4330 #endif
4331 #ifdef _PC_SYNC_IO
4332 {"PC_SYNC_IO", _PC_SYNC_IO},
4333 #endif
4334 #ifdef _PC_VDISABLE
4335 {"PC_VDISABLE", _PC_VDISABLE},
4336 #endif
4339 static int
4340 conv_path_confname(PyObject *arg, int *valuep)
4342 return conv_confname(arg, valuep, posix_constants_pathconf,
4343 sizeof(posix_constants_pathconf)
4344 / sizeof(struct constdef));
4346 #endif
4348 #ifdef HAVE_FPATHCONF
4349 static char posix_fpathconf__doc__[] = "\
4350 fpathconf(fd, name) -> integer\n\
4351 Return the configuration limit name for the file descriptor fd.\n\
4352 If there is no limit, return -1.";
4354 static PyObject *
4355 posix_fpathconf(PyObject *self, PyObject *args)
4357 PyObject *result = NULL;
4358 int name, fd;
4360 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4361 conv_path_confname, &name)) {
4362 long limit;
4364 errno = 0;
4365 limit = fpathconf(fd, name);
4366 if (limit == -1 && errno != 0)
4367 posix_error();
4368 else
4369 result = PyInt_FromLong(limit);
4371 return result;
4373 #endif
4376 #ifdef HAVE_PATHCONF
4377 static char posix_pathconf__doc__[] = "\
4378 pathconf(path, name) -> integer\n\
4379 Return the configuration limit name for the file or directory path.\n\
4380 If there is no limit, return -1.";
4382 static PyObject *
4383 posix_pathconf(PyObject *self, PyObject *args)
4385 PyObject *result = NULL;
4386 int name;
4387 char *path;
4389 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4390 conv_path_confname, &name)) {
4391 long limit;
4393 errno = 0;
4394 limit = pathconf(path, name);
4395 if (limit == -1 && errno != 0) {
4396 if (errno == EINVAL)
4397 /* could be a path or name problem */
4398 posix_error();
4399 else
4400 posix_error_with_filename(path);
4402 else
4403 result = PyInt_FromLong(limit);
4405 return result;
4407 #endif
4409 #ifdef HAVE_CONFSTR
4410 static struct constdef posix_constants_confstr[] = {
4411 #ifdef _CS_ARCHITECTURE
4412 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4413 #endif
4414 #ifdef _CS_HOSTNAME
4415 {"CS_HOSTNAME", _CS_HOSTNAME},
4416 #endif
4417 #ifdef _CS_HW_PROVIDER
4418 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4419 #endif
4420 #ifdef _CS_HW_SERIAL
4421 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4422 #endif
4423 #ifdef _CS_INITTAB_NAME
4424 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4425 #endif
4426 #ifdef _CS_LFS64_CFLAGS
4427 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4428 #endif
4429 #ifdef _CS_LFS64_LDFLAGS
4430 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4431 #endif
4432 #ifdef _CS_LFS64_LIBS
4433 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4434 #endif
4435 #ifdef _CS_LFS64_LINTFLAGS
4436 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4437 #endif
4438 #ifdef _CS_LFS_CFLAGS
4439 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4440 #endif
4441 #ifdef _CS_LFS_LDFLAGS
4442 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4443 #endif
4444 #ifdef _CS_LFS_LIBS
4445 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4446 #endif
4447 #ifdef _CS_LFS_LINTFLAGS
4448 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4449 #endif
4450 #ifdef _CS_MACHINE
4451 {"CS_MACHINE", _CS_MACHINE},
4452 #endif
4453 #ifdef _CS_PATH
4454 {"CS_PATH", _CS_PATH},
4455 #endif
4456 #ifdef _CS_RELEASE
4457 {"CS_RELEASE", _CS_RELEASE},
4458 #endif
4459 #ifdef _CS_SRPC_DOMAIN
4460 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4461 #endif
4462 #ifdef _CS_SYSNAME
4463 {"CS_SYSNAME", _CS_SYSNAME},
4464 #endif
4465 #ifdef _CS_VERSION
4466 {"CS_VERSION", _CS_VERSION},
4467 #endif
4468 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4469 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4470 #endif
4471 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4472 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4473 #endif
4474 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
4475 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4476 #endif
4477 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4478 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4479 #endif
4480 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4481 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4482 #endif
4483 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4484 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4485 #endif
4486 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4487 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4488 #endif
4489 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4490 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4491 #endif
4492 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4493 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4494 #endif
4495 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4496 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4497 #endif
4498 #ifdef _CS_XBS5_LP64_OFF64_LIBS
4499 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4500 #endif
4501 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4502 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4503 #endif
4504 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4505 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4506 #endif
4507 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4508 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4509 #endif
4510 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4511 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4512 #endif
4513 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4514 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4515 #endif
4516 #ifdef _MIPS_CS_AVAIL_PROCESSORS
4517 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4518 #endif
4519 #ifdef _MIPS_CS_BASE
4520 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4521 #endif
4522 #ifdef _MIPS_CS_HOSTID
4523 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4524 #endif
4525 #ifdef _MIPS_CS_HW_NAME
4526 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4527 #endif
4528 #ifdef _MIPS_CS_NUM_PROCESSORS
4529 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4530 #endif
4531 #ifdef _MIPS_CS_OSREL_MAJ
4532 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4533 #endif
4534 #ifdef _MIPS_CS_OSREL_MIN
4535 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4536 #endif
4537 #ifdef _MIPS_CS_OSREL_PATCH
4538 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4539 #endif
4540 #ifdef _MIPS_CS_OS_NAME
4541 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4542 #endif
4543 #ifdef _MIPS_CS_OS_PROVIDER
4544 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4545 #endif
4546 #ifdef _MIPS_CS_PROCESSORS
4547 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4548 #endif
4549 #ifdef _MIPS_CS_SERIAL
4550 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4551 #endif
4552 #ifdef _MIPS_CS_VENDOR
4553 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4554 #endif
4557 static int
4558 conv_confstr_confname(PyObject *arg, int *valuep)
4560 return conv_confname(arg, valuep, posix_constants_confstr,
4561 sizeof(posix_constants_confstr)
4562 / sizeof(struct constdef));
4565 static char posix_confstr__doc__[] = "\
4566 confstr(name) -> string\n\
4567 Return a string-valued system configuration variable.";
4569 static PyObject *
4570 posix_confstr(PyObject *self, PyObject *args)
4572 PyObject *result = NULL;
4573 int name;
4574 char buffer[64];
4576 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4577 int len = confstr(name, buffer, sizeof(buffer));
4579 errno = 0;
4580 if (len == 0) {
4581 if (errno != 0)
4582 posix_error();
4583 else
4584 result = PyString_FromString("");
4586 else {
4587 if (len >= sizeof(buffer)) {
4588 result = PyString_FromStringAndSize(NULL, len);
4589 if (result != NULL)
4590 confstr(name, PyString_AS_STRING(result), len+1);
4592 else
4593 result = PyString_FromString(buffer);
4596 return result;
4598 #endif
4601 #ifdef HAVE_SYSCONF
4602 static struct constdef posix_constants_sysconf[] = {
4603 #ifdef _SC_2_CHAR_TERM
4604 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4605 #endif
4606 #ifdef _SC_2_C_BIND
4607 {"SC_2_C_BIND", _SC_2_C_BIND},
4608 #endif
4609 #ifdef _SC_2_C_DEV
4610 {"SC_2_C_DEV", _SC_2_C_DEV},
4611 #endif
4612 #ifdef _SC_2_C_VERSION
4613 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4614 #endif
4615 #ifdef _SC_2_FORT_DEV
4616 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4617 #endif
4618 #ifdef _SC_2_FORT_RUN
4619 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4620 #endif
4621 #ifdef _SC_2_LOCALEDEF
4622 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4623 #endif
4624 #ifdef _SC_2_SW_DEV
4625 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4626 #endif
4627 #ifdef _SC_2_UPE
4628 {"SC_2_UPE", _SC_2_UPE},
4629 #endif
4630 #ifdef _SC_2_VERSION
4631 {"SC_2_VERSION", _SC_2_VERSION},
4632 #endif
4633 #ifdef _SC_ABI_ASYNCHRONOUS_IO
4634 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4635 #endif
4636 #ifdef _SC_ACL
4637 {"SC_ACL", _SC_ACL},
4638 #endif
4639 #ifdef _SC_AIO_LISTIO_MAX
4640 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4641 #endif
4642 #ifdef _SC_AIO_MAX
4643 {"SC_AIO_MAX", _SC_AIO_MAX},
4644 #endif
4645 #ifdef _SC_AIO_PRIO_DELTA_MAX
4646 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4647 #endif
4648 #ifdef _SC_ARG_MAX
4649 {"SC_ARG_MAX", _SC_ARG_MAX},
4650 #endif
4651 #ifdef _SC_ASYNCHRONOUS_IO
4652 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4653 #endif
4654 #ifdef _SC_ATEXIT_MAX
4655 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4656 #endif
4657 #ifdef _SC_AUDIT
4658 {"SC_AUDIT", _SC_AUDIT},
4659 #endif
4660 #ifdef _SC_AVPHYS_PAGES
4661 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4662 #endif
4663 #ifdef _SC_BC_BASE_MAX
4664 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4665 #endif
4666 #ifdef _SC_BC_DIM_MAX
4667 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4668 #endif
4669 #ifdef _SC_BC_SCALE_MAX
4670 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4671 #endif
4672 #ifdef _SC_BC_STRING_MAX
4673 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4674 #endif
4675 #ifdef _SC_CAP
4676 {"SC_CAP", _SC_CAP},
4677 #endif
4678 #ifdef _SC_CHARCLASS_NAME_MAX
4679 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4680 #endif
4681 #ifdef _SC_CHAR_BIT
4682 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4683 #endif
4684 #ifdef _SC_CHAR_MAX
4685 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4686 #endif
4687 #ifdef _SC_CHAR_MIN
4688 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4689 #endif
4690 #ifdef _SC_CHILD_MAX
4691 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4692 #endif
4693 #ifdef _SC_CLK_TCK
4694 {"SC_CLK_TCK", _SC_CLK_TCK},
4695 #endif
4696 #ifdef _SC_COHER_BLKSZ
4697 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4698 #endif
4699 #ifdef _SC_COLL_WEIGHTS_MAX
4700 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4701 #endif
4702 #ifdef _SC_DCACHE_ASSOC
4703 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4704 #endif
4705 #ifdef _SC_DCACHE_BLKSZ
4706 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4707 #endif
4708 #ifdef _SC_DCACHE_LINESZ
4709 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4710 #endif
4711 #ifdef _SC_DCACHE_SZ
4712 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4713 #endif
4714 #ifdef _SC_DCACHE_TBLKSZ
4715 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4716 #endif
4717 #ifdef _SC_DELAYTIMER_MAX
4718 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4719 #endif
4720 #ifdef _SC_EQUIV_CLASS_MAX
4721 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4722 #endif
4723 #ifdef _SC_EXPR_NEST_MAX
4724 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4725 #endif
4726 #ifdef _SC_FSYNC
4727 {"SC_FSYNC", _SC_FSYNC},
4728 #endif
4729 #ifdef _SC_GETGR_R_SIZE_MAX
4730 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4731 #endif
4732 #ifdef _SC_GETPW_R_SIZE_MAX
4733 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4734 #endif
4735 #ifdef _SC_ICACHE_ASSOC
4736 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4737 #endif
4738 #ifdef _SC_ICACHE_BLKSZ
4739 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4740 #endif
4741 #ifdef _SC_ICACHE_LINESZ
4742 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4743 #endif
4744 #ifdef _SC_ICACHE_SZ
4745 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4746 #endif
4747 #ifdef _SC_INF
4748 {"SC_INF", _SC_INF},
4749 #endif
4750 #ifdef _SC_INT_MAX
4751 {"SC_INT_MAX", _SC_INT_MAX},
4752 #endif
4753 #ifdef _SC_INT_MIN
4754 {"SC_INT_MIN", _SC_INT_MIN},
4755 #endif
4756 #ifdef _SC_IOV_MAX
4757 {"SC_IOV_MAX", _SC_IOV_MAX},
4758 #endif
4759 #ifdef _SC_IP_SECOPTS
4760 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4761 #endif
4762 #ifdef _SC_JOB_CONTROL
4763 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4764 #endif
4765 #ifdef _SC_KERN_POINTERS
4766 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4767 #endif
4768 #ifdef _SC_KERN_SIM
4769 {"SC_KERN_SIM", _SC_KERN_SIM},
4770 #endif
4771 #ifdef _SC_LINE_MAX
4772 {"SC_LINE_MAX", _SC_LINE_MAX},
4773 #endif
4774 #ifdef _SC_LOGIN_NAME_MAX
4775 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4776 #endif
4777 #ifdef _SC_LOGNAME_MAX
4778 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4779 #endif
4780 #ifdef _SC_LONG_BIT
4781 {"SC_LONG_BIT", _SC_LONG_BIT},
4782 #endif
4783 #ifdef _SC_MAC
4784 {"SC_MAC", _SC_MAC},
4785 #endif
4786 #ifdef _SC_MAPPED_FILES
4787 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4788 #endif
4789 #ifdef _SC_MAXPID
4790 {"SC_MAXPID", _SC_MAXPID},
4791 #endif
4792 #ifdef _SC_MB_LEN_MAX
4793 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4794 #endif
4795 #ifdef _SC_MEMLOCK
4796 {"SC_MEMLOCK", _SC_MEMLOCK},
4797 #endif
4798 #ifdef _SC_MEMLOCK_RANGE
4799 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4800 #endif
4801 #ifdef _SC_MEMORY_PROTECTION
4802 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4803 #endif
4804 #ifdef _SC_MESSAGE_PASSING
4805 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4806 #endif
4807 #ifdef _SC_MMAP_FIXED_ALIGNMENT
4808 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4809 #endif
4810 #ifdef _SC_MQ_OPEN_MAX
4811 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4812 #endif
4813 #ifdef _SC_MQ_PRIO_MAX
4814 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4815 #endif
4816 #ifdef _SC_NACLS_MAX
4817 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4818 #endif
4819 #ifdef _SC_NGROUPS_MAX
4820 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4821 #endif
4822 #ifdef _SC_NL_ARGMAX
4823 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4824 #endif
4825 #ifdef _SC_NL_LANGMAX
4826 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4827 #endif
4828 #ifdef _SC_NL_MSGMAX
4829 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4830 #endif
4831 #ifdef _SC_NL_NMAX
4832 {"SC_NL_NMAX", _SC_NL_NMAX},
4833 #endif
4834 #ifdef _SC_NL_SETMAX
4835 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4836 #endif
4837 #ifdef _SC_NL_TEXTMAX
4838 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4839 #endif
4840 #ifdef _SC_NPROCESSORS_CONF
4841 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4842 #endif
4843 #ifdef _SC_NPROCESSORS_ONLN
4844 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4845 #endif
4846 #ifdef _SC_NPROC_CONF
4847 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4848 #endif
4849 #ifdef _SC_NPROC_ONLN
4850 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4851 #endif
4852 #ifdef _SC_NZERO
4853 {"SC_NZERO", _SC_NZERO},
4854 #endif
4855 #ifdef _SC_OPEN_MAX
4856 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4857 #endif
4858 #ifdef _SC_PAGESIZE
4859 {"SC_PAGESIZE", _SC_PAGESIZE},
4860 #endif
4861 #ifdef _SC_PAGE_SIZE
4862 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4863 #endif
4864 #ifdef _SC_PASS_MAX
4865 {"SC_PASS_MAX", _SC_PASS_MAX},
4866 #endif
4867 #ifdef _SC_PHYS_PAGES
4868 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4869 #endif
4870 #ifdef _SC_PII
4871 {"SC_PII", _SC_PII},
4872 #endif
4873 #ifdef _SC_PII_INTERNET
4874 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4875 #endif
4876 #ifdef _SC_PII_INTERNET_DGRAM
4877 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4878 #endif
4879 #ifdef _SC_PII_INTERNET_STREAM
4880 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4881 #endif
4882 #ifdef _SC_PII_OSI
4883 {"SC_PII_OSI", _SC_PII_OSI},
4884 #endif
4885 #ifdef _SC_PII_OSI_CLTS
4886 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4887 #endif
4888 #ifdef _SC_PII_OSI_COTS
4889 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4890 #endif
4891 #ifdef _SC_PII_OSI_M
4892 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4893 #endif
4894 #ifdef _SC_PII_SOCKET
4895 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4896 #endif
4897 #ifdef _SC_PII_XTI
4898 {"SC_PII_XTI", _SC_PII_XTI},
4899 #endif
4900 #ifdef _SC_POLL
4901 {"SC_POLL", _SC_POLL},
4902 #endif
4903 #ifdef _SC_PRIORITIZED_IO
4904 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4905 #endif
4906 #ifdef _SC_PRIORITY_SCHEDULING
4907 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4908 #endif
4909 #ifdef _SC_REALTIME_SIGNALS
4910 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4911 #endif
4912 #ifdef _SC_RE_DUP_MAX
4913 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4914 #endif
4915 #ifdef _SC_RTSIG_MAX
4916 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4917 #endif
4918 #ifdef _SC_SAVED_IDS
4919 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4920 #endif
4921 #ifdef _SC_SCHAR_MAX
4922 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4923 #endif
4924 #ifdef _SC_SCHAR_MIN
4925 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4926 #endif
4927 #ifdef _SC_SELECT
4928 {"SC_SELECT", _SC_SELECT},
4929 #endif
4930 #ifdef _SC_SEMAPHORES
4931 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4932 #endif
4933 #ifdef _SC_SEM_NSEMS_MAX
4934 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4935 #endif
4936 #ifdef _SC_SEM_VALUE_MAX
4937 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4938 #endif
4939 #ifdef _SC_SHARED_MEMORY_OBJECTS
4940 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4941 #endif
4942 #ifdef _SC_SHRT_MAX
4943 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4944 #endif
4945 #ifdef _SC_SHRT_MIN
4946 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4947 #endif
4948 #ifdef _SC_SIGQUEUE_MAX
4949 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4950 #endif
4951 #ifdef _SC_SIGRT_MAX
4952 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4953 #endif
4954 #ifdef _SC_SIGRT_MIN
4955 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4956 #endif
4957 #ifdef _SC_SOFTPOWER
4958 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4959 #endif
4960 #ifdef _SC_SPLIT_CACHE
4961 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4962 #endif
4963 #ifdef _SC_SSIZE_MAX
4964 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4965 #endif
4966 #ifdef _SC_STACK_PROT
4967 {"SC_STACK_PROT", _SC_STACK_PROT},
4968 #endif
4969 #ifdef _SC_STREAM_MAX
4970 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4971 #endif
4972 #ifdef _SC_SYNCHRONIZED_IO
4973 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4974 #endif
4975 #ifdef _SC_THREADS
4976 {"SC_THREADS", _SC_THREADS},
4977 #endif
4978 #ifdef _SC_THREAD_ATTR_STACKADDR
4979 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4980 #endif
4981 #ifdef _SC_THREAD_ATTR_STACKSIZE
4982 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4983 #endif
4984 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4985 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4986 #endif
4987 #ifdef _SC_THREAD_KEYS_MAX
4988 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4989 #endif
4990 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
4991 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4992 #endif
4993 #ifdef _SC_THREAD_PRIO_INHERIT
4994 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4995 #endif
4996 #ifdef _SC_THREAD_PRIO_PROTECT
4997 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4998 #endif
4999 #ifdef _SC_THREAD_PROCESS_SHARED
5000 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5001 #endif
5002 #ifdef _SC_THREAD_SAFE_FUNCTIONS
5003 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5004 #endif
5005 #ifdef _SC_THREAD_STACK_MIN
5006 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5007 #endif
5008 #ifdef _SC_THREAD_THREADS_MAX
5009 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5010 #endif
5011 #ifdef _SC_TIMERS
5012 {"SC_TIMERS", _SC_TIMERS},
5013 #endif
5014 #ifdef _SC_TIMER_MAX
5015 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5016 #endif
5017 #ifdef _SC_TTY_NAME_MAX
5018 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5019 #endif
5020 #ifdef _SC_TZNAME_MAX
5021 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5022 #endif
5023 #ifdef _SC_T_IOV_MAX
5024 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5025 #endif
5026 #ifdef _SC_UCHAR_MAX
5027 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5028 #endif
5029 #ifdef _SC_UINT_MAX
5030 {"SC_UINT_MAX", _SC_UINT_MAX},
5031 #endif
5032 #ifdef _SC_UIO_MAXIOV
5033 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5034 #endif
5035 #ifdef _SC_ULONG_MAX
5036 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5037 #endif
5038 #ifdef _SC_USHRT_MAX
5039 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5040 #endif
5041 #ifdef _SC_VERSION
5042 {"SC_VERSION", _SC_VERSION},
5043 #endif
5044 #ifdef _SC_WORD_BIT
5045 {"SC_WORD_BIT", _SC_WORD_BIT},
5046 #endif
5047 #ifdef _SC_XBS5_ILP32_OFF32
5048 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5049 #endif
5050 #ifdef _SC_XBS5_ILP32_OFFBIG
5051 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5052 #endif
5053 #ifdef _SC_XBS5_LP64_OFF64
5054 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5055 #endif
5056 #ifdef _SC_XBS5_LPBIG_OFFBIG
5057 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5058 #endif
5059 #ifdef _SC_XOPEN_CRYPT
5060 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5061 #endif
5062 #ifdef _SC_XOPEN_ENH_I18N
5063 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5064 #endif
5065 #ifdef _SC_XOPEN_LEGACY
5066 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5067 #endif
5068 #ifdef _SC_XOPEN_REALTIME
5069 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5070 #endif
5071 #ifdef _SC_XOPEN_REALTIME_THREADS
5072 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5073 #endif
5074 #ifdef _SC_XOPEN_SHM
5075 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5076 #endif
5077 #ifdef _SC_XOPEN_UNIX
5078 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5079 #endif
5080 #ifdef _SC_XOPEN_VERSION
5081 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5082 #endif
5083 #ifdef _SC_XOPEN_XCU_VERSION
5084 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5085 #endif
5086 #ifdef _SC_XOPEN_XPG2
5087 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5088 #endif
5089 #ifdef _SC_XOPEN_XPG3
5090 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5091 #endif
5092 #ifdef _SC_XOPEN_XPG4
5093 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5094 #endif
5097 static int
5098 conv_sysconf_confname(PyObject *arg, int *valuep)
5100 return conv_confname(arg, valuep, posix_constants_sysconf,
5101 sizeof(posix_constants_sysconf)
5102 / sizeof(struct constdef));
5105 static char posix_sysconf__doc__[] = "\
5106 sysconf(name) -> integer\n\
5107 Return an integer-valued system configuration variable.";
5109 static PyObject *
5110 posix_sysconf(PyObject *self, PyObject *args)
5112 PyObject *result = NULL;
5113 int name;
5115 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5116 int value;
5118 errno = 0;
5119 value = sysconf(name);
5120 if (value == -1 && errno != 0)
5121 posix_error();
5122 else
5123 result = PyInt_FromLong(value);
5125 return result;
5127 #endif
5130 /* This code is used to ensure that the tables of configuration value names
5131 * are in sorted order as required by conv_confname(), and also to build the
5132 * the exported dictionaries that are used to publish information about the
5133 * names available on the host platform.
5135 * Sorting the table at runtime ensures that the table is properly ordered
5136 * when used, even for platforms we're not able to test on. It also makes
5137 * it easier to add additional entries to the tables.
5140 static int
5141 cmp_constdefs(const void *v1, const void *v2)
5143 const struct constdef *c1 =
5144 (const struct constdef *) v1;
5145 const struct constdef *c2 =
5146 (const struct constdef *) v2;
5148 return strcmp(c1->name, c2->name);
5151 static int
5152 setup_confname_table(struct constdef *table, size_t tablesize,
5153 char *tablename, PyObject *moddict)
5155 PyObject *d = NULL;
5156 size_t i;
5157 int status;
5159 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5160 d = PyDict_New();
5161 if (d == NULL)
5162 return -1;
5164 for (i=0; i < tablesize; ++i) {
5165 PyObject *o = PyInt_FromLong(table[i].value);
5166 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5167 Py_XDECREF(o);
5168 Py_DECREF(d);
5169 return -1;
5171 Py_DECREF(o);
5173 status = PyDict_SetItemString(moddict, tablename, d);
5174 Py_DECREF(d);
5175 return status;
5178 /* Return -1 on failure, 0 on success. */
5179 static int
5180 setup_confname_tables(PyObject *moddict)
5182 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5183 if (setup_confname_table(posix_constants_pathconf,
5184 sizeof(posix_constants_pathconf)
5185 / sizeof(struct constdef),
5186 "pathconf_names", moddict))
5187 return -1;
5188 #endif
5189 #ifdef HAVE_CONFSTR
5190 if (setup_confname_table(posix_constants_confstr,
5191 sizeof(posix_constants_confstr)
5192 / sizeof(struct constdef),
5193 "confstr_names", moddict))
5194 return -1;
5195 #endif
5196 #ifdef HAVE_SYSCONF
5197 if (setup_confname_table(posix_constants_sysconf,
5198 sizeof(posix_constants_sysconf)
5199 / sizeof(struct constdef),
5200 "sysconf_names", moddict))
5201 return -1;
5202 #endif
5203 return 0;
5207 static char posix_abort__doc__[] = "\
5208 abort() -> does not return!\n\
5209 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5210 in the hardest way possible on the hosting operating system.";
5212 static PyObject *
5213 posix_abort(PyObject *self, PyObject *args)
5215 if (!PyArg_ParseTuple(args, ":abort"))
5216 return NULL;
5217 abort();
5218 /*NOTREACHED*/
5219 Py_FatalError("abort() called from Python code didn't abort!");
5220 return NULL;
5223 #ifdef MS_WIN32
5224 static char win32_startfile__doc__[] = "\
5225 startfile(filepath) - Start a file with its associated application.\n\
5227 This acts like double-clicking the file in Explorer, or giving the file\n\
5228 name as an argument to the DOS \"start\" command: the file is opened\n\
5229 with whatever application (if any) its extension is associated.\n\
5231 startfile returns as soon as the associated application is launched.\n\
5232 There is no option to wait for the application to close, and no way\n\
5233 to retrieve the application's exit status.\n\
5235 The filepath is relative to the current directory. If you want to use\n\
5236 an absolute path, make sure the first character is not a slash (\"/\");\n\
5237 the underlying Win32 ShellExecute function doesn't work if it is.";
5239 static PyObject *
5240 win32_startfile(PyObject *self, PyObject *args)
5242 char *filepath;
5243 HINSTANCE rc;
5244 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5245 return NULL;
5246 Py_BEGIN_ALLOW_THREADS
5247 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5248 Py_END_ALLOW_THREADS
5249 if (rc <= (HINSTANCE)32)
5250 return win32_error("startfile", filepath);
5251 Py_INCREF(Py_None);
5252 return Py_None;
5254 #endif
5256 static PyMethodDef posix_methods[] = {
5257 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5258 #ifdef HAVE_TTYNAME
5259 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5260 #endif
5261 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5262 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
5263 #ifdef HAVE_CHOWN
5264 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
5265 #endif /* HAVE_CHOWN */
5266 #ifdef HAVE_CTERMID
5267 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5268 #endif
5269 #ifdef HAVE_GETCWD
5270 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
5271 #endif
5272 #ifdef HAVE_LINK
5273 {"link", posix_link, METH_VARARGS, posix_link__doc__},
5274 #endif /* HAVE_LINK */
5275 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5276 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5277 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
5278 #ifdef HAVE_NICE
5279 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
5280 #endif /* HAVE_NICE */
5281 #ifdef HAVE_READLINK
5282 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
5283 #endif /* HAVE_READLINK */
5284 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5285 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5286 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
5287 #ifdef HAVE_SYMLINK
5288 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
5289 #endif /* HAVE_SYMLINK */
5290 #ifdef HAVE_SYSTEM
5291 {"system", posix_system, METH_VARARGS, posix_system__doc__},
5292 #endif
5293 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
5294 #ifdef HAVE_UNAME
5295 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
5296 #endif /* HAVE_UNAME */
5297 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5298 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5299 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
5300 #ifdef HAVE_TIMES
5301 {"times", posix_times, METH_VARARGS, posix_times__doc__},
5302 #endif /* HAVE_TIMES */
5303 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
5304 #ifdef HAVE_EXECV
5305 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5306 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
5307 #endif /* HAVE_EXECV */
5308 #ifdef HAVE_SPAWNV
5309 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5310 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
5311 #endif /* HAVE_SPAWNV */
5312 #ifdef HAVE_FORK1
5313 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5314 #endif /* HAVE_FORK1 */
5315 #ifdef HAVE_FORK
5316 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
5317 #endif /* HAVE_FORK */
5318 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
5319 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
5320 #endif /* HAVE_OPENPTY || HAVE__GETPTY */
5321 #ifdef HAVE_FORKPTY
5322 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5323 #endif /* HAVE_FORKPTY */
5324 #ifdef HAVE_GETEGID
5325 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
5326 #endif /* HAVE_GETEGID */
5327 #ifdef HAVE_GETEUID
5328 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
5329 #endif /* HAVE_GETEUID */
5330 #ifdef HAVE_GETGID
5331 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
5332 #endif /* HAVE_GETGID */
5333 #ifdef HAVE_GETGROUPS
5334 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5335 #endif
5336 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
5337 #ifdef HAVE_GETPGRP
5338 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
5339 #endif /* HAVE_GETPGRP */
5340 #ifdef HAVE_GETPPID
5341 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
5342 #endif /* HAVE_GETPPID */
5343 #ifdef HAVE_GETUID
5344 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
5345 #endif /* HAVE_GETUID */
5346 #ifdef HAVE_GETLOGIN
5347 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5348 #endif
5349 #ifdef HAVE_KILL
5350 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
5351 #endif /* HAVE_KILL */
5352 #ifdef HAVE_PLOCK
5353 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
5354 #endif /* HAVE_PLOCK */
5355 #ifdef HAVE_POPEN
5356 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
5357 #ifdef MS_WIN32
5358 {"popen2", win32_popen2, METH_VARARGS},
5359 {"popen3", win32_popen3, METH_VARARGS},
5360 {"popen4", win32_popen4, METH_VARARGS},
5361 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
5362 #endif
5363 #endif /* HAVE_POPEN */
5364 #ifdef HAVE_SETUID
5365 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
5366 #endif /* HAVE_SETUID */
5367 #ifdef HAVE_SETEUID
5368 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5369 #endif /* HAVE_SETEUID */
5370 #ifdef HAVE_SETEGID
5371 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5372 #endif /* HAVE_SETEGID */
5373 #ifdef HAVE_SETREUID
5374 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5375 #endif /* HAVE_SETREUID */
5376 #ifdef HAVE_SETREGID
5377 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5378 #endif /* HAVE_SETREGID */
5379 #ifdef HAVE_SETGID
5380 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
5381 #endif /* HAVE_SETGID */
5382 #ifdef HAVE_SETPGRP
5383 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
5384 #endif /* HAVE_SETPGRP */
5385 #ifdef HAVE_WAIT
5386 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
5387 #endif /* HAVE_WAIT */
5388 #ifdef HAVE_WAITPID
5389 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
5390 #endif /* HAVE_WAITPID */
5391 #ifdef HAVE_SETSID
5392 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
5393 #endif /* HAVE_SETSID */
5394 #ifdef HAVE_SETPGID
5395 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
5396 #endif /* HAVE_SETPGID */
5397 #ifdef HAVE_TCGETPGRP
5398 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
5399 #endif /* HAVE_TCGETPGRP */
5400 #ifdef HAVE_TCSETPGRP
5401 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
5402 #endif /* HAVE_TCSETPGRP */
5403 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5404 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5405 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5406 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5407 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5408 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5409 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5410 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5411 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
5412 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
5413 #ifdef HAVE_PIPE
5414 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
5415 #endif
5416 #ifdef HAVE_MKFIFO
5417 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
5418 #endif
5419 #ifdef HAVE_FTRUNCATE
5420 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
5421 #endif
5422 #ifdef HAVE_PUTENV
5423 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
5424 #endif
5425 #ifdef HAVE_STRERROR
5426 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
5427 #endif
5428 #ifdef HAVE_FSYNC
5429 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
5430 #endif
5431 #ifdef HAVE_FDATASYNC
5432 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
5433 #endif
5434 #ifdef HAVE_SYS_WAIT_H
5435 #ifdef WIFSTOPPED
5436 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
5437 #endif /* WIFSTOPPED */
5438 #ifdef WIFSIGNALED
5439 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
5440 #endif /* WIFSIGNALED */
5441 #ifdef WIFEXITED
5442 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
5443 #endif /* WIFEXITED */
5444 #ifdef WEXITSTATUS
5445 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
5446 #endif /* WEXITSTATUS */
5447 #ifdef WTERMSIG
5448 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
5449 #endif /* WTERMSIG */
5450 #ifdef WSTOPSIG
5451 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
5452 #endif /* WSTOPSIG */
5453 #endif /* HAVE_SYS_WAIT_H */
5454 #ifdef HAVE_FSTATVFS
5455 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
5456 #endif
5457 #ifdef HAVE_STATVFS
5458 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
5459 #endif
5460 #ifdef HAVE_TMPFILE
5461 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5462 #endif
5463 #ifdef HAVE_TEMPNAM
5464 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5465 #endif
5466 #ifdef HAVE_TMPNAM
5467 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5468 #endif
5469 #ifdef HAVE_CONFSTR
5470 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5471 #endif
5472 #ifdef HAVE_SYSCONF
5473 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5474 #endif
5475 #ifdef HAVE_FPATHCONF
5476 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5477 #endif
5478 #ifdef HAVE_PATHCONF
5479 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5480 #endif
5481 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
5482 {NULL, NULL} /* Sentinel */
5486 static int
5487 ins(PyObject *d, char *symbol, long value)
5489 PyObject* v = PyInt_FromLong(value);
5490 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5491 return -1; /* triggers fatal error */
5493 Py_DECREF(v);
5494 return 0;
5497 #if defined(PYOS_OS2)
5498 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5499 static int insertvalues(PyObject *d)
5501 APIRET rc;
5502 ULONG values[QSV_MAX+1];
5503 PyObject *v;
5504 char *ver, tmp[10];
5506 Py_BEGIN_ALLOW_THREADS
5507 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5508 Py_END_ALLOW_THREADS
5510 if (rc != NO_ERROR) {
5511 os2_error(rc);
5512 return -1;
5515 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5516 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5517 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5518 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5519 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5520 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5521 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5523 switch (values[QSV_VERSION_MINOR]) {
5524 case 0: ver = "2.00"; break;
5525 case 10: ver = "2.10"; break;
5526 case 11: ver = "2.11"; break;
5527 case 30: ver = "3.00"; break;
5528 case 40: ver = "4.00"; break;
5529 case 50: ver = "5.00"; break;
5530 default:
5531 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5532 values[QSV_VERSION_MINOR]);
5533 ver = &tmp[0];
5536 /* Add Indicator of the Version of the Operating System */
5537 v = PyString_FromString(ver);
5538 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5539 return -1;
5540 Py_DECREF(v);
5542 /* Add Indicator of Which Drive was Used to Boot the System */
5543 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5544 tmp[1] = ':';
5545 tmp[2] = '\0';
5547 v = PyString_FromString(tmp);
5548 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5549 return -1;
5550 Py_DECREF(v);
5552 return 0;
5554 #endif
5556 static int
5557 all_ins(PyObject *d)
5559 #ifdef F_OK
5560 if (ins(d, "F_OK", (long)F_OK)) return -1;
5561 #endif
5562 #ifdef R_OK
5563 if (ins(d, "R_OK", (long)R_OK)) return -1;
5564 #endif
5565 #ifdef W_OK
5566 if (ins(d, "W_OK", (long)W_OK)) return -1;
5567 #endif
5568 #ifdef X_OK
5569 if (ins(d, "X_OK", (long)X_OK)) return -1;
5570 #endif
5571 #ifdef NGROUPS_MAX
5572 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5573 #endif
5574 #ifdef TMP_MAX
5575 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5576 #endif
5577 #ifdef WNOHANG
5578 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5579 #endif
5580 #ifdef O_RDONLY
5581 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5582 #endif
5583 #ifdef O_WRONLY
5584 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5585 #endif
5586 #ifdef O_RDWR
5587 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5588 #endif
5589 #ifdef O_NDELAY
5590 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5591 #endif
5592 #ifdef O_NONBLOCK
5593 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5594 #endif
5595 #ifdef O_APPEND
5596 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5597 #endif
5598 #ifdef O_DSYNC
5599 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5600 #endif
5601 #ifdef O_RSYNC
5602 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5603 #endif
5604 #ifdef O_SYNC
5605 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5606 #endif
5607 #ifdef O_NOCTTY
5608 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5609 #endif
5610 #ifdef O_CREAT
5611 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5612 #endif
5613 #ifdef O_EXCL
5614 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5615 #endif
5616 #ifdef O_TRUNC
5617 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5618 #endif
5619 #ifdef O_BINARY
5620 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5621 #endif
5622 #ifdef O_TEXT
5623 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5624 #endif
5626 #ifdef HAVE_SPAWNV
5627 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5628 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5629 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5630 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5631 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
5632 #endif
5634 #if defined(PYOS_OS2)
5635 if (insertvalues(d)) return -1;
5636 #endif
5637 return 0;
5641 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
5642 #define INITFUNC initnt
5643 #define MODNAME "nt"
5645 #elif defined(PYOS_OS2)
5646 #define INITFUNC initos2
5647 #define MODNAME "os2"
5649 #else
5650 #define INITFUNC initposix
5651 #define MODNAME "posix"
5652 #endif
5654 DL_EXPORT(void)
5655 INITFUNC(void)
5657 PyObject *m, *d, *v;
5659 m = Py_InitModule4(MODNAME,
5660 posix_methods,
5661 posix__doc__,
5662 (PyObject *)NULL,
5663 PYTHON_API_VERSION);
5664 d = PyModule_GetDict(m);
5666 /* Initialize environ dictionary */
5667 v = convertenviron();
5668 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
5669 return;
5670 Py_DECREF(v);
5672 if (all_ins(d))
5673 return;
5675 if (setup_confname_tables(d))
5676 return;
5678 PyDict_SetItemString(d, "error", PyExc_OSError);
5680 #ifdef HAVE_PUTENV
5681 if (posix_putenv_garbage == NULL)
5682 posix_putenv_garbage = PyDict_New();
5683 #endif