Updated for 2.1b2 distribution.
[python/dscho.git] / Modules / posixmodule.c
blobce77673a143fdf83ec1c5cc3869ec7b23a81716b
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_GETEGID 1
67 #define HAVE_GETEUID 1
68 #define HAVE_GETGID 1
69 #define HAVE_GETPPID 1
70 #define HAVE_GETUID 1
71 #define HAVE_KILL 1
72 #define HAVE_OPENDIR 1
73 #define HAVE_PIPE 1
74 #define HAVE_POPEN 1
75 #define HAVE_SYSTEM 1
76 #define HAVE_WAIT 1
77 #else
78 #ifdef _MSC_VER /* Microsoft compiler */
79 #define HAVE_GETCWD 1
80 #ifdef MS_WIN32
81 #define HAVE_SPAWNV 1
82 #define HAVE_EXECV 1
83 #define HAVE_PIPE 1
84 #define HAVE_POPEN 1
85 #define HAVE_SYSTEM 1
86 #else /* 16-bit Windows */
87 #endif /* !MS_WIN32 */
88 #else /* all other compilers */
89 /* Unix functions that the configure script doesn't check for */
90 #define HAVE_EXECV 1
91 #define HAVE_FORK 1
92 #define HAVE_GETCWD 1
93 #define HAVE_GETEGID 1
94 #define HAVE_GETEUID 1
95 #define HAVE_GETGID 1
96 #define HAVE_GETPPID 1
97 #define HAVE_GETUID 1
98 #define HAVE_KILL 1
99 #define HAVE_OPENDIR 1
100 #define HAVE_PIPE 1
101 #define HAVE_POPEN 1
102 #define HAVE_SYSTEM 1
103 #define HAVE_WAIT 1
104 #define HAVE_TTYNAME 1
105 #endif /* _MSC_VER */
106 #endif /* __BORLANDC__ */
107 #endif /* ! __WATCOMC__ || __QNX__ */
108 #endif /* ! __IBMC__ */
110 #ifndef _MSC_VER
112 #ifdef HAVE_UNISTD_H
113 #include <unistd.h>
114 #endif
116 #if defined(sun) && !defined(__SVR4)
117 /* SunOS 4.1.4 doesn't have prototypes for these: */
118 extern int rename(const char *, const char *);
119 extern int pclose(FILE *);
120 extern int fclose(FILE *);
121 extern int fsync(int);
122 extern int lstat(const char *, struct stat *);
123 extern int symlink(const char *, const char *);
124 #endif
126 #ifdef NeXT
127 /* NeXT's <unistd.h> and <utime.h> aren't worth much */
128 #undef HAVE_UNISTD_H
129 #undef HAVE_UTIME_H
130 #define HAVE_WAITPID
131 /* #undef HAVE_GETCWD */
132 #define UNION_WAIT /* This should really be checked for by autoconf */
133 #endif
135 #ifndef HAVE_UNISTD_H
136 #if defined(PYCC_VACPP)
137 extern int mkdir(char *);
138 #else
139 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
140 extern int mkdir(const char *);
141 #else
142 extern int mkdir(const char *, mode_t);
143 #endif
144 #endif
145 #if defined(__IBMC__) || defined(__IBMCPP__)
146 extern int chdir(char *);
147 extern int rmdir(char *);
148 #else
149 extern int chdir(const char *);
150 extern int rmdir(const char *);
151 #endif
152 extern int chmod(const char *, mode_t);
153 extern int chown(const char *, uid_t, gid_t);
154 extern char *getcwd(char *, int);
155 extern char *strerror(int);
156 extern int link(const char *, const char *);
157 extern int rename(const char *, const char *);
158 extern int stat(const char *, struct stat *);
159 extern int unlink(const char *);
160 extern int pclose(FILE *);
161 #ifdef HAVE_SYMLINK
162 extern int symlink(const char *, const char *);
163 #endif /* HAVE_SYMLINK */
164 #ifdef HAVE_LSTAT
165 extern int lstat(const char *, struct stat *);
166 #endif /* HAVE_LSTAT */
167 #endif /* !HAVE_UNISTD_H */
169 #endif /* !_MSC_VER */
171 #ifdef HAVE_UTIME_H
172 #include <utime.h>
173 #endif /* HAVE_UTIME_H */
175 #ifdef HAVE_SYS_UTIME_H
176 #include <sys/utime.h>
177 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
178 #endif /* HAVE_SYS_UTIME_H */
180 #ifdef HAVE_SYS_TIMES_H
181 #include <sys/times.h>
182 #endif /* HAVE_SYS_TIMES_H */
184 #ifdef HAVE_SYS_PARAM_H
185 #include <sys/param.h>
186 #endif /* HAVE_SYS_PARAM_H */
188 #ifdef HAVE_SYS_UTSNAME_H
189 #include <sys/utsname.h>
190 #endif /* HAVE_SYS_UTSNAME_H */
192 #ifndef MAXPATHLEN
193 #define MAXPATHLEN 1024
194 #endif /* MAXPATHLEN */
196 #ifdef HAVE_DIRENT_H
197 #include <dirent.h>
198 #define NAMLEN(dirent) strlen((dirent)->d_name)
199 #else
200 #if defined(__WATCOMC__) && !defined(__QNX__)
201 #include <direct.h>
202 #define NAMLEN(dirent) strlen((dirent)->d_name)
203 #else
204 #define dirent direct
205 #define NAMLEN(dirent) (dirent)->d_namlen
206 #endif
207 #ifdef HAVE_SYS_NDIR_H
208 #include <sys/ndir.h>
209 #endif
210 #ifdef HAVE_SYS_DIR_H
211 #include <sys/dir.h>
212 #endif
213 #ifdef HAVE_NDIR_H
214 #include <ndir.h>
215 #endif
216 #endif
218 #ifdef _MSC_VER
219 #include <direct.h>
220 #include <io.h>
221 #include <process.h>
222 #define WINDOWS_LEAN_AND_MEAN
223 #include <windows.h>
224 #ifdef MS_WIN32
225 #define popen _popen
226 #define pclose _pclose
227 #else /* 16-bit Windows */
228 #include <dos.h>
229 #include <ctype.h>
230 #endif /* MS_WIN32 */
231 #endif /* _MSC_VER */
233 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
234 #include <io.h>
235 #endif /* OS2 */
237 #ifdef UNION_WAIT
238 /* Emulate some macros on systems that have a union instead of macros */
240 #ifndef WIFEXITED
241 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
242 #endif
244 #ifndef WEXITSTATUS
245 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
246 #endif
248 #ifndef WTERMSIG
249 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
250 #endif
252 #endif /* UNION_WAIT */
254 /* Don't use the "_r" form if we don't need it (also, won't have a
255 prototype for it, at least on Solaris -- maybe others as well?). */
256 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
257 #define USE_CTERMID_R
258 #endif
260 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
261 #define USE_TMPNAM_R
262 #endif
264 /* choose the appropriate stat and fstat functions and return structs */
265 #undef STAT
266 #ifdef MS_WIN64
267 # define STAT _stati64
268 # define FSTAT _fstati64
269 # define STRUCT_STAT struct _stati64
270 #else
271 # define STAT stat
272 # define FSTAT fstat
273 # define STRUCT_STAT struct stat
274 #endif
277 /* Return a dictionary corresponding to the POSIX environment table */
279 #if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
280 extern char **environ;
281 #endif /* !_MSC_VER */
283 static PyObject *
284 convertenviron(void)
286 PyObject *d;
287 char **e;
288 d = PyDict_New();
289 if (d == NULL)
290 return NULL;
291 if (environ == NULL)
292 return d;
293 /* This part ignores errors */
294 for (e = environ; *e != NULL; e++) {
295 PyObject *k;
296 PyObject *v;
297 char *p = strchr(*e, '=');
298 if (p == NULL)
299 continue;
300 k = PyString_FromStringAndSize(*e, (int)(p-*e));
301 if (k == NULL) {
302 PyErr_Clear();
303 continue;
305 v = PyString_FromString(p+1);
306 if (v == NULL) {
307 PyErr_Clear();
308 Py_DECREF(k);
309 continue;
311 if (PyDict_GetItem(d, k) == NULL) {
312 if (PyDict_SetItem(d, k, v) != 0)
313 PyErr_Clear();
315 Py_DECREF(k);
316 Py_DECREF(v);
318 #if defined(PYOS_OS2)
320 APIRET rc;
321 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
323 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
324 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
325 PyObject *v = PyString_FromString(buffer);
326 PyDict_SetItemString(d, "BEGINLIBPATH", v);
327 Py_DECREF(v);
329 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
330 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
331 PyObject *v = PyString_FromString(buffer);
332 PyDict_SetItemString(d, "ENDLIBPATH", v);
333 Py_DECREF(v);
336 #endif
337 return d;
341 /* Set a POSIX-specific error from errno, and return NULL */
343 static PyObject *
344 posix_error(void)
346 return PyErr_SetFromErrno(PyExc_OSError);
348 static PyObject *
349 posix_error_with_filename(char* name)
351 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
354 #ifdef MS_WIN32
355 static PyObject *
356 win32_error(char* function, char* filename)
358 /* XXX We should pass the function name along in the future.
359 (_winreg.c also wants to pass the function name.)
360 This would however require an additional param to the
361 Windows error object, which is non-trivial.
363 errno = GetLastError();
364 if (filename)
365 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
366 else
367 return PyErr_SetFromWindowsErr(errno);
369 #endif
371 #if defined(PYOS_OS2)
372 /**********************************************************************
373 * Helper Function to Trim and Format OS/2 Messages
374 **********************************************************************/
375 static void
376 os2_formatmsg(char *msgbuf, int msglen, char *reason)
378 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
380 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
381 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
383 while (lastc > msgbuf && isspace(*lastc))
384 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
387 /* Add Optional Reason Text */
388 if (reason) {
389 strcat(msgbuf, " : ");
390 strcat(msgbuf, reason);
394 /**********************************************************************
395 * Decode an OS/2 Operating System Error Code
397 * A convenience function to lookup an OS/2 error code and return a
398 * text message we can use to raise a Python exception.
400 * Notes:
401 * The messages for errors returned from the OS/2 kernel reside in
402 * the file OSO001.MSG in the \OS2 directory hierarchy.
404 **********************************************************************/
405 static char *
406 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
408 APIRET rc;
409 ULONG msglen;
411 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
412 Py_BEGIN_ALLOW_THREADS
413 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
414 errorcode, "oso001.msg", &msglen);
415 Py_END_ALLOW_THREADS
417 if (rc == NO_ERROR)
418 os2_formatmsg(msgbuf, msglen, reason);
419 else
420 sprintf(msgbuf, "unknown OS error #%d", errorcode);
422 return msgbuf;
425 /* Set an OS/2-specific error and return NULL. OS/2 kernel
426 errors are not in a global variable e.g. 'errno' nor are
427 they congruent with posix error numbers. */
429 static PyObject * os2_error(int code)
431 char text[1024];
432 PyObject *v;
434 os2_strerror(text, sizeof(text), code, "");
436 v = Py_BuildValue("(is)", code, text);
437 if (v != NULL) {
438 PyErr_SetObject(PyExc_OSError, v);
439 Py_DECREF(v);
441 return NULL; /* Signal to Python that an Exception is Pending */
444 #endif /* OS2 */
446 /* POSIX generic methods */
448 static PyObject *
449 posix_int(PyObject *args, char *format, int (*func)(int))
451 int fd;
452 int res;
453 if (!PyArg_ParseTuple(args, format, &fd))
454 return NULL;
455 Py_BEGIN_ALLOW_THREADS
456 res = (*func)(fd);
457 Py_END_ALLOW_THREADS
458 if (res < 0)
459 return posix_error();
460 Py_INCREF(Py_None);
461 return Py_None;
465 static PyObject *
466 posix_1str(PyObject *args, char *format, int (*func)(const char*))
468 char *path1;
469 int res;
470 if (!PyArg_ParseTuple(args, format, &path1))
471 return NULL;
472 Py_BEGIN_ALLOW_THREADS
473 res = (*func)(path1);
474 Py_END_ALLOW_THREADS
475 if (res < 0)
476 return posix_error_with_filename(path1);
477 Py_INCREF(Py_None);
478 return Py_None;
481 static PyObject *
482 posix_2str(PyObject *args, char *format,
483 int (*func)(const char *, const char *))
485 char *path1, *path2;
486 int res;
487 if (!PyArg_ParseTuple(args, format, &path1, &path2))
488 return NULL;
489 Py_BEGIN_ALLOW_THREADS
490 res = (*func)(path1, path2);
491 Py_END_ALLOW_THREADS
492 if (res != 0)
493 /* XXX how to report both path1 and path2??? */
494 return posix_error();
495 Py_INCREF(Py_None);
496 return Py_None;
499 /* pack a system stat C structure into the Python stat tuple
500 (used by posix_stat() and posix_fstat()) */
501 static PyObject*
502 _pystat_fromstructstat(STRUCT_STAT st)
504 PyObject *v = PyTuple_New(10);
505 if (v == NULL)
506 return NULL;
508 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
509 #ifdef HAVE_LARGEFILE_SUPPORT
510 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
511 #else
512 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
513 #endif
514 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
515 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
516 #else
517 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
518 #endif
519 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
520 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
521 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
522 #ifdef HAVE_LARGEFILE_SUPPORT
523 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
524 #else
525 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
526 #endif
527 #if SIZEOF_TIME_T > SIZEOF_LONG
528 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
529 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
530 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
531 #else
532 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
533 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
534 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
535 #endif
537 if (PyErr_Occurred()) {
538 Py_DECREF(v);
539 return NULL;
542 return v;
546 static PyObject *
547 posix_do_stat(PyObject *self, PyObject *args, char *format,
548 int (*statfunc)(const char *, STRUCT_STAT *))
550 STRUCT_STAT st;
551 char *path;
552 int res;
554 #ifdef MS_WIN32
555 int pathlen;
556 char pathcopy[MAX_PATH];
557 #endif /* MS_WIN32 */
559 if (!PyArg_ParseTuple(args, format, &path))
560 return NULL;
562 #ifdef MS_WIN32
563 pathlen = strlen(path);
564 /* the library call can blow up if the file name is too long! */
565 if (pathlen > MAX_PATH) {
566 errno = ENAMETOOLONG;
567 return posix_error();
570 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
571 /* exception for specific or current drive root */
572 if (!((pathlen == 1) ||
573 ((pathlen == 3) &&
574 (path[1] == ':') &&
575 (path[2] == '\\' || path[2] == '/'))))
577 strncpy(pathcopy, path, pathlen);
578 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
579 path = pathcopy;
582 #endif /* MS_WIN32 */
584 Py_BEGIN_ALLOW_THREADS
585 res = (*statfunc)(path, &st);
586 Py_END_ALLOW_THREADS
587 if (res != 0)
588 return posix_error_with_filename(path);
590 return _pystat_fromstructstat(st);
594 /* POSIX methods */
596 static char posix_access__doc__[] =
597 "access(path, mode) -> 1 if granted, 0 otherwise\n\
598 Test for access to a file.";
600 static PyObject *
601 posix_access(PyObject *self, PyObject *args)
603 char *path;
604 int mode;
605 int res;
607 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
608 return NULL;
609 Py_BEGIN_ALLOW_THREADS
610 res = access(path, mode);
611 Py_END_ALLOW_THREADS
612 return(PyInt_FromLong(res == 0 ? 1L : 0L));
615 #ifndef F_OK
616 #define F_OK 0
617 #endif
618 #ifndef R_OK
619 #define R_OK 4
620 #endif
621 #ifndef W_OK
622 #define W_OK 2
623 #endif
624 #ifndef X_OK
625 #define X_OK 1
626 #endif
628 #ifdef HAVE_TTYNAME
629 static char posix_ttyname__doc__[] =
630 "ttyname(fd) -> String\n\
631 Return the name of the terminal device connected to 'fd'.";
633 static PyObject *
634 posix_ttyname(PyObject *self, PyObject *args)
636 int id;
637 char *ret;
639 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
640 return NULL;
642 ret = ttyname(id);
643 if (ret == NULL)
644 return(posix_error());
645 return(PyString_FromString(ret));
647 #endif
649 #ifdef HAVE_CTERMID
650 static char posix_ctermid__doc__[] =
651 "ctermid() -> String\n\
652 Return the name of the controlling terminal for this process.";
654 static PyObject *
655 posix_ctermid(PyObject *self, PyObject *args)
657 char *ret;
658 char buffer[L_ctermid];
660 if (!PyArg_ParseTuple(args, ":ctermid"))
661 return NULL;
663 #ifdef USE_CTERMID_R
664 ret = ctermid_r(buffer);
665 #else
666 ret = ctermid(buffer);
667 #endif
668 if (ret == NULL)
669 return(posix_error());
670 return(PyString_FromString(buffer));
672 #endif
674 static char posix_chdir__doc__[] =
675 "chdir(path) -> None\n\
676 Change the current working directory to the specified path.";
678 static PyObject *
679 posix_chdir(PyObject *self, PyObject *args)
681 return posix_1str(args, "s:chdir", chdir);
685 static char posix_chmod__doc__[] =
686 "chmod(path, mode) -> None\n\
687 Change the access permissions of a file.";
689 static PyObject *
690 posix_chmod(PyObject *self, PyObject *args)
692 char *path;
693 int i;
694 int res;
695 if (!PyArg_ParseTuple(args, "si", &path, &i))
696 return NULL;
697 Py_BEGIN_ALLOW_THREADS
698 res = chmod(path, i);
699 Py_END_ALLOW_THREADS
700 if (res < 0)
701 return posix_error_with_filename(path);
702 Py_INCREF(Py_None);
703 return Py_None;
707 #ifdef HAVE_FSYNC
708 static char posix_fsync__doc__[] =
709 "fsync(fildes) -> None\n\
710 force write of file with filedescriptor to disk.";
712 static PyObject *
713 posix_fsync(PyObject *self, PyObject *args)
715 return posix_int(args, "i:fsync", fsync);
717 #endif /* HAVE_FSYNC */
719 #ifdef HAVE_FDATASYNC
721 #ifdef __hpux
722 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
723 #endif
725 static char posix_fdatasync__doc__[] =
726 "fdatasync(fildes) -> None\n\
727 force write of file with filedescriptor to disk.\n\
728 does not force update of metadata.";
730 static PyObject *
731 posix_fdatasync(PyObject *self, PyObject *args)
733 return posix_int(args, "i:fdatasync", fdatasync);
735 #endif /* HAVE_FDATASYNC */
738 #ifdef HAVE_CHOWN
739 static char posix_chown__doc__[] =
740 "chown(path, uid, gid) -> None\n\
741 Change the owner and group id of path to the numeric uid and gid.";
743 static PyObject *
744 posix_chown(PyObject *self, PyObject *args)
746 char *path;
747 int uid, gid;
748 int res;
749 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
750 return NULL;
751 Py_BEGIN_ALLOW_THREADS
752 res = chown(path, (uid_t) uid, (gid_t) gid);
753 Py_END_ALLOW_THREADS
754 if (res < 0)
755 return posix_error_with_filename(path);
756 Py_INCREF(Py_None);
757 return Py_None;
759 #endif /* HAVE_CHOWN */
762 #ifdef HAVE_GETCWD
763 static char posix_getcwd__doc__[] =
764 "getcwd() -> path\n\
765 Return a string representing the current working directory.";
767 static PyObject *
768 posix_getcwd(PyObject *self, PyObject *args)
770 char buf[1026];
771 char *res;
772 if (!PyArg_ParseTuple(args, ":getcwd"))
773 return NULL;
774 Py_BEGIN_ALLOW_THREADS
775 res = getcwd(buf, sizeof buf);
776 Py_END_ALLOW_THREADS
777 if (res == NULL)
778 return posix_error();
779 return PyString_FromString(buf);
781 #endif
784 #ifdef HAVE_LINK
785 static char posix_link__doc__[] =
786 "link(src, dst) -> None\n\
787 Create a hard link to a file.";
789 static PyObject *
790 posix_link(PyObject *self, PyObject *args)
792 return posix_2str(args, "ss:link", link);
794 #endif /* HAVE_LINK */
797 static char posix_listdir__doc__[] =
798 "listdir(path) -> list_of_strings\n\
799 Return a list containing the names of the entries in the directory.\n\
801 path: path of directory to list\n\
803 The list is in arbitrary order. It does not include the special\n\
804 entries '.' and '..' even if they are present in the directory.";
806 static PyObject *
807 posix_listdir(PyObject *self, PyObject *args)
809 /* XXX Should redo this putting the (now four) versions of opendir
810 in separate files instead of having them all here... */
811 #if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
813 char *name;
814 int len;
815 PyObject *d, *v;
816 HANDLE hFindFile;
817 WIN32_FIND_DATA FileData;
818 char namebuf[MAX_PATH+5];
819 char ch;
821 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
822 return NULL;
823 if (len >= MAX_PATH) {
824 PyErr_SetString(PyExc_ValueError, "path too long");
825 return NULL;
827 strcpy(namebuf, name);
828 ch = namebuf[len-1];
829 if (ch != '/' && ch != '\\' && ch != ':')
830 namebuf[len++] = '/';
831 strcpy(namebuf + len, "*.*");
833 if ((d = PyList_New(0)) == NULL)
834 return NULL;
836 hFindFile = FindFirstFile(namebuf, &FileData);
837 if (hFindFile == INVALID_HANDLE_VALUE) {
838 errno = GetLastError();
839 if (errno == ERROR_FILE_NOT_FOUND)
840 return PyList_New(0);
841 return win32_error("FindFirstFile", name);
843 do {
844 if (FileData.cFileName[0] == '.' &&
845 (FileData.cFileName[1] == '\0' ||
846 FileData.cFileName[1] == '.' &&
847 FileData.cFileName[2] == '\0'))
848 continue;
849 v = PyString_FromString(FileData.cFileName);
850 if (v == NULL) {
851 Py_DECREF(d);
852 d = NULL;
853 break;
855 if (PyList_Append(d, v) != 0) {
856 Py_DECREF(v);
857 Py_DECREF(d);
858 d = NULL;
859 break;
861 Py_DECREF(v);
862 } while (FindNextFile(hFindFile, &FileData) == TRUE);
864 if (FindClose(hFindFile) == FALSE)
865 return win32_error("FindClose", name);
867 return d;
869 #elif defined(_MSC_VER) /* 16-bit Windows */
871 #ifndef MAX_PATH
872 #define MAX_PATH 250
873 #endif
874 char *name, *pt;
875 int len;
876 PyObject *d, *v;
877 char namebuf[MAX_PATH+5];
878 struct _find_t ep;
880 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
881 return NULL;
882 if (len >= MAX_PATH) {
883 PyErr_SetString(PyExc_ValueError, "path too long");
884 return NULL;
886 strcpy(namebuf, name);
887 for (pt = namebuf; *pt; pt++)
888 if (*pt == '/')
889 *pt = '\\';
890 if (namebuf[len-1] != '\\')
891 namebuf[len++] = '\\';
892 strcpy(namebuf + len, "*.*");
894 if ((d = PyList_New(0)) == NULL)
895 return NULL;
897 if (_dos_findfirst(namebuf, _A_RDONLY |
898 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
900 errno = ENOENT;
901 return posix_error_with_filename(name);
903 do {
904 if (ep.name[0] == '.' &&
905 (ep.name[1] == '\0' ||
906 ep.name[1] == '.' &&
907 ep.name[2] == '\0'))
908 continue;
909 strcpy(namebuf, ep.name);
910 for (pt = namebuf; *pt; pt++)
911 if (isupper(*pt))
912 *pt = tolower(*pt);
913 v = PyString_FromString(namebuf);
914 if (v == NULL) {
915 Py_DECREF(d);
916 d = NULL;
917 break;
919 if (PyList_Append(d, v) != 0) {
920 Py_DECREF(v);
921 Py_DECREF(d);
922 d = NULL;
923 break;
925 Py_DECREF(v);
926 } while (_dos_findnext(&ep) == 0);
928 return d;
930 #elif defined(PYOS_OS2)
932 #ifndef MAX_PATH
933 #define MAX_PATH CCHMAXPATH
934 #endif
935 char *name, *pt;
936 int len;
937 PyObject *d, *v;
938 char namebuf[MAX_PATH+5];
939 HDIR hdir = 1;
940 ULONG srchcnt = 1;
941 FILEFINDBUF3 ep;
942 APIRET rc;
944 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
945 return NULL;
946 if (len >= MAX_PATH) {
947 PyErr_SetString(PyExc_ValueError, "path too long");
948 return NULL;
950 strcpy(namebuf, name);
951 for (pt = namebuf; *pt; pt++)
952 if (*pt == '/')
953 *pt = '\\';
954 if (namebuf[len-1] != '\\')
955 namebuf[len++] = '\\';
956 strcpy(namebuf + len, "*.*");
958 if ((d = PyList_New(0)) == NULL)
959 return NULL;
961 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
962 &hdir, /* Handle to Use While Search Directory */
963 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
964 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
965 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
966 FIL_STANDARD); /* Format of Entry (EAs or Not) */
968 if (rc != NO_ERROR) {
969 errno = ENOENT;
970 return posix_error_with_filename(name);
973 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
974 do {
975 if (ep.achName[0] == '.'
976 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
977 continue; /* Skip Over "." and ".." Names */
979 strcpy(namebuf, ep.achName);
981 /* Leave Case of Name Alone -- In Native Form */
982 /* (Removed Forced Lowercasing Code) */
984 v = PyString_FromString(namebuf);
985 if (v == NULL) {
986 Py_DECREF(d);
987 d = NULL;
988 break;
990 if (PyList_Append(d, v) != 0) {
991 Py_DECREF(v);
992 Py_DECREF(d);
993 d = NULL;
994 break;
996 Py_DECREF(v);
997 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1000 return d;
1001 #else
1003 char *name;
1004 PyObject *d, *v;
1005 DIR *dirp;
1006 struct dirent *ep;
1007 if (!PyArg_ParseTuple(args, "s:listdir", &name))
1008 return NULL;
1009 if ((dirp = opendir(name)) == NULL) {
1010 return posix_error_with_filename(name);
1012 if ((d = PyList_New(0)) == NULL) {
1013 closedir(dirp);
1014 return NULL;
1016 while ((ep = readdir(dirp)) != NULL) {
1017 if (ep->d_name[0] == '.' &&
1018 (NAMLEN(ep) == 1 ||
1019 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
1020 continue;
1021 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
1022 if (v == NULL) {
1023 Py_DECREF(d);
1024 d = NULL;
1025 break;
1027 if (PyList_Append(d, v) != 0) {
1028 Py_DECREF(v);
1029 Py_DECREF(d);
1030 d = NULL;
1031 break;
1033 Py_DECREF(v);
1035 closedir(dirp);
1037 return d;
1039 #endif /* which OS */
1040 } /* end of posix_listdir */
1042 static char posix_mkdir__doc__[] =
1043 "mkdir(path [, mode=0777]) -> None\n\
1044 Create a directory.";
1046 static PyObject *
1047 posix_mkdir(PyObject *self, PyObject *args)
1049 int res;
1050 char *path;
1051 int mode = 0777;
1052 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
1053 return NULL;
1054 Py_BEGIN_ALLOW_THREADS
1055 #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1056 res = mkdir(path);
1057 #else
1058 res = mkdir(path, mode);
1059 #endif
1060 Py_END_ALLOW_THREADS
1061 if (res < 0)
1062 return posix_error_with_filename(path);
1063 Py_INCREF(Py_None);
1064 return Py_None;
1068 #ifdef HAVE_NICE
1069 static char posix_nice__doc__[] =
1070 "nice(inc) -> new_priority\n\
1071 Decrease the priority of process and return new priority.";
1073 static PyObject *
1074 posix_nice(PyObject *self, PyObject *args)
1076 int increment, value;
1078 if (!PyArg_ParseTuple(args, "i:nice", &increment))
1079 return NULL;
1080 value = nice(increment);
1081 if (value == -1)
1082 return posix_error();
1083 return PyInt_FromLong((long) value);
1085 #endif /* HAVE_NICE */
1088 static char posix_rename__doc__[] =
1089 "rename(old, new) -> None\n\
1090 Rename a file or directory.";
1092 static PyObject *
1093 posix_rename(PyObject *self, PyObject *args)
1095 return posix_2str(args, "ss:rename", rename);
1099 static char posix_rmdir__doc__[] =
1100 "rmdir(path) -> None\n\
1101 Remove a directory.";
1103 static PyObject *
1104 posix_rmdir(PyObject *self, PyObject *args)
1106 return posix_1str(args, "s:rmdir", rmdir);
1110 static char posix_stat__doc__[] =
1111 "stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1112 Perform a stat system call on the given path.";
1114 static PyObject *
1115 posix_stat(PyObject *self, PyObject *args)
1117 return posix_do_stat(self, args, "s:stat", STAT);
1121 #ifdef HAVE_SYSTEM
1122 static char posix_system__doc__[] =
1123 "system(command) -> exit_status\n\
1124 Execute the command (a string) in a subshell.";
1126 static PyObject *
1127 posix_system(PyObject *self, PyObject *args)
1129 char *command;
1130 long sts;
1131 if (!PyArg_ParseTuple(args, "s:system", &command))
1132 return NULL;
1133 Py_BEGIN_ALLOW_THREADS
1134 sts = system(command);
1135 Py_END_ALLOW_THREADS
1136 return PyInt_FromLong(sts);
1138 #endif
1141 static char posix_umask__doc__[] =
1142 "umask(new_mask) -> old_mask\n\
1143 Set the current numeric umask and return the previous umask.";
1145 static PyObject *
1146 posix_umask(PyObject *self, PyObject *args)
1148 int i;
1149 if (!PyArg_ParseTuple(args, "i:umask", &i))
1150 return NULL;
1151 i = umask(i);
1152 if (i < 0)
1153 return posix_error();
1154 return PyInt_FromLong((long)i);
1158 static char posix_unlink__doc__[] =
1159 "unlink(path) -> None\n\
1160 Remove a file (same as remove(path)).";
1162 static char posix_remove__doc__[] =
1163 "remove(path) -> None\n\
1164 Remove a file (same as unlink(path)).";
1166 static PyObject *
1167 posix_unlink(PyObject *self, PyObject *args)
1169 return posix_1str(args, "s:remove", unlink);
1173 #ifdef HAVE_UNAME
1174 static char posix_uname__doc__[] =
1175 "uname() -> (sysname, nodename, release, version, machine)\n\
1176 Return a tuple identifying the current operating system.";
1178 static PyObject *
1179 posix_uname(PyObject *self, PyObject *args)
1181 struct utsname u;
1182 int res;
1183 if (!PyArg_ParseTuple(args, ":uname"))
1184 return NULL;
1185 Py_BEGIN_ALLOW_THREADS
1186 res = uname(&u);
1187 Py_END_ALLOW_THREADS
1188 if (res < 0)
1189 return posix_error();
1190 return Py_BuildValue("(sssss)",
1191 u.sysname,
1192 u.nodename,
1193 u.release,
1194 u.version,
1195 u.machine);
1197 #endif /* HAVE_UNAME */
1200 static char posix_utime__doc__[] =
1201 "utime(path, (atime, utime)) -> None\n\
1202 utime(path, None) -> None\n\
1203 Set the access and modified time of the file to the given values. If the\n\
1204 second form is used, set the access and modified times to the current time.";
1206 static PyObject *
1207 posix_utime(PyObject *self, PyObject *args)
1209 char *path;
1210 long atime, mtime;
1211 int res;
1212 PyObject* arg;
1214 /* XXX should define struct utimbuf instead, above */
1215 #ifdef HAVE_UTIME_H
1216 struct utimbuf buf;
1217 #define ATIME buf.actime
1218 #define MTIME buf.modtime
1219 #define UTIME_ARG &buf
1220 #else /* HAVE_UTIME_H */
1221 time_t buf[2];
1222 #define ATIME buf[0]
1223 #define MTIME buf[1]
1224 #define UTIME_ARG buf
1225 #endif /* HAVE_UTIME_H */
1227 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
1228 return NULL;
1229 if (arg == Py_None) {
1230 /* optional time values not given */
1231 Py_BEGIN_ALLOW_THREADS
1232 res = utime(path, NULL);
1233 Py_END_ALLOW_THREADS
1235 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1236 PyErr_SetString(PyExc_TypeError,
1237 "utime() arg 2 must be a tuple (atime, mtime)");
1238 return NULL;
1240 else {
1241 ATIME = atime;
1242 MTIME = mtime;
1243 Py_BEGIN_ALLOW_THREADS
1244 res = utime(path, UTIME_ARG);
1245 Py_END_ALLOW_THREADS
1247 if (res < 0)
1248 return posix_error_with_filename(path);
1249 Py_INCREF(Py_None);
1250 return Py_None;
1251 #undef UTIME_ARG
1252 #undef ATIME
1253 #undef MTIME
1257 /* Process operations */
1259 static char posix__exit__doc__[] =
1260 "_exit(status)\n\
1261 Exit to the system with specified status, without normal exit processing.";
1263 static PyObject *
1264 posix__exit(PyObject *self, PyObject *args)
1266 int sts;
1267 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
1268 return NULL;
1269 _exit(sts);
1270 return NULL; /* Make gcc -Wall happy */
1274 #ifdef HAVE_EXECV
1275 static char posix_execv__doc__[] =
1276 "execv(path, args)\n\
1277 Execute an executable path with arguments, replacing current process.\n\
1279 path: path of executable file\n\
1280 args: tuple or list of strings";
1282 static PyObject *
1283 posix_execv(PyObject *self, PyObject *args)
1285 char *path;
1286 PyObject *argv;
1287 char **argvlist;
1288 int i, argc;
1289 PyObject *(*getitem)(PyObject *, int);
1291 /* execv has two arguments: (path, argv), where
1292 argv is a list or tuple of strings. */
1294 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
1295 return NULL;
1296 if (PyList_Check(argv)) {
1297 argc = PyList_Size(argv);
1298 getitem = PyList_GetItem;
1300 else if (PyTuple_Check(argv)) {
1301 argc = PyTuple_Size(argv);
1302 getitem = PyTuple_GetItem;
1304 else {
1305 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
1306 return NULL;
1309 if (argc == 0) {
1310 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
1311 return NULL;
1314 argvlist = PyMem_NEW(char *, argc+1);
1315 if (argvlist == NULL)
1316 return NULL;
1317 for (i = 0; i < argc; i++) {
1318 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1319 PyMem_DEL(argvlist);
1320 PyErr_SetString(PyExc_TypeError,
1321 "execv() arg 2 must contain only strings");
1322 return NULL;
1326 argvlist[argc] = NULL;
1328 #ifdef BAD_EXEC_PROTOTYPES
1329 execv(path, (const char **) argvlist);
1330 #else /* BAD_EXEC_PROTOTYPES */
1331 execv(path, argvlist);
1332 #endif /* BAD_EXEC_PROTOTYPES */
1334 /* If we get here it's definitely an error */
1336 PyMem_DEL(argvlist);
1337 return posix_error();
1341 static char posix_execve__doc__[] =
1342 "execve(path, args, env)\n\
1343 Execute a path with arguments and environment, replacing current process.\n\
1345 path: path of executable file\n\
1346 args: tuple or list of arguments\n\
1347 env: dictionary of strings mapping to strings";
1349 static PyObject *
1350 posix_execve(PyObject *self, PyObject *args)
1352 char *path;
1353 PyObject *argv, *env;
1354 char **argvlist;
1355 char **envlist;
1356 PyObject *key, *val, *keys=NULL, *vals=NULL;
1357 int i, pos, argc, envc;
1358 PyObject *(*getitem)(PyObject *, int);
1360 /* execve has three arguments: (path, argv, env), where
1361 argv is a list or tuple of strings and env is a dictionary
1362 like posix.environ. */
1364 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
1365 return NULL;
1366 if (PyList_Check(argv)) {
1367 argc = PyList_Size(argv);
1368 getitem = PyList_GetItem;
1370 else if (PyTuple_Check(argv)) {
1371 argc = PyTuple_Size(argv);
1372 getitem = PyTuple_GetItem;
1374 else {
1375 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
1376 return NULL;
1378 if (!PyMapping_Check(env)) {
1379 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
1380 return NULL;
1383 if (argc == 0) {
1384 PyErr_SetString(PyExc_ValueError,
1385 "execve() arg 2 must not be empty");
1386 return NULL;
1389 argvlist = PyMem_NEW(char *, argc+1);
1390 if (argvlist == NULL) {
1391 PyErr_NoMemory();
1392 return NULL;
1394 for (i = 0; i < argc; i++) {
1395 if (!PyArg_Parse((*getitem)(argv, i),
1396 "s;execve() arg 2 must contain only strings",
1397 &argvlist[i]))
1399 goto fail_1;
1402 argvlist[argc] = NULL;
1404 i = PyMapping_Size(env);
1405 envlist = PyMem_NEW(char *, i + 1);
1406 if (envlist == NULL) {
1407 PyErr_NoMemory();
1408 goto fail_1;
1410 envc = 0;
1411 keys = PyMapping_Keys(env);
1412 vals = PyMapping_Values(env);
1413 if (!keys || !vals)
1414 goto fail_2;
1416 for (pos = 0; pos < i; pos++) {
1417 char *p, *k, *v;
1419 key = PyList_GetItem(keys, pos);
1420 val = PyList_GetItem(vals, pos);
1421 if (!key || !val)
1422 goto fail_2;
1424 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1425 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
1427 goto fail_2;
1430 #if defined(PYOS_OS2)
1431 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1432 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1433 #endif
1434 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1435 if (p == NULL) {
1436 PyErr_NoMemory();
1437 goto fail_2;
1439 sprintf(p, "%s=%s", k, v);
1440 envlist[envc++] = p;
1441 #if defined(PYOS_OS2)
1443 #endif
1445 envlist[envc] = 0;
1448 #ifdef BAD_EXEC_PROTOTYPES
1449 execve(path, (const char **)argvlist, envlist);
1450 #else /* BAD_EXEC_PROTOTYPES */
1451 execve(path, argvlist, envlist);
1452 #endif /* BAD_EXEC_PROTOTYPES */
1454 /* If we get here it's definitely an error */
1456 (void) posix_error();
1458 fail_2:
1459 while (--envc >= 0)
1460 PyMem_DEL(envlist[envc]);
1461 PyMem_DEL(envlist);
1462 fail_1:
1463 PyMem_DEL(argvlist);
1464 Py_XDECREF(vals);
1465 Py_XDECREF(keys);
1466 return NULL;
1468 #endif /* HAVE_EXECV */
1471 #ifdef HAVE_SPAWNV
1472 static char posix_spawnv__doc__[] =
1473 "spawnv(mode, path, args)\n\
1474 Execute an executable path with arguments, replacing current process.\n\
1476 mode: mode of process creation\n\
1477 path: path of executable file\n\
1478 args: tuple or list of strings";
1480 static PyObject *
1481 posix_spawnv(PyObject *self, PyObject *args)
1483 char *path;
1484 PyObject *argv;
1485 char **argvlist;
1486 int mode, i, argc;
1487 intptr_t spawnval;
1488 PyObject *(*getitem)(PyObject *, int);
1490 /* spawnv has three arguments: (mode, path, argv), where
1491 argv is a list or tuple of strings. */
1493 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
1494 return NULL;
1495 if (PyList_Check(argv)) {
1496 argc = PyList_Size(argv);
1497 getitem = PyList_GetItem;
1499 else if (PyTuple_Check(argv)) {
1500 argc = PyTuple_Size(argv);
1501 getitem = PyTuple_GetItem;
1503 else {
1504 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
1505 return NULL;
1508 argvlist = PyMem_NEW(char *, argc+1);
1509 if (argvlist == NULL)
1510 return NULL;
1511 for (i = 0; i < argc; i++) {
1512 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1513 PyMem_DEL(argvlist);
1514 PyErr_SetString(PyExc_TypeError,
1515 "spawnv() arg 2 must contain only strings");
1516 return NULL;
1519 argvlist[argc] = NULL;
1521 if (mode == _OLD_P_OVERLAY)
1522 mode = _P_OVERLAY;
1523 spawnval = _spawnv(mode, path, argvlist);
1525 PyMem_DEL(argvlist);
1527 if (spawnval == -1)
1528 return posix_error();
1529 else
1530 #if SIZEOF_LONG == SIZEOF_VOID_P
1531 return Py_BuildValue("l", (long) spawnval);
1532 #else
1533 return Py_BuildValue("L", (LONG_LONG) spawnval);
1534 #endif
1538 static char posix_spawnve__doc__[] =
1539 "spawnve(mode, path, args, env)\n\
1540 Execute a path with arguments and environment, replacing current process.\n\
1542 mode: mode of process creation\n\
1543 path: path of executable file\n\
1544 args: tuple or list of arguments\n\
1545 env: dictionary of strings mapping to strings";
1547 static PyObject *
1548 posix_spawnve(PyObject *self, PyObject *args)
1550 char *path;
1551 PyObject *argv, *env;
1552 char **argvlist;
1553 char **envlist;
1554 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1555 int mode, i, pos, argc, envc;
1556 intptr_t spawnval;
1557 PyObject *(*getitem)(PyObject *, int);
1559 /* spawnve has four arguments: (mode, path, argv, env), where
1560 argv is a list or tuple of strings and env is a dictionary
1561 like posix.environ. */
1563 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
1564 return NULL;
1565 if (PyList_Check(argv)) {
1566 argc = PyList_Size(argv);
1567 getitem = PyList_GetItem;
1569 else if (PyTuple_Check(argv)) {
1570 argc = PyTuple_Size(argv);
1571 getitem = PyTuple_GetItem;
1573 else {
1574 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
1575 return NULL;
1577 if (!PyMapping_Check(env)) {
1578 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
1579 return NULL;
1582 argvlist = PyMem_NEW(char *, argc+1);
1583 if (argvlist == NULL) {
1584 PyErr_NoMemory();
1585 return NULL;
1587 for (i = 0; i < argc; i++) {
1588 if (!PyArg_Parse((*getitem)(argv, i),
1589 "s;spawnve() arg 2 must contain only strings",
1590 &argvlist[i]))
1592 goto fail_1;
1595 argvlist[argc] = NULL;
1597 i = PyMapping_Size(env);
1598 envlist = PyMem_NEW(char *, i + 1);
1599 if (envlist == NULL) {
1600 PyErr_NoMemory();
1601 goto fail_1;
1603 envc = 0;
1604 keys = PyMapping_Keys(env);
1605 vals = PyMapping_Values(env);
1606 if (!keys || !vals)
1607 goto fail_2;
1609 for (pos = 0; pos < i; pos++) {
1610 char *p, *k, *v;
1612 key = PyList_GetItem(keys, pos);
1613 val = PyList_GetItem(vals, pos);
1614 if (!key || !val)
1615 goto fail_2;
1617 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1618 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
1620 goto fail_2;
1622 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1623 if (p == NULL) {
1624 PyErr_NoMemory();
1625 goto fail_2;
1627 sprintf(p, "%s=%s", k, v);
1628 envlist[envc++] = p;
1630 envlist[envc] = 0;
1632 if (mode == _OLD_P_OVERLAY)
1633 mode = _P_OVERLAY;
1634 spawnval = _spawnve(mode, path, argvlist, envlist);
1635 if (spawnval == -1)
1636 (void) posix_error();
1637 else
1638 #if SIZEOF_LONG == SIZEOF_VOID_P
1639 res = Py_BuildValue("l", (long) spawnval);
1640 #else
1641 res = Py_BuildValue("L", (LONG_LONG) spawnval);
1642 #endif
1644 fail_2:
1645 while (--envc >= 0)
1646 PyMem_DEL(envlist[envc]);
1647 PyMem_DEL(envlist);
1648 fail_1:
1649 PyMem_DEL(argvlist);
1650 Py_XDECREF(vals);
1651 Py_XDECREF(keys);
1652 return res;
1654 #endif /* HAVE_SPAWNV */
1657 #ifdef HAVE_FORK
1658 static char posix_fork__doc__[] =
1659 "fork() -> pid\n\
1660 Fork a child process.\n\
1662 Return 0 to child process and PID of child to parent process.";
1664 static PyObject *
1665 posix_fork(PyObject *self, PyObject *args)
1667 int pid;
1668 if (!PyArg_ParseTuple(args, ":fork"))
1669 return NULL;
1670 pid = fork();
1671 if (pid == -1)
1672 return posix_error();
1673 if (pid == 0)
1674 PyOS_AfterFork();
1675 return PyInt_FromLong((long)pid);
1677 #endif
1679 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1680 #ifdef HAVE_PTY_H
1681 #include <pty.h>
1682 #else
1683 #ifdef HAVE_LIBUTIL_H
1684 #include <libutil.h>
1685 #endif /* HAVE_LIBUTIL_H */
1686 #endif /* HAVE_PTY_H */
1687 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
1689 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
1690 static char posix_openpty__doc__[] =
1691 "openpty() -> (master_fd, slave_fd)\n\
1692 Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1694 static PyObject *
1695 posix_openpty(PyObject *self, PyObject *args)
1697 int master_fd, slave_fd;
1698 #ifndef HAVE_OPENPTY
1699 char * slave_name;
1700 #endif
1702 if (!PyArg_ParseTuple(args, ":openpty"))
1703 return NULL;
1705 #ifdef HAVE_OPENPTY
1706 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1707 return posix_error();
1708 #else
1709 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1710 if (slave_name == NULL)
1711 return posix_error();
1713 slave_fd = open(slave_name, O_RDWR);
1714 if (slave_fd < 0)
1715 return posix_error();
1716 #endif /* HAVE_OPENPTY */
1718 return Py_BuildValue("(ii)", master_fd, slave_fd);
1721 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
1723 #ifdef HAVE_FORKPTY
1724 static char posix_forkpty__doc__[] =
1725 "forkpty() -> (pid, master_fd)\n\
1726 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1727 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1728 To both, return fd of newly opened pseudo-terminal.\n";
1730 static PyObject *
1731 posix_forkpty(PyObject *self, PyObject *args)
1733 int master_fd, pid;
1735 if (!PyArg_ParseTuple(args, ":forkpty"))
1736 return NULL;
1737 pid = forkpty(&master_fd, NULL, NULL, NULL);
1738 if (pid == -1)
1739 return posix_error();
1740 if (pid == 0)
1741 PyOS_AfterFork();
1742 return Py_BuildValue("(ii)", pid, master_fd);
1744 #endif
1746 #ifdef HAVE_GETEGID
1747 static char posix_getegid__doc__[] =
1748 "getegid() -> egid\n\
1749 Return the current process's effective group id.";
1751 static PyObject *
1752 posix_getegid(PyObject *self, PyObject *args)
1754 if (!PyArg_ParseTuple(args, ":getegid"))
1755 return NULL;
1756 return PyInt_FromLong((long)getegid());
1758 #endif
1761 #ifdef HAVE_GETEUID
1762 static char posix_geteuid__doc__[] =
1763 "geteuid() -> euid\n\
1764 Return the current process's effective user id.";
1766 static PyObject *
1767 posix_geteuid(PyObject *self, PyObject *args)
1769 if (!PyArg_ParseTuple(args, ":geteuid"))
1770 return NULL;
1771 return PyInt_FromLong((long)geteuid());
1773 #endif
1776 #ifdef HAVE_GETGID
1777 static char posix_getgid__doc__[] =
1778 "getgid() -> gid\n\
1779 Return the current process's group id.";
1781 static PyObject *
1782 posix_getgid(PyObject *self, PyObject *args)
1784 if (!PyArg_ParseTuple(args, ":getgid"))
1785 return NULL;
1786 return PyInt_FromLong((long)getgid());
1788 #endif
1791 static char posix_getpid__doc__[] =
1792 "getpid() -> pid\n\
1793 Return the current process id";
1795 static PyObject *
1796 posix_getpid(PyObject *self, PyObject *args)
1798 if (!PyArg_ParseTuple(args, ":getpid"))
1799 return NULL;
1800 return PyInt_FromLong((long)getpid());
1804 #ifdef HAVE_GETGROUPS
1805 static char posix_getgroups__doc__[] = "\
1806 getgroups() -> list of group IDs\n\
1807 Return list of supplemental group IDs for the process.";
1809 static PyObject *
1810 posix_getgroups(PyObject *self, PyObject *args)
1812 PyObject *result = NULL;
1814 if (PyArg_ParseTuple(args, ":getgroups")) {
1815 #ifdef NGROUPS_MAX
1816 #define MAX_GROUPS NGROUPS_MAX
1817 #else
1818 /* defined to be 16 on Solaris7, so this should be a small number */
1819 #define MAX_GROUPS 64
1820 #endif
1821 gid_t grouplist[MAX_GROUPS];
1822 int n;
1824 n = getgroups(MAX_GROUPS, grouplist);
1825 if (n < 0)
1826 posix_error();
1827 else {
1828 result = PyList_New(n);
1829 if (result != NULL) {
1830 PyObject *o;
1831 int i;
1832 for (i = 0; i < n; ++i) {
1833 o = PyInt_FromLong((long)grouplist[i]);
1834 if (o == NULL) {
1835 Py_DECREF(result);
1836 result = NULL;
1837 break;
1839 PyList_SET_ITEM(result, i, o);
1844 return result;
1846 #endif
1848 #ifdef HAVE_GETPGRP
1849 static char posix_getpgrp__doc__[] =
1850 "getpgrp() -> pgrp\n\
1851 Return the current process group id.";
1853 static PyObject *
1854 posix_getpgrp(PyObject *self, PyObject *args)
1856 if (!PyArg_ParseTuple(args, ":getpgrp"))
1857 return NULL;
1858 #ifdef GETPGRP_HAVE_ARG
1859 return PyInt_FromLong((long)getpgrp(0));
1860 #else /* GETPGRP_HAVE_ARG */
1861 return PyInt_FromLong((long)getpgrp());
1862 #endif /* GETPGRP_HAVE_ARG */
1864 #endif /* HAVE_GETPGRP */
1867 #ifdef HAVE_SETPGRP
1868 static char posix_setpgrp__doc__[] =
1869 "setpgrp() -> None\n\
1870 Make this process a session leader.";
1872 static PyObject *
1873 posix_setpgrp(PyObject *self, PyObject *args)
1875 if (!PyArg_ParseTuple(args, ":setpgrp"))
1876 return NULL;
1877 #ifdef SETPGRP_HAVE_ARG
1878 if (setpgrp(0, 0) < 0)
1879 #else /* SETPGRP_HAVE_ARG */
1880 if (setpgrp() < 0)
1881 #endif /* SETPGRP_HAVE_ARG */
1882 return posix_error();
1883 Py_INCREF(Py_None);
1884 return Py_None;
1887 #endif /* HAVE_SETPGRP */
1889 #ifdef HAVE_GETPPID
1890 static char posix_getppid__doc__[] =
1891 "getppid() -> ppid\n\
1892 Return the parent's process id.";
1894 static PyObject *
1895 posix_getppid(PyObject *self, PyObject *args)
1897 if (!PyArg_ParseTuple(args, ":getppid"))
1898 return NULL;
1899 return PyInt_FromLong((long)getppid());
1901 #endif
1904 #ifdef HAVE_GETLOGIN
1905 static char posix_getlogin__doc__[] = "\
1906 getlogin() -> string\n\
1907 Return the actual login name.";
1909 static PyObject *
1910 posix_getlogin(PyObject *self, PyObject *args)
1912 PyObject *result = NULL;
1914 if (PyArg_ParseTuple(args, ":getlogin")) {
1915 char *name;
1916 int old_errno = errno;
1918 errno = 0;
1919 name = getlogin();
1920 if (name == NULL) {
1921 if (errno)
1922 posix_error();
1923 else
1924 PyErr_SetString(PyExc_OSError,
1925 "unable to determine login name");
1927 else
1928 result = PyString_FromString(name);
1929 errno = old_errno;
1931 return result;
1933 #endif
1935 #ifdef HAVE_GETUID
1936 static char posix_getuid__doc__[] =
1937 "getuid() -> uid\n\
1938 Return the current process's user id.";
1940 static PyObject *
1941 posix_getuid(PyObject *self, PyObject *args)
1943 if (!PyArg_ParseTuple(args, ":getuid"))
1944 return NULL;
1945 return PyInt_FromLong((long)getuid());
1947 #endif
1950 #ifdef HAVE_KILL
1951 static char posix_kill__doc__[] =
1952 "kill(pid, sig) -> None\n\
1953 Kill a process with a signal.";
1955 static PyObject *
1956 posix_kill(PyObject *self, PyObject *args)
1958 int pid, sig;
1959 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
1960 return NULL;
1961 #if defined(PYOS_OS2)
1962 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1963 APIRET rc;
1964 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
1965 return os2_error(rc);
1967 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1968 APIRET rc;
1969 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
1970 return os2_error(rc);
1972 } else
1973 return NULL; /* Unrecognized Signal Requested */
1974 #else
1975 if (kill(pid, sig) == -1)
1976 return posix_error();
1977 #endif
1978 Py_INCREF(Py_None);
1979 return Py_None;
1981 #endif
1983 #ifdef HAVE_PLOCK
1985 #ifdef HAVE_SYS_LOCK_H
1986 #include <sys/lock.h>
1987 #endif
1989 static char posix_plock__doc__[] =
1990 "plock(op) -> None\n\
1991 Lock program segments into memory.";
1993 static PyObject *
1994 posix_plock(PyObject *self, PyObject *args)
1996 int op;
1997 if (!PyArg_ParseTuple(args, "i:plock", &op))
1998 return NULL;
1999 if (plock(op) == -1)
2000 return posix_error();
2001 Py_INCREF(Py_None);
2002 return Py_None;
2004 #endif
2007 #ifdef HAVE_POPEN
2008 static char posix_popen__doc__[] =
2009 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2010 Open a pipe to/from a command returning a file object.";
2012 #if defined(PYOS_OS2)
2013 static int
2014 async_system(const char *command)
2016 char *p, errormsg[256], args[1024];
2017 RESULTCODES rcodes;
2018 APIRET rc;
2019 char *shell = getenv("COMSPEC");
2020 if (!shell)
2021 shell = "cmd";
2023 strcpy(args, shell);
2024 p = &args[ strlen(args)+1 ];
2025 strcpy(p, "/c ");
2026 strcat(p, command);
2027 p += strlen(p) + 1;
2028 *p = '\0';
2030 rc = DosExecPgm(errormsg, sizeof(errormsg),
2031 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
2032 args,
2033 NULL, /* Inherit Parent's Environment */
2034 &rcodes, shell);
2035 return rc;
2038 static FILE *
2039 popen(const char *command, const char *mode, int pipesize, int *err)
2041 HFILE rhan, whan;
2042 FILE *retfd = NULL;
2043 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2045 if (rc != NO_ERROR) {
2046 *err = rc;
2047 return NULL; /* ERROR - Unable to Create Anon Pipe */
2050 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2051 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
2053 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2054 close(1); /* Make STDOUT Available for Reallocation */
2056 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2057 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
2059 if (async_system(command) == NO_ERROR)
2060 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2063 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2064 DosExitCritSec(); /* Now Allow Other Threads to Run */
2066 close(oldfd); /* And Close Saved STDOUT Handle */
2067 return retfd; /* Return fd of Pipe or NULL if Error */
2069 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2070 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
2072 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2073 close(0); /* Make STDIN Available for Reallocation */
2075 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2076 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
2078 if (async_system(command) == NO_ERROR)
2079 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2082 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2083 DosExitCritSec(); /* Now Allow Other Threads to Run */
2085 close(oldfd); /* And Close Saved STDIN Handle */
2086 return retfd; /* Return fd of Pipe or NULL if Error */
2088 } else {
2089 *err = ERROR_INVALID_ACCESS;
2090 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
2094 static PyObject *
2095 posix_popen(PyObject *self, PyObject *args)
2097 char *name;
2098 char *mode = "r";
2099 int err, bufsize = -1;
2100 FILE *fp;
2101 PyObject *f;
2102 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2103 return NULL;
2104 Py_BEGIN_ALLOW_THREADS
2105 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
2106 Py_END_ALLOW_THREADS
2107 if (fp == NULL)
2108 return os2_error(err);
2110 f = PyFile_FromFile(fp, name, mode, fclose);
2111 if (f != NULL)
2112 PyFile_SetBufSize(f, bufsize);
2113 return f;
2116 #elif defined(MS_WIN32)
2119 * Portable 'popen' replacement for Win32.
2121 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2122 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
2123 * Return code handling by David Bolen <db3l@fitlinxx.com>.
2126 #include <malloc.h>
2127 #include <io.h>
2128 #include <fcntl.h>
2130 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2131 #define POPEN_1 1
2132 #define POPEN_2 2
2133 #define POPEN_3 3
2134 #define POPEN_4 4
2136 static PyObject *_PyPopen(char *, int, int);
2137 static int _PyPclose(FILE *file);
2140 * Internal dictionary mapping popen* file pointers to process handles,
2141 * for use when retrieving the process exit code. See _PyPclose() below
2142 * for more information on this dictionary's use.
2144 static PyObject *_PyPopenProcs = NULL;
2147 /* popen that works from a GUI.
2149 * The result of this function is a pipe (file) connected to the
2150 * processes stdin or stdout, depending on the requested mode.
2153 static PyObject *
2154 posix_popen(PyObject *self, PyObject *args)
2156 PyObject *f, *s;
2157 int tm = 0;
2159 char *cmdstring;
2160 char *mode = "r";
2161 int bufsize = -1;
2162 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
2163 return NULL;
2165 s = PyTuple_New(0);
2167 if (*mode == 'r')
2168 tm = _O_RDONLY;
2169 else if (*mode != 'w') {
2170 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
2171 return NULL;
2172 } else
2173 tm = _O_WRONLY;
2175 if (bufsize != -1) {
2176 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
2177 return NULL;
2180 if (*(mode+1) == 't')
2181 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2182 else if (*(mode+1) == 'b')
2183 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
2184 else
2185 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2187 return f;
2190 /* Variation on win32pipe.popen
2192 * The result of this function is a pipe (file) connected to the
2193 * process's stdin, and a pipe connected to the process's stdout.
2196 static PyObject *
2197 win32_popen2(PyObject *self, PyObject *args)
2199 PyObject *f;
2200 int tm=0;
2202 char *cmdstring;
2203 char *mode = "t";
2204 int bufsize = -1;
2205 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2206 return NULL;
2208 if (*mode == 't')
2209 tm = _O_TEXT;
2210 else if (*mode != 'b') {
2211 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
2212 return NULL;
2213 } else
2214 tm = _O_BINARY;
2216 if (bufsize != -1) {
2217 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
2218 return NULL;
2221 f = _PyPopen(cmdstring, tm, POPEN_2);
2223 return f;
2227 * Variation on <om win32pipe.popen>
2229 * The result of this function is 3 pipes - the process's stdin,
2230 * stdout and stderr
2233 static PyObject *
2234 win32_popen3(PyObject *self, PyObject *args)
2236 PyObject *f;
2237 int tm = 0;
2239 char *cmdstring;
2240 char *mode = "t";
2241 int bufsize = -1;
2242 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2243 return NULL;
2245 if (*mode == 't')
2246 tm = _O_TEXT;
2247 else if (*mode != 'b') {
2248 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
2249 return NULL;
2250 } else
2251 tm = _O_BINARY;
2253 if (bufsize != -1) {
2254 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
2255 return NULL;
2258 f = _PyPopen(cmdstring, tm, POPEN_3);
2260 return f;
2264 * Variation on win32pipe.popen
2266 * The result of this function is 2 pipes - the processes stdin,
2267 * and stdout+stderr combined as a single pipe.
2270 static PyObject *
2271 win32_popen4(PyObject *self, PyObject *args)
2273 PyObject *f;
2274 int tm = 0;
2276 char *cmdstring;
2277 char *mode = "t";
2278 int bufsize = -1;
2279 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2280 return NULL;
2282 if (*mode == 't')
2283 tm = _O_TEXT;
2284 else if (*mode != 'b') {
2285 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
2286 return NULL;
2287 } else
2288 tm = _O_BINARY;
2290 if (bufsize != -1) {
2291 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
2292 return NULL;
2295 f = _PyPopen(cmdstring, tm, POPEN_4);
2297 return f;
2300 static BOOL
2301 _PyPopenCreateProcess(char *cmdstring,
2302 HANDLE hStdin,
2303 HANDLE hStdout,
2304 HANDLE hStderr,
2305 HANDLE *hProcess)
2307 PROCESS_INFORMATION piProcInfo;
2308 STARTUPINFO siStartInfo;
2309 char *s1,*s2, *s3 = " /c ";
2310 const char *szConsoleSpawn = "w9xpopen.exe";
2311 int i;
2312 int x;
2314 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2315 s1 = (char *)_alloca(i);
2316 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2317 return x;
2318 if (GetVersion() < 0x80000000) {
2320 * NT/2000
2322 x = i + strlen(s3) + strlen(cmdstring) + 1;
2323 s2 = (char *)_alloca(x);
2324 ZeroMemory(s2, x);
2325 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2327 else {
2329 * Oh gag, we're on Win9x. Use the workaround listed in
2330 * KB: Q150956
2332 char modulepath[_MAX_PATH];
2333 struct stat statinfo;
2334 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2335 for (i = x = 0; modulepath[i]; i++)
2336 if (modulepath[i] == '\\')
2337 x = i+1;
2338 modulepath[x] = '\0';
2339 /* Create the full-name to w9xpopen, so we can test it exists */
2340 strncat(modulepath,
2341 szConsoleSpawn,
2342 (sizeof(modulepath)/sizeof(modulepath[0]))
2343 -strlen(modulepath));
2344 if (stat(modulepath, &statinfo) != 0) {
2345 /* Eeek - file-not-found - possibly an embedding
2346 situation - see if we can locate it in sys.prefix
2348 strncpy(modulepath,
2349 Py_GetExecPrefix(),
2350 sizeof(modulepath)/sizeof(modulepath[0]));
2351 if (modulepath[strlen(modulepath)-1] != '\\')
2352 strcat(modulepath, "\\");
2353 strncat(modulepath,
2354 szConsoleSpawn,
2355 (sizeof(modulepath)/sizeof(modulepath[0]))
2356 -strlen(modulepath));
2357 /* No where else to look - raise an easily identifiable
2358 error, rather than leaving Windows to report
2359 "file not found" - as the user is probably blissfully
2360 unaware this shim EXE is used, and it will confuse them.
2361 (well, it confused me for a while ;-)
2363 if (stat(modulepath, &statinfo) != 0) {
2364 PyErr_Format(PyExc_RuntimeError,
2365 "Can not locate '%s' which is needed "
2366 "for popen to work on this platform.",
2367 szConsoleSpawn);
2368 return FALSE;
2371 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2372 strlen(modulepath) +
2373 strlen(szConsoleSpawn) + 1;
2375 s2 = (char *)_alloca(x);
2376 ZeroMemory(s2, x);
2377 sprintf(
2379 "%s \"%s%s%s\"",
2380 modulepath,
2383 cmdstring);
2387 /* Could be an else here to try cmd.exe / command.com in the path
2388 Now we'll just error out.. */
2389 else {
2390 PyErr_SetString(PyExc_RuntimeError, "Can not locate a COMSPEC environment variable to use as the shell");
2391 return FALSE;
2394 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2395 siStartInfo.cb = sizeof(STARTUPINFO);
2396 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2397 siStartInfo.hStdInput = hStdin;
2398 siStartInfo.hStdOutput = hStdout;
2399 siStartInfo.hStdError = hStderr;
2400 siStartInfo.wShowWindow = SW_HIDE;
2402 if (CreateProcess(NULL,
2404 NULL,
2405 NULL,
2406 TRUE,
2407 CREATE_NEW_CONSOLE,
2408 NULL,
2409 NULL,
2410 &siStartInfo,
2411 &piProcInfo) ) {
2412 /* Close the handles now so anyone waiting is woken. */
2413 CloseHandle(piProcInfo.hThread);
2415 /* Return process handle */
2416 *hProcess = piProcInfo.hProcess;
2417 return TRUE;
2419 win32_error("CreateProcess", NULL);
2420 return FALSE;
2423 /* The following code is based off of KB: Q190351 */
2425 static PyObject *
2426 _PyPopen(char *cmdstring, int mode, int n)
2428 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2429 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
2430 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
2432 SECURITY_ATTRIBUTES saAttr;
2433 BOOL fSuccess;
2434 int fd1, fd2, fd3;
2435 FILE *f1, *f2, *f3;
2436 long file_count;
2437 PyObject *f;
2439 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2440 saAttr.bInheritHandle = TRUE;
2441 saAttr.lpSecurityDescriptor = NULL;
2443 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2444 return win32_error("CreatePipe", NULL);
2446 /* Create new output read handle and the input write handle. Set
2447 * the inheritance properties to FALSE. Otherwise, the child inherits
2448 * the these handles; resulting in non-closeable handles to the pipes
2449 * being created. */
2450 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
2451 GetCurrentProcess(), &hChildStdinWrDup, 0,
2452 FALSE,
2453 DUPLICATE_SAME_ACCESS);
2454 if (!fSuccess)
2455 return win32_error("DuplicateHandle", NULL);
2457 /* Close the inheritable version of ChildStdin
2458 that we're using. */
2459 CloseHandle(hChildStdinWr);
2461 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2462 return win32_error("CreatePipe", NULL);
2464 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
2465 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2466 FALSE, DUPLICATE_SAME_ACCESS);
2467 if (!fSuccess)
2468 return win32_error("DuplicateHandle", NULL);
2470 /* Close the inheritable version of ChildStdout
2471 that we're using. */
2472 CloseHandle(hChildStdoutRd);
2474 if (n != POPEN_4) {
2475 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2476 return win32_error("CreatePipe", NULL);
2477 fSuccess = DuplicateHandle(GetCurrentProcess(),
2478 hChildStderrRd,
2479 GetCurrentProcess(),
2480 &hChildStderrRdDup, 0,
2481 FALSE, DUPLICATE_SAME_ACCESS);
2482 if (!fSuccess)
2483 return win32_error("DuplicateHandle", NULL);
2484 /* Close the inheritable version of ChildStdErr that we're using. */
2485 CloseHandle(hChildStderrRd);
2488 switch (n) {
2489 case POPEN_1:
2490 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2491 case _O_WRONLY | _O_TEXT:
2492 /* Case for writing to child Stdin in text mode. */
2493 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2494 f1 = _fdopen(fd1, "w");
2495 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
2496 PyFile_SetBufSize(f, 0);
2497 /* We don't care about these pipes anymore, so close them. */
2498 CloseHandle(hChildStdoutRdDup);
2499 CloseHandle(hChildStderrRdDup);
2500 break;
2502 case _O_RDONLY | _O_TEXT:
2503 /* Case for reading from child Stdout in text mode. */
2504 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2505 f1 = _fdopen(fd1, "r");
2506 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
2507 PyFile_SetBufSize(f, 0);
2508 /* We don't care about these pipes anymore, so close them. */
2509 CloseHandle(hChildStdinWrDup);
2510 CloseHandle(hChildStderrRdDup);
2511 break;
2513 case _O_RDONLY | _O_BINARY:
2514 /* Case for readinig from child Stdout in binary mode. */
2515 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2516 f1 = _fdopen(fd1, "rb");
2517 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
2518 PyFile_SetBufSize(f, 0);
2519 /* We don't care about these pipes anymore, so close them. */
2520 CloseHandle(hChildStdinWrDup);
2521 CloseHandle(hChildStderrRdDup);
2522 break;
2524 case _O_WRONLY | _O_BINARY:
2525 /* Case for writing to child Stdin in binary mode. */
2526 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2527 f1 = _fdopen(fd1, "wb");
2528 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
2529 PyFile_SetBufSize(f, 0);
2530 /* We don't care about these pipes anymore, so close them. */
2531 CloseHandle(hChildStdoutRdDup);
2532 CloseHandle(hChildStderrRdDup);
2533 break;
2535 file_count = 1;
2536 break;
2538 case POPEN_2:
2539 case POPEN_4:
2541 char *m1, *m2;
2542 PyObject *p1, *p2;
2544 if (mode && _O_TEXT) {
2545 m1 = "r";
2546 m2 = "w";
2547 } else {
2548 m1 = "rb";
2549 m2 = "wb";
2552 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2553 f1 = _fdopen(fd1, m2);
2554 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2555 f2 = _fdopen(fd2, m1);
2556 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
2557 PyFile_SetBufSize(p1, 0);
2558 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2559 PyFile_SetBufSize(p2, 0);
2561 if (n != 4)
2562 CloseHandle(hChildStderrRdDup);
2564 f = Py_BuildValue("OO",p1,p2);
2565 Py_XDECREF(p1);
2566 Py_XDECREF(p2);
2567 file_count = 2;
2568 break;
2571 case POPEN_3:
2573 char *m1, *m2;
2574 PyObject *p1, *p2, *p3;
2576 if (mode && _O_TEXT) {
2577 m1 = "r";
2578 m2 = "w";
2579 } else {
2580 m1 = "rb";
2581 m2 = "wb";
2584 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2585 f1 = _fdopen(fd1, m2);
2586 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2587 f2 = _fdopen(fd2, m1);
2588 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2589 f3 = _fdopen(fd3, m1);
2590 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
2591 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2592 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
2593 PyFile_SetBufSize(p1, 0);
2594 PyFile_SetBufSize(p2, 0);
2595 PyFile_SetBufSize(p3, 0);
2596 f = Py_BuildValue("OOO",p1,p2,p3);
2597 Py_XDECREF(p1);
2598 Py_XDECREF(p2);
2599 Py_XDECREF(p3);
2600 file_count = 3;
2601 break;
2605 if (n == POPEN_4) {
2606 if (!_PyPopenCreateProcess(cmdstring,
2607 hChildStdinRd,
2608 hChildStdoutWr,
2609 hChildStdoutWr,
2610 &hProcess))
2611 return NULL;
2613 else {
2614 if (!_PyPopenCreateProcess(cmdstring,
2615 hChildStdinRd,
2616 hChildStdoutWr,
2617 hChildStderrWr,
2618 &hProcess))
2619 return NULL;
2623 * Insert the files we've created into the process dictionary
2624 * all referencing the list with the process handle and the
2625 * initial number of files (see description below in _PyPclose).
2626 * Since if _PyPclose later tried to wait on a process when all
2627 * handles weren't closed, it could create a deadlock with the
2628 * child, we spend some energy here to try to ensure that we
2629 * either insert all file handles into the dictionary or none
2630 * at all. It's a little clumsy with the various popen modes
2631 * and variable number of files involved.
2633 if (!_PyPopenProcs) {
2634 _PyPopenProcs = PyDict_New();
2637 if (_PyPopenProcs) {
2638 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2639 int ins_rc[3];
2641 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2642 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2644 procObj = PyList_New(2);
2645 hProcessObj = PyLong_FromVoidPtr(hProcess);
2646 intObj = PyInt_FromLong(file_count);
2648 if (procObj && hProcessObj && intObj) {
2649 PyList_SetItem(procObj,0,hProcessObj);
2650 PyList_SetItem(procObj,1,intObj);
2652 fileObj[0] = PyLong_FromVoidPtr(f1);
2653 if (fileObj[0]) {
2654 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2655 fileObj[0],
2656 procObj);
2658 if (file_count >= 2) {
2659 fileObj[1] = PyLong_FromVoidPtr(f2);
2660 if (fileObj[1]) {
2661 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2662 fileObj[1],
2663 procObj);
2666 if (file_count >= 3) {
2667 fileObj[2] = PyLong_FromVoidPtr(f3);
2668 if (fileObj[2]) {
2669 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2670 fileObj[2],
2671 procObj);
2675 if (ins_rc[0] < 0 || !fileObj[0] ||
2676 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2677 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2678 /* Something failed - remove any dictionary
2679 * entries that did make it.
2681 if (!ins_rc[0] && fileObj[0]) {
2682 PyDict_DelItem(_PyPopenProcs,
2683 fileObj[0]);
2685 if (!ins_rc[1] && fileObj[1]) {
2686 PyDict_DelItem(_PyPopenProcs,
2687 fileObj[1]);
2689 if (!ins_rc[2] && fileObj[2]) {
2690 PyDict_DelItem(_PyPopenProcs,
2691 fileObj[2]);
2697 * Clean up our localized references for the dictionary keys
2698 * and value since PyDict_SetItem will Py_INCREF any copies
2699 * that got placed in the dictionary.
2701 Py_XDECREF(procObj);
2702 Py_XDECREF(fileObj[0]);
2703 Py_XDECREF(fileObj[1]);
2704 Py_XDECREF(fileObj[2]);
2707 /* Child is launched. Close the parents copy of those pipe
2708 * handles that only the child should have open. You need to
2709 * make sure that no handles to the write end of the output pipe
2710 * are maintained in this process or else the pipe will not close
2711 * when the child process exits and the ReadFile will hang. */
2713 if (!CloseHandle(hChildStdinRd))
2714 return win32_error("CloseHandle", NULL);
2716 if (!CloseHandle(hChildStdoutWr))
2717 return win32_error("CloseHandle", NULL);
2719 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2720 return win32_error("CloseHandle", NULL);
2722 return f;
2726 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2727 * exit code for the child process and return as a result of the close.
2729 * This function uses the _PyPopenProcs dictionary in order to map the
2730 * input file pointer to information about the process that was
2731 * originally created by the popen* call that created the file pointer.
2732 * The dictionary uses the file pointer as a key (with one entry
2733 * inserted for each file returned by the original popen* call) and a
2734 * single list object as the value for all files from a single call.
2735 * The list object contains the Win32 process handle at [0], and a file
2736 * count at [1], which is initialized to the total number of file
2737 * handles using that list.
2739 * This function closes whichever handle it is passed, and decrements
2740 * the file count in the dictionary for the process handle pointed to
2741 * by this file. On the last close (when the file count reaches zero),
2742 * this function will wait for the child process and then return its
2743 * exit code as the result of the close() operation. This permits the
2744 * files to be closed in any order - it is always the close() of the
2745 * final handle that will return the exit code.
2748 /* RED_FLAG 31-Aug-2000 Tim
2749 * This is always called (today!) between a pair of
2750 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2751 * macros. So the thread running this has no valid thread state, as
2752 * far as Python is concerned. However, this calls some Python API
2753 * functions that cannot be called safely without a valid thread
2754 * state, in particular PyDict_GetItem.
2755 * As a temporary hack (although it may last for years ...), we
2756 * *rely* on not having a valid thread state in this function, in
2757 * order to create our own "from scratch".
2758 * This will deadlock if _PyPclose is ever called by a thread
2759 * holding the global lock.
2762 static int _PyPclose(FILE *file)
2764 int result;
2765 DWORD exit_code;
2766 HANDLE hProcess;
2767 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2768 long file_count;
2769 #ifdef WITH_THREAD
2770 PyInterpreterState* pInterpreterState;
2771 PyThreadState* pThreadState;
2772 #endif
2774 /* Close the file handle first, to ensure it can't block the
2775 * child from exiting if it's the last handle.
2777 result = fclose(file);
2779 #ifdef WITH_THREAD
2780 /* Bootstrap a valid thread state into existence. */
2781 pInterpreterState = PyInterpreterState_New();
2782 if (!pInterpreterState) {
2783 /* Well, we're hosed now! We don't have a thread
2784 * state, so can't call a nice error routine, or raise
2785 * an exception. Just die.
2787 Py_FatalError("unable to allocate interpreter state "
2788 "when closing popen object");
2789 return -1; /* unreachable */
2791 pThreadState = PyThreadState_New(pInterpreterState);
2792 if (!pThreadState) {
2793 Py_FatalError("unable to allocate thread state "
2794 "when closing popen object");
2795 return -1; /* unreachable */
2797 /* Grab the global lock. Note that this will deadlock if the
2798 * current thread already has the lock! (see RED_FLAG comments
2799 * before this function)
2801 PyEval_RestoreThread(pThreadState);
2802 #endif
2804 if (_PyPopenProcs) {
2805 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2806 (procObj = PyDict_GetItem(_PyPopenProcs,
2807 fileObj)) != NULL &&
2808 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2809 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2811 hProcess = PyLong_AsVoidPtr(hProcessObj);
2812 file_count = PyInt_AsLong(intObj);
2814 if (file_count > 1) {
2815 /* Still other files referencing process */
2816 file_count--;
2817 PyList_SetItem(procObj,1,
2818 PyInt_FromLong(file_count));
2819 } else {
2820 /* Last file for this process */
2821 if (result != EOF &&
2822 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2823 GetExitCodeProcess(hProcess, &exit_code)) {
2824 /* Possible truncation here in 16-bit environments, but
2825 * real exit codes are just the lower byte in any event.
2827 result = exit_code;
2828 } else {
2829 /* Indicate failure - this will cause the file object
2830 * to raise an I/O error and translate the last Win32
2831 * error code from errno. We do have a problem with
2832 * last errors that overlap the normal errno table,
2833 * but that's a consistent problem with the file object.
2835 if (result != EOF) {
2836 /* If the error wasn't from the fclose(), then
2837 * set errno for the file object error handling.
2839 errno = GetLastError();
2841 result = -1;
2844 /* Free up the native handle at this point */
2845 CloseHandle(hProcess);
2848 /* Remove this file pointer from dictionary */
2849 PyDict_DelItem(_PyPopenProcs, fileObj);
2851 if (PyDict_Size(_PyPopenProcs) == 0) {
2852 Py_DECREF(_PyPopenProcs);
2853 _PyPopenProcs = NULL;
2856 } /* if object retrieval ok */
2858 Py_XDECREF(fileObj);
2859 } /* if _PyPopenProcs */
2861 #ifdef WITH_THREAD
2862 /* Tear down the thread & interpreter states.
2863 * Note that interpreter state clear & delete functions automatically
2864 * call the thread clear & delete functions, and indeed insist on
2865 * doing that themselves. The lock must be held during the clear, but
2866 * need not be held during the delete.
2868 PyInterpreterState_Clear(pInterpreterState);
2869 PyEval_ReleaseThread(pThreadState);
2870 PyInterpreterState_Delete(pInterpreterState);
2871 #endif
2873 return result;
2876 #else /* which OS? */
2877 static PyObject *
2878 posix_popen(PyObject *self, PyObject *args)
2880 char *name;
2881 char *mode = "r";
2882 int bufsize = -1;
2883 FILE *fp;
2884 PyObject *f;
2885 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2886 return NULL;
2887 Py_BEGIN_ALLOW_THREADS
2888 fp = popen(name, mode);
2889 Py_END_ALLOW_THREADS
2890 if (fp == NULL)
2891 return posix_error();
2892 f = PyFile_FromFile(fp, name, mode, pclose);
2893 if (f != NULL)
2894 PyFile_SetBufSize(f, bufsize);
2895 return f;
2897 #endif
2899 #endif /* HAVE_POPEN */
2902 #ifdef HAVE_SETUID
2903 static char posix_setuid__doc__[] =
2904 "setuid(uid) -> None\n\
2905 Set the current process's user id.";
2906 static PyObject *
2907 posix_setuid(PyObject *self, PyObject *args)
2909 int uid;
2910 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
2911 return NULL;
2912 if (setuid(uid) < 0)
2913 return posix_error();
2914 Py_INCREF(Py_None);
2915 return Py_None;
2917 #endif /* HAVE_SETUID */
2920 #ifdef HAVE_SETEUID
2921 static char posix_seteuid__doc__[] =
2922 "seteuid(uid) -> None\n\
2923 Set the current process's effective user id.";
2924 static PyObject *
2925 posix_seteuid (PyObject *self, PyObject *args)
2927 int euid;
2928 if (!PyArg_ParseTuple(args, "i", &euid)) {
2929 return NULL;
2930 } else if (seteuid(euid) < 0) {
2931 return posix_error();
2932 } else {
2933 Py_INCREF(Py_None);
2934 return Py_None;
2937 #endif /* HAVE_SETEUID */
2939 #ifdef HAVE_SETEGID
2940 static char posix_setegid__doc__[] =
2941 "setegid(gid) -> None\n\
2942 Set the current process's effective group id.";
2943 static PyObject *
2944 posix_setegid (PyObject *self, PyObject *args)
2946 int egid;
2947 if (!PyArg_ParseTuple(args, "i", &egid)) {
2948 return NULL;
2949 } else if (setegid(egid) < 0) {
2950 return posix_error();
2951 } else {
2952 Py_INCREF(Py_None);
2953 return Py_None;
2956 #endif /* HAVE_SETEGID */
2958 #ifdef HAVE_SETREUID
2959 static char posix_setreuid__doc__[] =
2960 "seteuid(ruid, euid) -> None\n\
2961 Set the current process's real and effective user ids.";
2962 static PyObject *
2963 posix_setreuid (PyObject *self, PyObject *args)
2965 int ruid, euid;
2966 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2967 return NULL;
2968 } else if (setreuid(ruid, euid) < 0) {
2969 return posix_error();
2970 } else {
2971 Py_INCREF(Py_None);
2972 return Py_None;
2975 #endif /* HAVE_SETREUID */
2977 #ifdef HAVE_SETREGID
2978 static char posix_setregid__doc__[] =
2979 "setegid(rgid, egid) -> None\n\
2980 Set the current process's real and effective group ids.";
2981 static PyObject *
2982 posix_setregid (PyObject *self, PyObject *args)
2984 int rgid, egid;
2985 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2986 return NULL;
2987 } else if (setregid(rgid, egid) < 0) {
2988 return posix_error();
2989 } else {
2990 Py_INCREF(Py_None);
2991 return Py_None;
2994 #endif /* HAVE_SETREGID */
2996 #ifdef HAVE_SETGID
2997 static char posix_setgid__doc__[] =
2998 "setgid(gid) -> None\n\
2999 Set the current process's group id.";
3001 static PyObject *
3002 posix_setgid(PyObject *self, PyObject *args)
3004 int gid;
3005 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
3006 return NULL;
3007 if (setgid(gid) < 0)
3008 return posix_error();
3009 Py_INCREF(Py_None);
3010 return Py_None;
3012 #endif /* HAVE_SETGID */
3015 #ifdef HAVE_WAITPID
3016 static char posix_waitpid__doc__[] =
3017 "waitpid(pid, options) -> (pid, status)\n\
3018 Wait for completion of a given child process.";
3020 static PyObject *
3021 posix_waitpid(PyObject *self, PyObject *args)
3023 int pid, options;
3024 #ifdef UNION_WAIT
3025 union wait status;
3026 #define status_i (status.w_status)
3027 #else
3028 int status;
3029 #define status_i status
3030 #endif
3031 status_i = 0;
3033 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
3034 return NULL;
3035 Py_BEGIN_ALLOW_THREADS
3036 #ifdef NeXT
3037 pid = wait4(pid, &status, options, NULL);
3038 #else
3039 pid = waitpid(pid, &status, options);
3040 #endif
3041 Py_END_ALLOW_THREADS
3042 if (pid == -1)
3043 return posix_error();
3044 else
3045 return Py_BuildValue("ii", pid, status_i);
3047 #endif /* HAVE_WAITPID */
3050 #ifdef HAVE_WAIT
3051 static char posix_wait__doc__[] =
3052 "wait() -> (pid, status)\n\
3053 Wait for completion of a child process.";
3055 static PyObject *
3056 posix_wait(PyObject *self, PyObject *args)
3058 int pid;
3059 #ifdef UNION_WAIT
3060 union wait status;
3061 #define status_i (status.w_status)
3062 #else
3063 int status;
3064 #define status_i status
3065 #endif
3066 if (!PyArg_ParseTuple(args, ":wait"))
3067 return NULL;
3068 status_i = 0;
3069 Py_BEGIN_ALLOW_THREADS
3070 pid = wait(&status);
3071 Py_END_ALLOW_THREADS
3072 if (pid == -1)
3073 return posix_error();
3074 else
3075 return Py_BuildValue("ii", pid, status_i);
3076 #undef status_i
3078 #endif
3081 static char posix_lstat__doc__[] =
3082 "lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3083 Like stat(path), but do not follow symbolic links.";
3085 static PyObject *
3086 posix_lstat(PyObject *self, PyObject *args)
3088 #ifdef HAVE_LSTAT
3089 return posix_do_stat(self, args, "s:lstat", lstat);
3090 #else /* !HAVE_LSTAT */
3091 return posix_do_stat(self, args, "s:lstat", STAT);
3092 #endif /* !HAVE_LSTAT */
3096 #ifdef HAVE_READLINK
3097 static char posix_readlink__doc__[] =
3098 "readlink(path) -> path\n\
3099 Return a string representing the path to which the symbolic link points.";
3101 static PyObject *
3102 posix_readlink(PyObject *self, PyObject *args)
3104 char buf[MAXPATHLEN];
3105 char *path;
3106 int n;
3107 if (!PyArg_ParseTuple(args, "s:readlink", &path))
3108 return NULL;
3109 Py_BEGIN_ALLOW_THREADS
3110 n = readlink(path, buf, (int) sizeof buf);
3111 Py_END_ALLOW_THREADS
3112 if (n < 0)
3113 return posix_error_with_filename(path);
3114 return PyString_FromStringAndSize(buf, n);
3116 #endif /* HAVE_READLINK */
3119 #ifdef HAVE_SYMLINK
3120 static char posix_symlink__doc__[] =
3121 "symlink(src, dst) -> None\n\
3122 Create a symbolic link.";
3124 static PyObject *
3125 posix_symlink(PyObject *self, PyObject *args)
3127 return posix_2str(args, "ss:symlink", symlink);
3129 #endif /* HAVE_SYMLINK */
3132 #ifdef HAVE_TIMES
3133 #ifndef HZ
3134 #define HZ 60 /* Universal constant :-) */
3135 #endif /* HZ */
3137 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
3138 static long
3139 system_uptime(void)
3141 ULONG value = 0;
3143 Py_BEGIN_ALLOW_THREADS
3144 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3145 Py_END_ALLOW_THREADS
3147 return value;
3150 static PyObject *
3151 posix_times(PyObject *self, PyObject *args)
3153 if (!PyArg_ParseTuple(args, ":times"))
3154 return NULL;
3156 /* Currently Only Uptime is Provided -- Others Later */
3157 return Py_BuildValue("ddddd",
3158 (double)0 /* t.tms_utime / HZ */,
3159 (double)0 /* t.tms_stime / HZ */,
3160 (double)0 /* t.tms_cutime / HZ */,
3161 (double)0 /* t.tms_cstime / HZ */,
3162 (double)system_uptime() / 1000);
3164 #else /* not OS2 */
3165 static PyObject *
3166 posix_times(PyObject *self, PyObject *args)
3168 struct tms t;
3169 clock_t c;
3170 if (!PyArg_ParseTuple(args, ":times"))
3171 return NULL;
3172 errno = 0;
3173 c = times(&t);
3174 if (c == (clock_t) -1)
3175 return posix_error();
3176 return Py_BuildValue("ddddd",
3177 (double)t.tms_utime / HZ,
3178 (double)t.tms_stime / HZ,
3179 (double)t.tms_cutime / HZ,
3180 (double)t.tms_cstime / HZ,
3181 (double)c / HZ);
3183 #endif /* not OS2 */
3184 #endif /* HAVE_TIMES */
3187 #ifdef MS_WIN32
3188 #define HAVE_TIMES /* so the method table will pick it up */
3189 static PyObject *
3190 posix_times(PyObject *self, PyObject *args)
3192 FILETIME create, exit, kernel, user;
3193 HANDLE hProc;
3194 if (!PyArg_ParseTuple(args, ":times"))
3195 return NULL;
3196 hProc = GetCurrentProcess();
3197 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3198 /* The fields of a FILETIME structure are the hi and lo part
3199 of a 64-bit value expressed in 100 nanosecond units.
3200 1e7 is one second in such units; 1e-7 the inverse.
3201 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3203 return Py_BuildValue(
3204 "ddddd",
3205 (double)(kernel.dwHighDateTime*429.4967296 +
3206 kernel.dwLowDateTime*1e-7),
3207 (double)(user.dwHighDateTime*429.4967296 +
3208 user.dwLowDateTime*1e-7),
3209 (double)0,
3210 (double)0,
3211 (double)0);
3213 #endif /* MS_WIN32 */
3215 #ifdef HAVE_TIMES
3216 static char posix_times__doc__[] =
3217 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3218 Return a tuple of floating point numbers indicating process times.";
3219 #endif
3222 #ifdef HAVE_SETSID
3223 static char posix_setsid__doc__[] =
3224 "setsid() -> None\n\
3225 Call the system call setsid().";
3227 static PyObject *
3228 posix_setsid(PyObject *self, PyObject *args)
3230 if (!PyArg_ParseTuple(args, ":setsid"))
3231 return NULL;
3232 if (setsid() < 0)
3233 return posix_error();
3234 Py_INCREF(Py_None);
3235 return Py_None;
3237 #endif /* HAVE_SETSID */
3239 #ifdef HAVE_SETPGID
3240 static char posix_setpgid__doc__[] =
3241 "setpgid(pid, pgrp) -> None\n\
3242 Call the system call setpgid().";
3244 static PyObject *
3245 posix_setpgid(PyObject *self, PyObject *args)
3247 int pid, pgrp;
3248 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
3249 return NULL;
3250 if (setpgid(pid, pgrp) < 0)
3251 return posix_error();
3252 Py_INCREF(Py_None);
3253 return Py_None;
3255 #endif /* HAVE_SETPGID */
3258 #ifdef HAVE_TCGETPGRP
3259 static char posix_tcgetpgrp__doc__[] =
3260 "tcgetpgrp(fd) -> pgid\n\
3261 Return the process group associated with the terminal given by a fd.";
3263 static PyObject *
3264 posix_tcgetpgrp(PyObject *self, PyObject *args)
3266 int fd, pgid;
3267 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
3268 return NULL;
3269 pgid = tcgetpgrp(fd);
3270 if (pgid < 0)
3271 return posix_error();
3272 return PyInt_FromLong((long)pgid);
3274 #endif /* HAVE_TCGETPGRP */
3277 #ifdef HAVE_TCSETPGRP
3278 static char posix_tcsetpgrp__doc__[] =
3279 "tcsetpgrp(fd, pgid) -> None\n\
3280 Set the process group associated with the terminal given by a fd.";
3282 static PyObject *
3283 posix_tcsetpgrp(PyObject *self, PyObject *args)
3285 int fd, pgid;
3286 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
3287 return NULL;
3288 if (tcsetpgrp(fd, pgid) < 0)
3289 return posix_error();
3290 Py_INCREF(Py_None);
3291 return Py_None;
3293 #endif /* HAVE_TCSETPGRP */
3295 /* Functions acting on file descriptors */
3297 static char posix_open__doc__[] =
3298 "open(filename, flag [, mode=0777]) -> fd\n\
3299 Open a file (for low level IO).";
3301 static PyObject *
3302 posix_open(PyObject *self, PyObject *args)
3304 char *file;
3305 int flag;
3306 int mode = 0777;
3307 int fd;
3308 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3309 return NULL;
3311 Py_BEGIN_ALLOW_THREADS
3312 fd = open(file, flag, mode);
3313 Py_END_ALLOW_THREADS
3314 if (fd < 0)
3315 return posix_error_with_filename(file);
3316 return PyInt_FromLong((long)fd);
3320 static char posix_close__doc__[] =
3321 "close(fd) -> None\n\
3322 Close a file descriptor (for low level IO).";
3324 static PyObject *
3325 posix_close(PyObject *self, PyObject *args)
3327 int fd, res;
3328 if (!PyArg_ParseTuple(args, "i:close", &fd))
3329 return NULL;
3330 Py_BEGIN_ALLOW_THREADS
3331 res = close(fd);
3332 Py_END_ALLOW_THREADS
3333 if (res < 0)
3334 return posix_error();
3335 Py_INCREF(Py_None);
3336 return Py_None;
3340 static char posix_dup__doc__[] =
3341 "dup(fd) -> fd2\n\
3342 Return a duplicate of a file descriptor.";
3344 static PyObject *
3345 posix_dup(PyObject *self, PyObject *args)
3347 int fd;
3348 if (!PyArg_ParseTuple(args, "i:dup", &fd))
3349 return NULL;
3350 Py_BEGIN_ALLOW_THREADS
3351 fd = dup(fd);
3352 Py_END_ALLOW_THREADS
3353 if (fd < 0)
3354 return posix_error();
3355 return PyInt_FromLong((long)fd);
3359 static char posix_dup2__doc__[] =
3360 "dup2(fd, fd2) -> None\n\
3361 Duplicate file descriptor.";
3363 static PyObject *
3364 posix_dup2(PyObject *self, PyObject *args)
3366 int fd, fd2, res;
3367 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
3368 return NULL;
3369 Py_BEGIN_ALLOW_THREADS
3370 res = dup2(fd, fd2);
3371 Py_END_ALLOW_THREADS
3372 if (res < 0)
3373 return posix_error();
3374 Py_INCREF(Py_None);
3375 return Py_None;
3379 static char posix_lseek__doc__[] =
3380 "lseek(fd, pos, how) -> newpos\n\
3381 Set the current position of a file descriptor.";
3383 static PyObject *
3384 posix_lseek(PyObject *self, PyObject *args)
3386 int fd, how;
3387 #ifdef MS_WIN64
3388 LONG_LONG pos, res;
3389 #else
3390 off_t pos, res;
3391 #endif
3392 PyObject *posobj;
3393 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
3394 return NULL;
3395 #ifdef SEEK_SET
3396 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3397 switch (how) {
3398 case 0: how = SEEK_SET; break;
3399 case 1: how = SEEK_CUR; break;
3400 case 2: how = SEEK_END; break;
3402 #endif /* SEEK_END */
3404 #if !defined(HAVE_LARGEFILE_SUPPORT)
3405 pos = PyInt_AsLong(posobj);
3406 #else
3407 pos = PyLong_Check(posobj) ?
3408 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3409 #endif
3410 if (PyErr_Occurred())
3411 return NULL;
3413 Py_BEGIN_ALLOW_THREADS
3414 #ifdef MS_WIN64
3415 res = _lseeki64(fd, pos, how);
3416 #else
3417 res = lseek(fd, pos, how);
3418 #endif
3419 Py_END_ALLOW_THREADS
3420 if (res < 0)
3421 return posix_error();
3423 #if !defined(HAVE_LARGEFILE_SUPPORT)
3424 return PyInt_FromLong(res);
3425 #else
3426 return PyLong_FromLongLong(res);
3427 #endif
3431 static char posix_read__doc__[] =
3432 "read(fd, buffersize) -> string\n\
3433 Read a file descriptor.";
3435 static PyObject *
3436 posix_read(PyObject *self, PyObject *args)
3438 int fd, size, n;
3439 PyObject *buffer;
3440 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
3441 return NULL;
3442 buffer = PyString_FromStringAndSize((char *)NULL, size);
3443 if (buffer == NULL)
3444 return NULL;
3445 Py_BEGIN_ALLOW_THREADS
3446 n = read(fd, PyString_AsString(buffer), size);
3447 Py_END_ALLOW_THREADS
3448 if (n < 0) {
3449 Py_DECREF(buffer);
3450 return posix_error();
3452 if (n != size)
3453 _PyString_Resize(&buffer, n);
3454 return buffer;
3458 static char posix_write__doc__[] =
3459 "write(fd, string) -> byteswritten\n\
3460 Write a string to a file descriptor.";
3462 static PyObject *
3463 posix_write(PyObject *self, PyObject *args)
3465 int fd, size;
3466 char *buffer;
3467 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
3468 return NULL;
3469 Py_BEGIN_ALLOW_THREADS
3470 size = write(fd, buffer, size);
3471 Py_END_ALLOW_THREADS
3472 if (size < 0)
3473 return posix_error();
3474 return PyInt_FromLong((long)size);
3478 static char posix_fstat__doc__[]=
3479 "fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3480 Like stat(), but for an open file descriptor.";
3482 static PyObject *
3483 posix_fstat(PyObject *self, PyObject *args)
3485 int fd;
3486 STRUCT_STAT st;
3487 int res;
3488 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
3489 return NULL;
3490 Py_BEGIN_ALLOW_THREADS
3491 res = FSTAT(fd, &st);
3492 Py_END_ALLOW_THREADS
3493 if (res != 0)
3494 return posix_error();
3496 return _pystat_fromstructstat(st);
3500 static char posix_fdopen__doc__[] =
3501 "fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3502 Return an open file object connected to a file descriptor.";
3504 static PyObject *
3505 posix_fdopen(PyObject *self, PyObject *args)
3507 int fd;
3508 char *mode = "r";
3509 int bufsize = -1;
3510 FILE *fp;
3511 PyObject *f;
3512 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
3513 return NULL;
3515 Py_BEGIN_ALLOW_THREADS
3516 fp = fdopen(fd, mode);
3517 Py_END_ALLOW_THREADS
3518 if (fp == NULL)
3519 return posix_error();
3520 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
3521 if (f != NULL)
3522 PyFile_SetBufSize(f, bufsize);
3523 return f;
3526 static char posix_isatty__doc__[] =
3527 "isatty(fd) -> Boolean\n\
3528 Return true if the file descriptor 'fd' is an open file descriptor\n\
3529 connected to the slave end of a terminal.";
3531 static PyObject *
3532 posix_isatty(PyObject *self, PyObject *args)
3534 int fd;
3535 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3536 return NULL;
3537 return Py_BuildValue("i", isatty(fd));
3540 #ifdef HAVE_PIPE
3541 static char posix_pipe__doc__[] =
3542 "pipe() -> (read_end, write_end)\n\
3543 Create a pipe.";
3545 static PyObject *
3546 posix_pipe(PyObject *self, PyObject *args)
3548 #if defined(PYOS_OS2)
3549 HFILE read, write;
3550 APIRET rc;
3552 if (!PyArg_ParseTuple(args, ":pipe"))
3553 return NULL;
3555 Py_BEGIN_ALLOW_THREADS
3556 rc = DosCreatePipe( &read, &write, 4096);
3557 Py_END_ALLOW_THREADS
3558 if (rc != NO_ERROR)
3559 return os2_error(rc);
3561 return Py_BuildValue("(ii)", read, write);
3562 #else
3563 #if !defined(MS_WIN32)
3564 int fds[2];
3565 int res;
3566 if (!PyArg_ParseTuple(args, ":pipe"))
3567 return NULL;
3568 Py_BEGIN_ALLOW_THREADS
3569 res = pipe(fds);
3570 Py_END_ALLOW_THREADS
3571 if (res != 0)
3572 return posix_error();
3573 return Py_BuildValue("(ii)", fds[0], fds[1]);
3574 #else /* MS_WIN32 */
3575 HANDLE read, write;
3576 int read_fd, write_fd;
3577 BOOL ok;
3578 if (!PyArg_ParseTuple(args, ":pipe"))
3579 return NULL;
3580 Py_BEGIN_ALLOW_THREADS
3581 ok = CreatePipe(&read, &write, NULL, 0);
3582 Py_END_ALLOW_THREADS
3583 if (!ok)
3584 return win32_error("CreatePipe", NULL);
3585 read_fd = _open_osfhandle((intptr_t)read, 0);
3586 write_fd = _open_osfhandle((intptr_t)write, 1);
3587 return Py_BuildValue("(ii)", read_fd, write_fd);
3588 #endif /* MS_WIN32 */
3589 #endif
3591 #endif /* HAVE_PIPE */
3594 #ifdef HAVE_MKFIFO
3595 static char posix_mkfifo__doc__[] =
3596 "mkfifo(file, [, mode=0666]) -> None\n\
3597 Create a FIFO (a POSIX named pipe).";
3599 static PyObject *
3600 posix_mkfifo(PyObject *self, PyObject *args)
3602 char *file;
3603 int mode = 0666;
3604 int res;
3605 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
3606 return NULL;
3607 Py_BEGIN_ALLOW_THREADS
3608 res = mkfifo(file, mode);
3609 Py_END_ALLOW_THREADS
3610 if (res < 0)
3611 return posix_error();
3612 Py_INCREF(Py_None);
3613 return Py_None;
3615 #endif
3618 #ifdef HAVE_FTRUNCATE
3619 static char posix_ftruncate__doc__[] =
3620 "ftruncate(fd, length) -> None\n\
3621 Truncate a file to a specified length.";
3623 static PyObject *
3624 posix_ftruncate(PyObject *self, PyObject *args)
3626 int fd;
3627 off_t length;
3628 int res;
3629 PyObject *lenobj;
3631 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
3632 return NULL;
3634 #if !defined(HAVE_LARGEFILE_SUPPORT)
3635 length = PyInt_AsLong(lenobj);
3636 #else
3637 length = PyLong_Check(lenobj) ?
3638 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3639 #endif
3640 if (PyErr_Occurred())
3641 return NULL;
3643 Py_BEGIN_ALLOW_THREADS
3644 res = ftruncate(fd, length);
3645 Py_END_ALLOW_THREADS
3646 if (res < 0) {
3647 PyErr_SetFromErrno(PyExc_IOError);
3648 return NULL;
3650 Py_INCREF(Py_None);
3651 return Py_None;
3653 #endif
3655 #ifdef NeXT
3656 #define HAVE_PUTENV
3657 /* Steve Spicklemire got this putenv from NeXTAnswers */
3658 static int
3659 putenv(char *newval)
3661 extern char **environ;
3663 static int firstTime = 1;
3664 char **ep;
3665 char *cp;
3666 int esiz;
3667 char *np;
3669 if (!(np = strchr(newval, '=')))
3670 return 1;
3671 *np = '\0';
3673 /* look it up */
3674 for (ep=environ ; *ep ; ep++)
3676 /* this should always be true... */
3677 if (cp = strchr(*ep, '='))
3679 *cp = '\0';
3680 if (!strcmp(*ep, newval))
3682 /* got it! */
3683 *cp = '=';
3684 break;
3686 *cp = '=';
3688 else
3690 *np = '=';
3691 return 1;
3695 *np = '=';
3696 if (*ep)
3698 /* the string was already there:
3699 just replace it with the new one */
3700 *ep = newval;
3701 return 0;
3704 /* expand environ by one */
3705 for (esiz=2, ep=environ ; *ep ; ep++)
3706 esiz++;
3707 if (firstTime)
3709 char **epp;
3710 char **newenv;
3711 if (!(newenv = malloc(esiz * sizeof(char *))))
3712 return 1;
3714 for (ep=environ, epp=newenv ; *ep ;)
3715 *epp++ = *ep++;
3716 *epp++ = newval;
3717 *epp = (char *) 0;
3718 environ = newenv;
3720 else
3722 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3723 return 1;
3724 environ[esiz - 2] = newval;
3725 environ[esiz - 1] = (char *) 0;
3726 firstTime = 0;
3729 return 0;
3731 #endif /* NeXT */
3734 #ifdef HAVE_PUTENV
3735 static char posix_putenv__doc__[] =
3736 "putenv(key, value) -> None\n\
3737 Change or add an environment variable.";
3739 /* Save putenv() parameters as values here, so we can collect them when they
3740 * get re-set with another call for the same key. */
3741 static PyObject *posix_putenv_garbage;
3743 static PyObject *
3744 posix_putenv(PyObject *self, PyObject *args)
3746 char *s1, *s2;
3747 char *new;
3748 PyObject *newstr;
3750 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
3751 return NULL;
3753 #if defined(PYOS_OS2)
3754 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3755 APIRET rc;
3757 if (strlen(s2) == 0) /* If New Value is an Empty String */
3758 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3760 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3761 if (rc != NO_ERROR)
3762 return os2_error(rc);
3764 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3765 APIRET rc;
3767 if (strlen(s2) == 0) /* If New Value is an Empty String */
3768 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3770 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3771 if (rc != NO_ERROR)
3772 return os2_error(rc);
3773 } else {
3774 #endif
3776 /* XXX This can leak memory -- not easy to fix :-( */
3777 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3778 if (newstr == NULL)
3779 return PyErr_NoMemory();
3780 new = PyString_AS_STRING(newstr);
3781 (void) sprintf(new, "%s=%s", s1, s2);
3782 if (putenv(new)) {
3783 posix_error();
3784 return NULL;
3786 /* Install the first arg and newstr in posix_putenv_garbage;
3787 * this will cause previous value to be collected. This has to
3788 * happen after the real putenv() call because the old value
3789 * was still accessible until then. */
3790 if (PyDict_SetItem(posix_putenv_garbage,
3791 PyTuple_GET_ITEM(args, 0), newstr)) {
3792 /* really not much we can do; just leak */
3793 PyErr_Clear();
3795 else {
3796 Py_DECREF(newstr);
3799 #if defined(PYOS_OS2)
3801 #endif
3802 Py_INCREF(Py_None);
3803 return Py_None;
3805 #endif /* putenv */
3807 #ifdef HAVE_STRERROR
3808 static char posix_strerror__doc__[] =
3809 "strerror(code) -> string\n\
3810 Translate an error code to a message string.";
3812 PyObject *
3813 posix_strerror(PyObject *self, PyObject *args)
3815 int code;
3816 char *message;
3817 if (!PyArg_ParseTuple(args, "i:strerror", &code))
3818 return NULL;
3819 message = strerror(code);
3820 if (message == NULL) {
3821 PyErr_SetString(PyExc_ValueError,
3822 "strerror() argument out of range");
3823 return NULL;
3825 return PyString_FromString(message);
3827 #endif /* strerror */
3830 #ifdef HAVE_SYS_WAIT_H
3832 #ifdef WIFSTOPPED
3833 static char posix_WIFSTOPPED__doc__[] =
3834 "WIFSTOPPED(status) -> Boolean\n\
3835 Return true if the process returning 'status' was stopped.";
3837 static PyObject *
3838 posix_WIFSTOPPED(PyObject *self, PyObject *args)
3840 #ifdef UNION_WAIT
3841 union wait status;
3842 #define status_i (status.w_status)
3843 #else
3844 int status;
3845 #define status_i status
3846 #endif
3847 status_i = 0;
3849 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
3851 return NULL;
3854 return Py_BuildValue("i", WIFSTOPPED(status));
3855 #undef status_i
3857 #endif /* WIFSTOPPED */
3859 #ifdef WIFSIGNALED
3860 static char posix_WIFSIGNALED__doc__[] =
3861 "WIFSIGNALED(status) -> Boolean\n\
3862 Return true if the process returning 'status' was terminated by a signal.";
3864 static PyObject *
3865 posix_WIFSIGNALED(PyObject *self, PyObject *args)
3867 #ifdef UNION_WAIT
3868 union wait status;
3869 #define status_i (status.w_status)
3870 #else
3871 int status;
3872 #define status_i status
3873 #endif
3874 status_i = 0;
3876 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
3878 return NULL;
3881 return Py_BuildValue("i", WIFSIGNALED(status));
3882 #undef status_i
3884 #endif /* WIFSIGNALED */
3886 #ifdef WIFEXITED
3887 static char posix_WIFEXITED__doc__[] =
3888 "WIFEXITED(status) -> Boolean\n\
3889 Return true if the process returning 'status' exited using the exit()\n\
3890 system call.";
3892 static PyObject *
3893 posix_WIFEXITED(PyObject *self, PyObject *args)
3895 #ifdef UNION_WAIT
3896 union wait status;
3897 #define status_i (status.w_status)
3898 #else
3899 int status;
3900 #define status_i status
3901 #endif
3902 status_i = 0;
3904 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
3906 return NULL;
3909 return Py_BuildValue("i", WIFEXITED(status));
3910 #undef status_i
3912 #endif /* WIFEXITED */
3914 #ifdef WEXITSTATUS
3915 static char posix_WEXITSTATUS__doc__[] =
3916 "WEXITSTATUS(status) -> integer\n\
3917 Return the process return code from 'status'.";
3919 static PyObject *
3920 posix_WEXITSTATUS(PyObject *self, PyObject *args)
3922 #ifdef UNION_WAIT
3923 union wait status;
3924 #define status_i (status.w_status)
3925 #else
3926 int status;
3927 #define status_i status
3928 #endif
3929 status_i = 0;
3931 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
3933 return NULL;
3936 return Py_BuildValue("i", WEXITSTATUS(status));
3937 #undef status_i
3939 #endif /* WEXITSTATUS */
3941 #ifdef WTERMSIG
3942 static char posix_WTERMSIG__doc__[] =
3943 "WTERMSIG(status) -> integer\n\
3944 Return the signal that terminated the process that provided the 'status'\n\
3945 value.";
3947 static PyObject *
3948 posix_WTERMSIG(PyObject *self, PyObject *args)
3950 #ifdef UNION_WAIT
3951 union wait status;
3952 #define status_i (status.w_status)
3953 #else
3954 int status;
3955 #define status_i status
3956 #endif
3957 status_i = 0;
3959 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
3961 return NULL;
3964 return Py_BuildValue("i", WTERMSIG(status));
3965 #undef status_i
3967 #endif /* WTERMSIG */
3969 #ifdef WSTOPSIG
3970 static char posix_WSTOPSIG__doc__[] =
3971 "WSTOPSIG(status) -> integer\n\
3972 Return the signal that stopped the process that provided the 'status' value.";
3974 static PyObject *
3975 posix_WSTOPSIG(PyObject *self, PyObject *args)
3977 #ifdef UNION_WAIT
3978 union wait status;
3979 #define status_i (status.w_status)
3980 #else
3981 int status;
3982 #define status_i status
3983 #endif
3984 status_i = 0;
3986 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
3988 return NULL;
3991 return Py_BuildValue("i", WSTOPSIG(status));
3992 #undef status_i
3994 #endif /* WSTOPSIG */
3996 #endif /* HAVE_SYS_WAIT_H */
3999 #if defined(HAVE_FSTATVFS)
4000 #ifdef _SCO_DS
4001 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4002 needed definitions in sys/statvfs.h */
4003 #define _SVID3
4004 #endif
4005 #include <sys/statvfs.h>
4007 static char posix_fstatvfs__doc__[] =
4008 "fstatvfs(fd) -> \n\
4009 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
4010 Perform an fstatvfs system call on the given fd.";
4012 static PyObject *
4013 posix_fstatvfs(PyObject *self, PyObject *args)
4015 int fd, res;
4016 struct statvfs st;
4017 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
4018 return NULL;
4019 Py_BEGIN_ALLOW_THREADS
4020 res = fstatvfs(fd, &st);
4021 Py_END_ALLOW_THREADS
4022 if (res != 0)
4023 return posix_error();
4024 #if !defined(HAVE_LARGEFILE_SUPPORT)
4025 return Py_BuildValue("(llllllllll)",
4026 (long) st.f_bsize,
4027 (long) st.f_frsize,
4028 (long) st.f_blocks,
4029 (long) st.f_bfree,
4030 (long) st.f_bavail,
4031 (long) st.f_files,
4032 (long) st.f_ffree,
4033 (long) st.f_favail,
4034 (long) st.f_flag,
4035 (long) st.f_namemax);
4036 #else
4037 return Py_BuildValue("(llLLLLLLll)",
4038 (long) st.f_bsize,
4039 (long) st.f_frsize,
4040 (LONG_LONG) st.f_blocks,
4041 (LONG_LONG) st.f_bfree,
4042 (LONG_LONG) st.f_bavail,
4043 (LONG_LONG) st.f_files,
4044 (LONG_LONG) st.f_ffree,
4045 (LONG_LONG) st.f_favail,
4046 (long) st.f_flag,
4047 (long) st.f_namemax);
4048 #endif
4050 #endif /* HAVE_FSTATVFS */
4053 #if defined(HAVE_STATVFS)
4054 #include <sys/statvfs.h>
4056 static char posix_statvfs__doc__[] =
4057 "statvfs(path) -> \n\
4058 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
4059 Perform a statvfs system call on the given path.";
4061 static PyObject *
4062 posix_statvfs(PyObject *self, PyObject *args)
4064 char *path;
4065 int res;
4066 struct statvfs st;
4067 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
4068 return NULL;
4069 Py_BEGIN_ALLOW_THREADS
4070 res = statvfs(path, &st);
4071 Py_END_ALLOW_THREADS
4072 if (res != 0)
4073 return posix_error_with_filename(path);
4074 #if !defined(HAVE_LARGEFILE_SUPPORT)
4075 return Py_BuildValue("(llllllllll)",
4076 (long) st.f_bsize,
4077 (long) st.f_frsize,
4078 (long) st.f_blocks,
4079 (long) st.f_bfree,
4080 (long) st.f_bavail,
4081 (long) st.f_files,
4082 (long) st.f_ffree,
4083 (long) st.f_favail,
4084 (long) st.f_flag,
4085 (long) st.f_namemax);
4086 #else /* HAVE_LARGEFILE_SUPPORT */
4087 return Py_BuildValue("(llLLLLLLll)",
4088 (long) st.f_bsize,
4089 (long) st.f_frsize,
4090 (LONG_LONG) st.f_blocks,
4091 (LONG_LONG) st.f_bfree,
4092 (LONG_LONG) st.f_bavail,
4093 (LONG_LONG) st.f_files,
4094 (LONG_LONG) st.f_ffree,
4095 (LONG_LONG) st.f_favail,
4096 (long) st.f_flag,
4097 (long) st.f_namemax);
4098 #endif
4100 #endif /* HAVE_STATVFS */
4103 #ifdef HAVE_TEMPNAM
4104 static char posix_tempnam__doc__[] = "\
4105 tempnam([dir[, prefix]]) -> string\n\
4106 Return a unique name for a temporary file.\n\
4107 The directory and a short may be specified as strings; they may be omitted\n\
4108 or None if not needed.";
4110 static PyObject *
4111 posix_tempnam(PyObject *self, PyObject *args)
4113 PyObject *result = NULL;
4114 char *dir = NULL;
4115 char *pfx = NULL;
4116 char *name;
4118 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4119 return NULL;
4120 name = tempnam(dir, pfx);
4121 if (name == NULL)
4122 return PyErr_NoMemory();
4123 result = PyString_FromString(name);
4124 free(name);
4125 return result;
4127 #endif
4130 #ifdef HAVE_TMPFILE
4131 static char posix_tmpfile__doc__[] = "\
4132 tmpfile() -> file object\n\
4133 Create a temporary file with no directory entries.";
4135 static PyObject *
4136 posix_tmpfile(PyObject *self, PyObject *args)
4138 FILE *fp;
4140 if (!PyArg_ParseTuple(args, ":tmpfile"))
4141 return NULL;
4142 fp = tmpfile();
4143 if (fp == NULL)
4144 return posix_error();
4145 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4147 #endif
4150 #ifdef HAVE_TMPNAM
4151 static char posix_tmpnam__doc__[] = "\
4152 tmpnam() -> string\n\
4153 Return a unique name for a temporary file.";
4155 static PyObject *
4156 posix_tmpnam(PyObject *self, PyObject *args)
4158 char buffer[L_tmpnam];
4159 char *name;
4161 if (!PyArg_ParseTuple(args, ":tmpnam"))
4162 return NULL;
4163 #ifdef USE_TMPNAM_R
4164 name = tmpnam_r(buffer);
4165 #else
4166 name = tmpnam(buffer);
4167 #endif
4168 if (name == NULL) {
4169 PyErr_SetObject(PyExc_OSError,
4170 Py_BuildValue("is", 0,
4171 #ifdef USE_TMPNAM_R
4172 "unexpected NULL from tmpnam_r"
4173 #else
4174 "unexpected NULL from tmpnam"
4175 #endif
4177 return NULL;
4179 return PyString_FromString(buffer);
4181 #endif
4184 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4185 * It maps strings representing configuration variable names to
4186 * integer values, allowing those functions to be called with the
4187 * magic names instead of polluting the module's namespace with tons of
4188 * rarely-used constants. There are three separate tables that use
4189 * these definitions.
4191 * This code is always included, even if none of the interfaces that
4192 * need it are included. The #if hackery needed to avoid it would be
4193 * sufficiently pervasive that it's not worth the loss of readability.
4195 struct constdef {
4196 char *name;
4197 long value;
4200 static int
4201 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4202 size_t tablesize)
4204 if (PyInt_Check(arg)) {
4205 *valuep = PyInt_AS_LONG(arg);
4206 return 1;
4208 if (PyString_Check(arg)) {
4209 /* look up the value in the table using a binary search */
4210 size_t lo = 0;
4211 size_t mid;
4212 size_t hi = tablesize;
4213 int cmp;
4214 char *confname = PyString_AS_STRING(arg);
4215 while (lo < hi) {
4216 mid = (lo + hi) / 2;
4217 cmp = strcmp(confname, table[mid].name);
4218 if (cmp < 0)
4219 hi = mid;
4220 else if (cmp > 0)
4221 lo = mid + 1;
4222 else {
4223 *valuep = table[mid].value;
4224 return 1;
4227 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4229 else
4230 PyErr_SetString(PyExc_TypeError,
4231 "configuration names must be strings or integers");
4232 return 0;
4236 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4237 static struct constdef posix_constants_pathconf[] = {
4238 #ifdef _PC_ABI_AIO_XFER_MAX
4239 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4240 #endif
4241 #ifdef _PC_ABI_ASYNC_IO
4242 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4243 #endif
4244 #ifdef _PC_ASYNC_IO
4245 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4246 #endif
4247 #ifdef _PC_CHOWN_RESTRICTED
4248 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4249 #endif
4250 #ifdef _PC_FILESIZEBITS
4251 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4252 #endif
4253 #ifdef _PC_LAST
4254 {"PC_LAST", _PC_LAST},
4255 #endif
4256 #ifdef _PC_LINK_MAX
4257 {"PC_LINK_MAX", _PC_LINK_MAX},
4258 #endif
4259 #ifdef _PC_MAX_CANON
4260 {"PC_MAX_CANON", _PC_MAX_CANON},
4261 #endif
4262 #ifdef _PC_MAX_INPUT
4263 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4264 #endif
4265 #ifdef _PC_NAME_MAX
4266 {"PC_NAME_MAX", _PC_NAME_MAX},
4267 #endif
4268 #ifdef _PC_NO_TRUNC
4269 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4270 #endif
4271 #ifdef _PC_PATH_MAX
4272 {"PC_PATH_MAX", _PC_PATH_MAX},
4273 #endif
4274 #ifdef _PC_PIPE_BUF
4275 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4276 #endif
4277 #ifdef _PC_PRIO_IO
4278 {"PC_PRIO_IO", _PC_PRIO_IO},
4279 #endif
4280 #ifdef _PC_SOCK_MAXBUF
4281 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4282 #endif
4283 #ifdef _PC_SYNC_IO
4284 {"PC_SYNC_IO", _PC_SYNC_IO},
4285 #endif
4286 #ifdef _PC_VDISABLE
4287 {"PC_VDISABLE", _PC_VDISABLE},
4288 #endif
4291 static int
4292 conv_path_confname(PyObject *arg, int *valuep)
4294 return conv_confname(arg, valuep, posix_constants_pathconf,
4295 sizeof(posix_constants_pathconf)
4296 / sizeof(struct constdef));
4298 #endif
4300 #ifdef HAVE_FPATHCONF
4301 static char posix_fpathconf__doc__[] = "\
4302 fpathconf(fd, name) -> integer\n\
4303 Return the configuration limit name for the file descriptor fd.\n\
4304 If there is no limit, return -1.";
4306 static PyObject *
4307 posix_fpathconf(PyObject *self, PyObject *args)
4309 PyObject *result = NULL;
4310 int name, fd;
4312 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4313 conv_path_confname, &name)) {
4314 long limit;
4316 errno = 0;
4317 limit = fpathconf(fd, name);
4318 if (limit == -1 && errno != 0)
4319 posix_error();
4320 else
4321 result = PyInt_FromLong(limit);
4323 return result;
4325 #endif
4328 #ifdef HAVE_PATHCONF
4329 static char posix_pathconf__doc__[] = "\
4330 pathconf(path, name) -> integer\n\
4331 Return the configuration limit name for the file or directory path.\n\
4332 If there is no limit, return -1.";
4334 static PyObject *
4335 posix_pathconf(PyObject *self, PyObject *args)
4337 PyObject *result = NULL;
4338 int name;
4339 char *path;
4341 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4342 conv_path_confname, &name)) {
4343 long limit;
4345 errno = 0;
4346 limit = pathconf(path, name);
4347 if (limit == -1 && errno != 0) {
4348 if (errno == EINVAL)
4349 /* could be a path or name problem */
4350 posix_error();
4351 else
4352 posix_error_with_filename(path);
4354 else
4355 result = PyInt_FromLong(limit);
4357 return result;
4359 #endif
4361 #ifdef HAVE_CONFSTR
4362 static struct constdef posix_constants_confstr[] = {
4363 #ifdef _CS_ARCHITECTURE
4364 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4365 #endif
4366 #ifdef _CS_HOSTNAME
4367 {"CS_HOSTNAME", _CS_HOSTNAME},
4368 #endif
4369 #ifdef _CS_HW_PROVIDER
4370 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4371 #endif
4372 #ifdef _CS_HW_SERIAL
4373 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4374 #endif
4375 #ifdef _CS_INITTAB_NAME
4376 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4377 #endif
4378 #ifdef _CS_LFS64_CFLAGS
4379 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4380 #endif
4381 #ifdef _CS_LFS64_LDFLAGS
4382 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4383 #endif
4384 #ifdef _CS_LFS64_LIBS
4385 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4386 #endif
4387 #ifdef _CS_LFS64_LINTFLAGS
4388 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4389 #endif
4390 #ifdef _CS_LFS_CFLAGS
4391 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4392 #endif
4393 #ifdef _CS_LFS_LDFLAGS
4394 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4395 #endif
4396 #ifdef _CS_LFS_LIBS
4397 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4398 #endif
4399 #ifdef _CS_LFS_LINTFLAGS
4400 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4401 #endif
4402 #ifdef _CS_MACHINE
4403 {"CS_MACHINE", _CS_MACHINE},
4404 #endif
4405 #ifdef _CS_PATH
4406 {"CS_PATH", _CS_PATH},
4407 #endif
4408 #ifdef _CS_RELEASE
4409 {"CS_RELEASE", _CS_RELEASE},
4410 #endif
4411 #ifdef _CS_SRPC_DOMAIN
4412 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4413 #endif
4414 #ifdef _CS_SYSNAME
4415 {"CS_SYSNAME", _CS_SYSNAME},
4416 #endif
4417 #ifdef _CS_VERSION
4418 {"CS_VERSION", _CS_VERSION},
4419 #endif
4420 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4421 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4422 #endif
4423 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4424 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4425 #endif
4426 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
4427 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4428 #endif
4429 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4430 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4431 #endif
4432 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4433 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4434 #endif
4435 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4436 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4437 #endif
4438 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4439 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4440 #endif
4441 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4442 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4443 #endif
4444 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4445 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4446 #endif
4447 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4448 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4449 #endif
4450 #ifdef _CS_XBS5_LP64_OFF64_LIBS
4451 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4452 #endif
4453 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4454 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4455 #endif
4456 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4457 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4458 #endif
4459 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4460 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4461 #endif
4462 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4463 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4464 #endif
4465 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4466 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4467 #endif
4468 #ifdef _MIPS_CS_AVAIL_PROCESSORS
4469 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4470 #endif
4471 #ifdef _MIPS_CS_BASE
4472 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4473 #endif
4474 #ifdef _MIPS_CS_HOSTID
4475 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4476 #endif
4477 #ifdef _MIPS_CS_HW_NAME
4478 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4479 #endif
4480 #ifdef _MIPS_CS_NUM_PROCESSORS
4481 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4482 #endif
4483 #ifdef _MIPS_CS_OSREL_MAJ
4484 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4485 #endif
4486 #ifdef _MIPS_CS_OSREL_MIN
4487 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4488 #endif
4489 #ifdef _MIPS_CS_OSREL_PATCH
4490 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4491 #endif
4492 #ifdef _MIPS_CS_OS_NAME
4493 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4494 #endif
4495 #ifdef _MIPS_CS_OS_PROVIDER
4496 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4497 #endif
4498 #ifdef _MIPS_CS_PROCESSORS
4499 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4500 #endif
4501 #ifdef _MIPS_CS_SERIAL
4502 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4503 #endif
4504 #ifdef _MIPS_CS_VENDOR
4505 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4506 #endif
4509 static int
4510 conv_confstr_confname(PyObject *arg, int *valuep)
4512 return conv_confname(arg, valuep, posix_constants_confstr,
4513 sizeof(posix_constants_confstr)
4514 / sizeof(struct constdef));
4517 static char posix_confstr__doc__[] = "\
4518 confstr(name) -> string\n\
4519 Return a string-valued system configuration variable.";
4521 static PyObject *
4522 posix_confstr(PyObject *self, PyObject *args)
4524 PyObject *result = NULL;
4525 int name;
4526 char buffer[64];
4528 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4529 int len = confstr(name, buffer, sizeof(buffer));
4531 errno = 0;
4532 if (len == 0) {
4533 if (errno != 0)
4534 posix_error();
4535 else
4536 result = PyString_FromString("");
4538 else {
4539 if (len >= sizeof(buffer)) {
4540 result = PyString_FromStringAndSize(NULL, len);
4541 if (result != NULL)
4542 confstr(name, PyString_AS_STRING(result), len+1);
4544 else
4545 result = PyString_FromString(buffer);
4548 return result;
4550 #endif
4553 #ifdef HAVE_SYSCONF
4554 static struct constdef posix_constants_sysconf[] = {
4555 #ifdef _SC_2_CHAR_TERM
4556 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4557 #endif
4558 #ifdef _SC_2_C_BIND
4559 {"SC_2_C_BIND", _SC_2_C_BIND},
4560 #endif
4561 #ifdef _SC_2_C_DEV
4562 {"SC_2_C_DEV", _SC_2_C_DEV},
4563 #endif
4564 #ifdef _SC_2_C_VERSION
4565 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4566 #endif
4567 #ifdef _SC_2_FORT_DEV
4568 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4569 #endif
4570 #ifdef _SC_2_FORT_RUN
4571 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4572 #endif
4573 #ifdef _SC_2_LOCALEDEF
4574 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4575 #endif
4576 #ifdef _SC_2_SW_DEV
4577 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4578 #endif
4579 #ifdef _SC_2_UPE
4580 {"SC_2_UPE", _SC_2_UPE},
4581 #endif
4582 #ifdef _SC_2_VERSION
4583 {"SC_2_VERSION", _SC_2_VERSION},
4584 #endif
4585 #ifdef _SC_ABI_ASYNCHRONOUS_IO
4586 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4587 #endif
4588 #ifdef _SC_ACL
4589 {"SC_ACL", _SC_ACL},
4590 #endif
4591 #ifdef _SC_AIO_LISTIO_MAX
4592 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4593 #endif
4594 #ifdef _SC_AIO_MAX
4595 {"SC_AIO_MAX", _SC_AIO_MAX},
4596 #endif
4597 #ifdef _SC_AIO_PRIO_DELTA_MAX
4598 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4599 #endif
4600 #ifdef _SC_ARG_MAX
4601 {"SC_ARG_MAX", _SC_ARG_MAX},
4602 #endif
4603 #ifdef _SC_ASYNCHRONOUS_IO
4604 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4605 #endif
4606 #ifdef _SC_ATEXIT_MAX
4607 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4608 #endif
4609 #ifdef _SC_AUDIT
4610 {"SC_AUDIT", _SC_AUDIT},
4611 #endif
4612 #ifdef _SC_AVPHYS_PAGES
4613 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4614 #endif
4615 #ifdef _SC_BC_BASE_MAX
4616 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4617 #endif
4618 #ifdef _SC_BC_DIM_MAX
4619 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4620 #endif
4621 #ifdef _SC_BC_SCALE_MAX
4622 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4623 #endif
4624 #ifdef _SC_BC_STRING_MAX
4625 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4626 #endif
4627 #ifdef _SC_CAP
4628 {"SC_CAP", _SC_CAP},
4629 #endif
4630 #ifdef _SC_CHARCLASS_NAME_MAX
4631 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4632 #endif
4633 #ifdef _SC_CHAR_BIT
4634 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4635 #endif
4636 #ifdef _SC_CHAR_MAX
4637 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4638 #endif
4639 #ifdef _SC_CHAR_MIN
4640 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4641 #endif
4642 #ifdef _SC_CHILD_MAX
4643 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4644 #endif
4645 #ifdef _SC_CLK_TCK
4646 {"SC_CLK_TCK", _SC_CLK_TCK},
4647 #endif
4648 #ifdef _SC_COHER_BLKSZ
4649 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4650 #endif
4651 #ifdef _SC_COLL_WEIGHTS_MAX
4652 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4653 #endif
4654 #ifdef _SC_DCACHE_ASSOC
4655 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4656 #endif
4657 #ifdef _SC_DCACHE_BLKSZ
4658 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4659 #endif
4660 #ifdef _SC_DCACHE_LINESZ
4661 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4662 #endif
4663 #ifdef _SC_DCACHE_SZ
4664 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4665 #endif
4666 #ifdef _SC_DCACHE_TBLKSZ
4667 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4668 #endif
4669 #ifdef _SC_DELAYTIMER_MAX
4670 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4671 #endif
4672 #ifdef _SC_EQUIV_CLASS_MAX
4673 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4674 #endif
4675 #ifdef _SC_EXPR_NEST_MAX
4676 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4677 #endif
4678 #ifdef _SC_FSYNC
4679 {"SC_FSYNC", _SC_FSYNC},
4680 #endif
4681 #ifdef _SC_GETGR_R_SIZE_MAX
4682 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4683 #endif
4684 #ifdef _SC_GETPW_R_SIZE_MAX
4685 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4686 #endif
4687 #ifdef _SC_ICACHE_ASSOC
4688 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4689 #endif
4690 #ifdef _SC_ICACHE_BLKSZ
4691 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4692 #endif
4693 #ifdef _SC_ICACHE_LINESZ
4694 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4695 #endif
4696 #ifdef _SC_ICACHE_SZ
4697 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4698 #endif
4699 #ifdef _SC_INF
4700 {"SC_INF", _SC_INF},
4701 #endif
4702 #ifdef _SC_INT_MAX
4703 {"SC_INT_MAX", _SC_INT_MAX},
4704 #endif
4705 #ifdef _SC_INT_MIN
4706 {"SC_INT_MIN", _SC_INT_MIN},
4707 #endif
4708 #ifdef _SC_IOV_MAX
4709 {"SC_IOV_MAX", _SC_IOV_MAX},
4710 #endif
4711 #ifdef _SC_IP_SECOPTS
4712 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4713 #endif
4714 #ifdef _SC_JOB_CONTROL
4715 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4716 #endif
4717 #ifdef _SC_KERN_POINTERS
4718 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4719 #endif
4720 #ifdef _SC_KERN_SIM
4721 {"SC_KERN_SIM", _SC_KERN_SIM},
4722 #endif
4723 #ifdef _SC_LINE_MAX
4724 {"SC_LINE_MAX", _SC_LINE_MAX},
4725 #endif
4726 #ifdef _SC_LOGIN_NAME_MAX
4727 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4728 #endif
4729 #ifdef _SC_LOGNAME_MAX
4730 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4731 #endif
4732 #ifdef _SC_LONG_BIT
4733 {"SC_LONG_BIT", _SC_LONG_BIT},
4734 #endif
4735 #ifdef _SC_MAC
4736 {"SC_MAC", _SC_MAC},
4737 #endif
4738 #ifdef _SC_MAPPED_FILES
4739 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4740 #endif
4741 #ifdef _SC_MAXPID
4742 {"SC_MAXPID", _SC_MAXPID},
4743 #endif
4744 #ifdef _SC_MB_LEN_MAX
4745 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4746 #endif
4747 #ifdef _SC_MEMLOCK
4748 {"SC_MEMLOCK", _SC_MEMLOCK},
4749 #endif
4750 #ifdef _SC_MEMLOCK_RANGE
4751 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4752 #endif
4753 #ifdef _SC_MEMORY_PROTECTION
4754 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4755 #endif
4756 #ifdef _SC_MESSAGE_PASSING
4757 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4758 #endif
4759 #ifdef _SC_MMAP_FIXED_ALIGNMENT
4760 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4761 #endif
4762 #ifdef _SC_MQ_OPEN_MAX
4763 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4764 #endif
4765 #ifdef _SC_MQ_PRIO_MAX
4766 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4767 #endif
4768 #ifdef _SC_NACLS_MAX
4769 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4770 #endif
4771 #ifdef _SC_NGROUPS_MAX
4772 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4773 #endif
4774 #ifdef _SC_NL_ARGMAX
4775 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4776 #endif
4777 #ifdef _SC_NL_LANGMAX
4778 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4779 #endif
4780 #ifdef _SC_NL_MSGMAX
4781 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4782 #endif
4783 #ifdef _SC_NL_NMAX
4784 {"SC_NL_NMAX", _SC_NL_NMAX},
4785 #endif
4786 #ifdef _SC_NL_SETMAX
4787 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4788 #endif
4789 #ifdef _SC_NL_TEXTMAX
4790 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4791 #endif
4792 #ifdef _SC_NPROCESSORS_CONF
4793 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4794 #endif
4795 #ifdef _SC_NPROCESSORS_ONLN
4796 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4797 #endif
4798 #ifdef _SC_NPROC_CONF
4799 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4800 #endif
4801 #ifdef _SC_NPROC_ONLN
4802 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4803 #endif
4804 #ifdef _SC_NZERO
4805 {"SC_NZERO", _SC_NZERO},
4806 #endif
4807 #ifdef _SC_OPEN_MAX
4808 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4809 #endif
4810 #ifdef _SC_PAGESIZE
4811 {"SC_PAGESIZE", _SC_PAGESIZE},
4812 #endif
4813 #ifdef _SC_PAGE_SIZE
4814 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4815 #endif
4816 #ifdef _SC_PASS_MAX
4817 {"SC_PASS_MAX", _SC_PASS_MAX},
4818 #endif
4819 #ifdef _SC_PHYS_PAGES
4820 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4821 #endif
4822 #ifdef _SC_PII
4823 {"SC_PII", _SC_PII},
4824 #endif
4825 #ifdef _SC_PII_INTERNET
4826 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4827 #endif
4828 #ifdef _SC_PII_INTERNET_DGRAM
4829 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4830 #endif
4831 #ifdef _SC_PII_INTERNET_STREAM
4832 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4833 #endif
4834 #ifdef _SC_PII_OSI
4835 {"SC_PII_OSI", _SC_PII_OSI},
4836 #endif
4837 #ifdef _SC_PII_OSI_CLTS
4838 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4839 #endif
4840 #ifdef _SC_PII_OSI_COTS
4841 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4842 #endif
4843 #ifdef _SC_PII_OSI_M
4844 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4845 #endif
4846 #ifdef _SC_PII_SOCKET
4847 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4848 #endif
4849 #ifdef _SC_PII_XTI
4850 {"SC_PII_XTI", _SC_PII_XTI},
4851 #endif
4852 #ifdef _SC_POLL
4853 {"SC_POLL", _SC_POLL},
4854 #endif
4855 #ifdef _SC_PRIORITIZED_IO
4856 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4857 #endif
4858 #ifdef _SC_PRIORITY_SCHEDULING
4859 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4860 #endif
4861 #ifdef _SC_REALTIME_SIGNALS
4862 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4863 #endif
4864 #ifdef _SC_RE_DUP_MAX
4865 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4866 #endif
4867 #ifdef _SC_RTSIG_MAX
4868 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4869 #endif
4870 #ifdef _SC_SAVED_IDS
4871 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4872 #endif
4873 #ifdef _SC_SCHAR_MAX
4874 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4875 #endif
4876 #ifdef _SC_SCHAR_MIN
4877 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4878 #endif
4879 #ifdef _SC_SELECT
4880 {"SC_SELECT", _SC_SELECT},
4881 #endif
4882 #ifdef _SC_SEMAPHORES
4883 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4884 #endif
4885 #ifdef _SC_SEM_NSEMS_MAX
4886 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4887 #endif
4888 #ifdef _SC_SEM_VALUE_MAX
4889 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4890 #endif
4891 #ifdef _SC_SHARED_MEMORY_OBJECTS
4892 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4893 #endif
4894 #ifdef _SC_SHRT_MAX
4895 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4896 #endif
4897 #ifdef _SC_SHRT_MIN
4898 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4899 #endif
4900 #ifdef _SC_SIGQUEUE_MAX
4901 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4902 #endif
4903 #ifdef _SC_SIGRT_MAX
4904 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4905 #endif
4906 #ifdef _SC_SIGRT_MIN
4907 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4908 #endif
4909 #ifdef _SC_SOFTPOWER
4910 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4911 #endif
4912 #ifdef _SC_SPLIT_CACHE
4913 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4914 #endif
4915 #ifdef _SC_SSIZE_MAX
4916 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4917 #endif
4918 #ifdef _SC_STACK_PROT
4919 {"SC_STACK_PROT", _SC_STACK_PROT},
4920 #endif
4921 #ifdef _SC_STREAM_MAX
4922 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4923 #endif
4924 #ifdef _SC_SYNCHRONIZED_IO
4925 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4926 #endif
4927 #ifdef _SC_THREADS
4928 {"SC_THREADS", _SC_THREADS},
4929 #endif
4930 #ifdef _SC_THREAD_ATTR_STACKADDR
4931 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4932 #endif
4933 #ifdef _SC_THREAD_ATTR_STACKSIZE
4934 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4935 #endif
4936 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4937 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4938 #endif
4939 #ifdef _SC_THREAD_KEYS_MAX
4940 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4941 #endif
4942 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
4943 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4944 #endif
4945 #ifdef _SC_THREAD_PRIO_INHERIT
4946 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4947 #endif
4948 #ifdef _SC_THREAD_PRIO_PROTECT
4949 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4950 #endif
4951 #ifdef _SC_THREAD_PROCESS_SHARED
4952 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4953 #endif
4954 #ifdef _SC_THREAD_SAFE_FUNCTIONS
4955 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4956 #endif
4957 #ifdef _SC_THREAD_STACK_MIN
4958 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4959 #endif
4960 #ifdef _SC_THREAD_THREADS_MAX
4961 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4962 #endif
4963 #ifdef _SC_TIMERS
4964 {"SC_TIMERS", _SC_TIMERS},
4965 #endif
4966 #ifdef _SC_TIMER_MAX
4967 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4968 #endif
4969 #ifdef _SC_TTY_NAME_MAX
4970 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4971 #endif
4972 #ifdef _SC_TZNAME_MAX
4973 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4974 #endif
4975 #ifdef _SC_T_IOV_MAX
4976 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4977 #endif
4978 #ifdef _SC_UCHAR_MAX
4979 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4980 #endif
4981 #ifdef _SC_UINT_MAX
4982 {"SC_UINT_MAX", _SC_UINT_MAX},
4983 #endif
4984 #ifdef _SC_UIO_MAXIOV
4985 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4986 #endif
4987 #ifdef _SC_ULONG_MAX
4988 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4989 #endif
4990 #ifdef _SC_USHRT_MAX
4991 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4992 #endif
4993 #ifdef _SC_VERSION
4994 {"SC_VERSION", _SC_VERSION},
4995 #endif
4996 #ifdef _SC_WORD_BIT
4997 {"SC_WORD_BIT", _SC_WORD_BIT},
4998 #endif
4999 #ifdef _SC_XBS5_ILP32_OFF32
5000 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5001 #endif
5002 #ifdef _SC_XBS5_ILP32_OFFBIG
5003 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5004 #endif
5005 #ifdef _SC_XBS5_LP64_OFF64
5006 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5007 #endif
5008 #ifdef _SC_XBS5_LPBIG_OFFBIG
5009 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5010 #endif
5011 #ifdef _SC_XOPEN_CRYPT
5012 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5013 #endif
5014 #ifdef _SC_XOPEN_ENH_I18N
5015 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5016 #endif
5017 #ifdef _SC_XOPEN_LEGACY
5018 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5019 #endif
5020 #ifdef _SC_XOPEN_REALTIME
5021 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5022 #endif
5023 #ifdef _SC_XOPEN_REALTIME_THREADS
5024 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5025 #endif
5026 #ifdef _SC_XOPEN_SHM
5027 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5028 #endif
5029 #ifdef _SC_XOPEN_UNIX
5030 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5031 #endif
5032 #ifdef _SC_XOPEN_VERSION
5033 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5034 #endif
5035 #ifdef _SC_XOPEN_XCU_VERSION
5036 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5037 #endif
5038 #ifdef _SC_XOPEN_XPG2
5039 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5040 #endif
5041 #ifdef _SC_XOPEN_XPG3
5042 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5043 #endif
5044 #ifdef _SC_XOPEN_XPG4
5045 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5046 #endif
5049 static int
5050 conv_sysconf_confname(PyObject *arg, int *valuep)
5052 return conv_confname(arg, valuep, posix_constants_sysconf,
5053 sizeof(posix_constants_sysconf)
5054 / sizeof(struct constdef));
5057 static char posix_sysconf__doc__[] = "\
5058 sysconf(name) -> integer\n\
5059 Return an integer-valued system configuration variable.";
5061 static PyObject *
5062 posix_sysconf(PyObject *self, PyObject *args)
5064 PyObject *result = NULL;
5065 int name;
5067 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5068 int value;
5070 errno = 0;
5071 value = sysconf(name);
5072 if (value == -1 && errno != 0)
5073 posix_error();
5074 else
5075 result = PyInt_FromLong(value);
5077 return result;
5079 #endif
5082 /* This code is used to ensure that the tables of configuration value names
5083 * are in sorted order as required by conv_confname(), and also to build the
5084 * the exported dictionaries that are used to publish information about the
5085 * names available on the host platform.
5087 * Sorting the table at runtime ensures that the table is properly ordered
5088 * when used, even for platforms we're not able to test on. It also makes
5089 * it easier to add additional entries to the tables.
5092 static int
5093 cmp_constdefs(const void *v1, const void *v2)
5095 const struct constdef *c1 =
5096 (const struct constdef *) v1;
5097 const struct constdef *c2 =
5098 (const struct constdef *) v2;
5100 return strcmp(c1->name, c2->name);
5103 static int
5104 setup_confname_table(struct constdef *table, size_t tablesize,
5105 char *tablename, PyObject *moddict)
5107 PyObject *d = NULL;
5108 size_t i;
5109 int status;
5111 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5112 d = PyDict_New();
5113 if (d == NULL)
5114 return -1;
5116 for (i=0; i < tablesize; ++i) {
5117 PyObject *o = PyInt_FromLong(table[i].value);
5118 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5119 Py_XDECREF(o);
5120 Py_DECREF(d);
5121 return -1;
5123 Py_DECREF(o);
5125 status = PyDict_SetItemString(moddict, tablename, d);
5126 Py_DECREF(d);
5127 return status;
5130 /* Return -1 on failure, 0 on success. */
5131 static int
5132 setup_confname_tables(PyObject *moddict)
5134 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5135 if (setup_confname_table(posix_constants_pathconf,
5136 sizeof(posix_constants_pathconf)
5137 / sizeof(struct constdef),
5138 "pathconf_names", moddict))
5139 return -1;
5140 #endif
5141 #ifdef HAVE_CONFSTR
5142 if (setup_confname_table(posix_constants_confstr,
5143 sizeof(posix_constants_confstr)
5144 / sizeof(struct constdef),
5145 "confstr_names", moddict))
5146 return -1;
5147 #endif
5148 #ifdef HAVE_SYSCONF
5149 if (setup_confname_table(posix_constants_sysconf,
5150 sizeof(posix_constants_sysconf)
5151 / sizeof(struct constdef),
5152 "sysconf_names", moddict))
5153 return -1;
5154 #endif
5155 return 0;
5159 static char posix_abort__doc__[] = "\
5160 abort() -> does not return!\n\
5161 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5162 in the hardest way possible on the hosting operating system.";
5164 static PyObject *
5165 posix_abort(PyObject *self, PyObject *args)
5167 if (!PyArg_ParseTuple(args, ":abort"))
5168 return NULL;
5169 abort();
5170 /*NOTREACHED*/
5171 Py_FatalError("abort() called from Python code didn't abort!");
5172 return NULL;
5175 #ifdef MS_WIN32
5176 static char win32_startfile__doc__[] = "\
5177 startfile(filepath) - Start a file with its associated application.\n\
5179 This acts like double-clicking the file in Explorer, or giving the file\n\
5180 name as an argument to the DOS \"start\" command: the file is opened\n\
5181 with whatever application (if any) its extension is associated.\n\
5183 startfile returns as soon as the associated application is launched.\n\
5184 There is no option to wait for the application to close, and no way\n\
5185 to retrieve the application's exit status.\n\
5187 The filepath is relative to the current directory. If you want to use\n\
5188 an absolute path, make sure the first character is not a slash (\"/\");\n\
5189 the underlying Win32 ShellExecute function doesn't work if it is.";
5191 static PyObject *
5192 win32_startfile(PyObject *self, PyObject *args)
5194 char *filepath;
5195 HINSTANCE rc;
5196 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5197 return NULL;
5198 Py_BEGIN_ALLOW_THREADS
5199 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5200 Py_END_ALLOW_THREADS
5201 if (rc <= (HINSTANCE)32)
5202 return win32_error("startfile", filepath);
5203 Py_INCREF(Py_None);
5204 return Py_None;
5206 #endif
5208 static PyMethodDef posix_methods[] = {
5209 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5210 #ifdef HAVE_TTYNAME
5211 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5212 #endif
5213 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5214 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
5215 #ifdef HAVE_CHOWN
5216 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
5217 #endif /* HAVE_CHOWN */
5218 #ifdef HAVE_CTERMID
5219 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5220 #endif
5221 #ifdef HAVE_GETCWD
5222 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
5223 #endif
5224 #ifdef HAVE_LINK
5225 {"link", posix_link, METH_VARARGS, posix_link__doc__},
5226 #endif /* HAVE_LINK */
5227 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5228 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5229 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
5230 #ifdef HAVE_NICE
5231 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
5232 #endif /* HAVE_NICE */
5233 #ifdef HAVE_READLINK
5234 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
5235 #endif /* HAVE_READLINK */
5236 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5237 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5238 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
5239 #ifdef HAVE_SYMLINK
5240 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
5241 #endif /* HAVE_SYMLINK */
5242 #ifdef HAVE_SYSTEM
5243 {"system", posix_system, METH_VARARGS, posix_system__doc__},
5244 #endif
5245 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
5246 #ifdef HAVE_UNAME
5247 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
5248 #endif /* HAVE_UNAME */
5249 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5250 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5251 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
5252 #ifdef HAVE_TIMES
5253 {"times", posix_times, METH_VARARGS, posix_times__doc__},
5254 #endif /* HAVE_TIMES */
5255 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
5256 #ifdef HAVE_EXECV
5257 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5258 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
5259 #endif /* HAVE_EXECV */
5260 #ifdef HAVE_SPAWNV
5261 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5262 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
5263 #endif /* HAVE_SPAWNV */
5264 #ifdef HAVE_FORK
5265 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
5266 #endif /* HAVE_FORK */
5267 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
5268 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
5269 #endif /* HAVE_OPENPTY || HAVE__GETPTY */
5270 #ifdef HAVE_FORKPTY
5271 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5272 #endif /* HAVE_FORKPTY */
5273 #ifdef HAVE_GETEGID
5274 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
5275 #endif /* HAVE_GETEGID */
5276 #ifdef HAVE_GETEUID
5277 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
5278 #endif /* HAVE_GETEUID */
5279 #ifdef HAVE_GETGID
5280 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
5281 #endif /* HAVE_GETGID */
5282 #ifdef HAVE_GETGROUPS
5283 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5284 #endif
5285 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
5286 #ifdef HAVE_GETPGRP
5287 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
5288 #endif /* HAVE_GETPGRP */
5289 #ifdef HAVE_GETPPID
5290 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
5291 #endif /* HAVE_GETPPID */
5292 #ifdef HAVE_GETUID
5293 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
5294 #endif /* HAVE_GETUID */
5295 #ifdef HAVE_GETLOGIN
5296 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5297 #endif
5298 #ifdef HAVE_KILL
5299 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
5300 #endif /* HAVE_KILL */
5301 #ifdef HAVE_PLOCK
5302 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
5303 #endif /* HAVE_PLOCK */
5304 #ifdef HAVE_POPEN
5305 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
5306 #ifdef MS_WIN32
5307 {"popen2", win32_popen2, METH_VARARGS},
5308 {"popen3", win32_popen3, METH_VARARGS},
5309 {"popen4", win32_popen4, METH_VARARGS},
5310 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
5311 #endif
5312 #endif /* HAVE_POPEN */
5313 #ifdef HAVE_SETUID
5314 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
5315 #endif /* HAVE_SETUID */
5316 #ifdef HAVE_SETEUID
5317 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5318 #endif /* HAVE_SETEUID */
5319 #ifdef HAVE_SETEGID
5320 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5321 #endif /* HAVE_SETEGID */
5322 #ifdef HAVE_SETREUID
5323 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5324 #endif /* HAVE_SETREUID */
5325 #ifdef HAVE_SETREGID
5326 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5327 #endif /* HAVE_SETREGID */
5328 #ifdef HAVE_SETGID
5329 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
5330 #endif /* HAVE_SETGID */
5331 #ifdef HAVE_SETPGRP
5332 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
5333 #endif /* HAVE_SETPGRP */
5334 #ifdef HAVE_WAIT
5335 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
5336 #endif /* HAVE_WAIT */
5337 #ifdef HAVE_WAITPID
5338 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
5339 #endif /* HAVE_WAITPID */
5340 #ifdef HAVE_SETSID
5341 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
5342 #endif /* HAVE_SETSID */
5343 #ifdef HAVE_SETPGID
5344 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
5345 #endif /* HAVE_SETPGID */
5346 #ifdef HAVE_TCGETPGRP
5347 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
5348 #endif /* HAVE_TCGETPGRP */
5349 #ifdef HAVE_TCSETPGRP
5350 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
5351 #endif /* HAVE_TCSETPGRP */
5352 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5353 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5354 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5355 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5356 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5357 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5358 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5359 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5360 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
5361 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
5362 #ifdef HAVE_PIPE
5363 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
5364 #endif
5365 #ifdef HAVE_MKFIFO
5366 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
5367 #endif
5368 #ifdef HAVE_FTRUNCATE
5369 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
5370 #endif
5371 #ifdef HAVE_PUTENV
5372 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
5373 #endif
5374 #ifdef HAVE_STRERROR
5375 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
5376 #endif
5377 #ifdef HAVE_FSYNC
5378 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
5379 #endif
5380 #ifdef HAVE_FDATASYNC
5381 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
5382 #endif
5383 #ifdef HAVE_SYS_WAIT_H
5384 #ifdef WIFSTOPPED
5385 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
5386 #endif /* WIFSTOPPED */
5387 #ifdef WIFSIGNALED
5388 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
5389 #endif /* WIFSIGNALED */
5390 #ifdef WIFEXITED
5391 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
5392 #endif /* WIFEXITED */
5393 #ifdef WEXITSTATUS
5394 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
5395 #endif /* WEXITSTATUS */
5396 #ifdef WTERMSIG
5397 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
5398 #endif /* WTERMSIG */
5399 #ifdef WSTOPSIG
5400 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
5401 #endif /* WSTOPSIG */
5402 #endif /* HAVE_SYS_WAIT_H */
5403 #ifdef HAVE_FSTATVFS
5404 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
5405 #endif
5406 #ifdef HAVE_STATVFS
5407 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
5408 #endif
5409 #ifdef HAVE_TMPFILE
5410 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5411 #endif
5412 #ifdef HAVE_TEMPNAM
5413 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5414 #endif
5415 #ifdef HAVE_TMPNAM
5416 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5417 #endif
5418 #ifdef HAVE_CONFSTR
5419 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5420 #endif
5421 #ifdef HAVE_SYSCONF
5422 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5423 #endif
5424 #ifdef HAVE_FPATHCONF
5425 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5426 #endif
5427 #ifdef HAVE_PATHCONF
5428 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5429 #endif
5430 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
5431 {NULL, NULL} /* Sentinel */
5435 static int
5436 ins(PyObject *d, char *symbol, long value)
5438 PyObject* v = PyInt_FromLong(value);
5439 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5440 return -1; /* triggers fatal error */
5442 Py_DECREF(v);
5443 return 0;
5446 #if defined(PYOS_OS2)
5447 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5448 static int insertvalues(PyObject *d)
5450 APIRET rc;
5451 ULONG values[QSV_MAX+1];
5452 PyObject *v;
5453 char *ver, tmp[10];
5455 Py_BEGIN_ALLOW_THREADS
5456 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5457 Py_END_ALLOW_THREADS
5459 if (rc != NO_ERROR) {
5460 os2_error(rc);
5461 return -1;
5464 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5465 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5466 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5467 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5468 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5469 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5470 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5472 switch (values[QSV_VERSION_MINOR]) {
5473 case 0: ver = "2.00"; break;
5474 case 10: ver = "2.10"; break;
5475 case 11: ver = "2.11"; break;
5476 case 30: ver = "3.00"; break;
5477 case 40: ver = "4.00"; break;
5478 case 50: ver = "5.00"; break;
5479 default:
5480 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5481 values[QSV_VERSION_MINOR]);
5482 ver = &tmp[0];
5485 /* Add Indicator of the Version of the Operating System */
5486 v = PyString_FromString(ver);
5487 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5488 return -1;
5489 Py_DECREF(v);
5491 /* Add Indicator of Which Drive was Used to Boot the System */
5492 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5493 tmp[1] = ':';
5494 tmp[2] = '\0';
5496 v = PyString_FromString(tmp);
5497 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5498 return -1;
5499 Py_DECREF(v);
5501 return 0;
5503 #endif
5505 static int
5506 all_ins(PyObject *d)
5508 #ifdef F_OK
5509 if (ins(d, "F_OK", (long)F_OK)) return -1;
5510 #endif
5511 #ifdef R_OK
5512 if (ins(d, "R_OK", (long)R_OK)) return -1;
5513 #endif
5514 #ifdef W_OK
5515 if (ins(d, "W_OK", (long)W_OK)) return -1;
5516 #endif
5517 #ifdef X_OK
5518 if (ins(d, "X_OK", (long)X_OK)) return -1;
5519 #endif
5520 #ifdef NGROUPS_MAX
5521 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5522 #endif
5523 #ifdef TMP_MAX
5524 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5525 #endif
5526 #ifdef WNOHANG
5527 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5528 #endif
5529 #ifdef O_RDONLY
5530 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5531 #endif
5532 #ifdef O_WRONLY
5533 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5534 #endif
5535 #ifdef O_RDWR
5536 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5537 #endif
5538 #ifdef O_NDELAY
5539 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5540 #endif
5541 #ifdef O_NONBLOCK
5542 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5543 #endif
5544 #ifdef O_APPEND
5545 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5546 #endif
5547 #ifdef O_DSYNC
5548 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5549 #endif
5550 #ifdef O_RSYNC
5551 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5552 #endif
5553 #ifdef O_SYNC
5554 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5555 #endif
5556 #ifdef O_NOCTTY
5557 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5558 #endif
5559 #ifdef O_CREAT
5560 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5561 #endif
5562 #ifdef O_EXCL
5563 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5564 #endif
5565 #ifdef O_TRUNC
5566 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5567 #endif
5568 #ifdef O_BINARY
5569 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5570 #endif
5571 #ifdef O_TEXT
5572 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5573 #endif
5575 #ifdef HAVE_SPAWNV
5576 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5577 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5578 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5579 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5580 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
5581 #endif
5583 #if defined(PYOS_OS2)
5584 if (insertvalues(d)) return -1;
5585 #endif
5586 return 0;
5590 #if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
5591 #define INITFUNC initnt
5592 #define MODNAME "nt"
5593 #else
5594 #if defined(PYOS_OS2)
5595 #define INITFUNC initos2
5596 #define MODNAME "os2"
5597 #else
5598 #define INITFUNC initposix
5599 #define MODNAME "posix"
5600 #endif
5601 #endif
5603 DL_EXPORT(void)
5604 INITFUNC(void)
5606 PyObject *m, *d, *v;
5608 m = Py_InitModule4(MODNAME,
5609 posix_methods,
5610 posix__doc__,
5611 (PyObject *)NULL,
5612 PYTHON_API_VERSION);
5613 d = PyModule_GetDict(m);
5615 /* Initialize environ dictionary */
5616 v = convertenviron();
5617 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
5618 return;
5619 Py_DECREF(v);
5621 if (all_ins(d))
5622 return;
5624 if (setup_confname_tables(d))
5625 return;
5627 PyDict_SetItemString(d, "error", PyExc_OSError);
5629 #ifdef HAVE_PUTENV
5630 if (posix_putenv_garbage == NULL)
5631 posix_putenv_garbage = PyDict_New();
5632 #endif