Added 'list_only' option (and modified 'run()' to respect it).
[python/dscho.git] / Modules / posixmodule.c
blob61c9a21d41b04049734ae87c4847d779bc4f55ea
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* POSIX module implementation */
34 /* This file is also used for Windows NT and MS-Win. In that case the module
35 actually calls itself 'nt', not 'posix', and a few functions are
36 either unimplemented or implemented differently. The source
37 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
38 of the compiler used. Different compilers define their own feature
39 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
41 /* See also ../Dos/dosmodule.c */
43 static char posix__doc__ [] =
44 "This module provides access to operating system functionality that is\n\
45 standardized by the C Standard and the POSIX standard (a thinly\n\
46 disguised Unix interface). Refer to the library manual and\n\
47 corresponding Unix manual entries for more information on calls.";
49 #include "Python.h"
51 #if defined(PYOS_OS2)
52 #define INCL_DOS
53 #define INCL_DOSERRORS
54 #define INCL_DOSPROCESS
55 #define INCL_NOPMAPI
56 #include <os2.h>
57 #endif
59 #include <sys/types.h>
60 #include <sys/stat.h>
61 #ifdef HAVE_SYS_WAIT_H
62 #include <sys/wait.h> /* For WNOHANG */
63 #endif
65 #ifdef HAVE_SIGNAL_H
66 #include <signal.h>
67 #endif
69 #include "mytime.h" /* For clock_t on some systems */
71 #ifdef HAVE_FCNTL_H
72 #include <fcntl.h>
73 #endif /* HAVE_FCNTL_H */
75 /* Various compilers have only certain posix functions */
76 /* XXX Gosh I wish these were all moved into config.h */
77 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
78 #include <process.h>
79 #else
80 #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
81 #define HAVE_GETCWD 1
82 #define HAVE_OPENDIR 1
83 #define HAVE_SYSTEM 1
84 #if defined(__OS2__)
85 #define HAVE_EXECV 1
86 #define HAVE_WAIT 1
87 #endif
88 #include <process.h>
89 #else
90 #ifdef __BORLANDC__ /* Borland compiler */
91 #define HAVE_EXECV 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 #else
105 #ifdef _MSC_VER /* Microsoft compiler */
106 #define HAVE_GETCWD 1
107 #ifdef MS_WIN32
108 #define HAVE_SPAWNV 1
109 #define HAVE_EXECV 1
110 #define HAVE_PIPE 1
111 #define HAVE_POPEN 1
112 #define HAVE_SYSTEM 1
113 #else /* 16-bit Windows */
114 #endif /* !MS_WIN32 */
115 #else /* all other compilers */
116 /* Unix functions that the configure script doesn't check for */
117 #define HAVE_EXECV 1
118 #define HAVE_FORK 1
119 #define HAVE_GETCWD 1
120 #define HAVE_GETEGID 1
121 #define HAVE_GETEUID 1
122 #define HAVE_GETGID 1
123 #define HAVE_GETPPID 1
124 #define HAVE_GETUID 1
125 #define HAVE_KILL 1
126 #define HAVE_OPENDIR 1
127 #define HAVE_PIPE 1
128 #define HAVE_POPEN 1
129 #define HAVE_SYSTEM 1
130 #define HAVE_WAIT 1
131 #define HAVE_TTYNAME 1
132 #endif /* _MSC_VER */
133 #endif /* __BORLANDC__ */
134 #endif /* ! __WATCOMC__ || __QNX__ */
135 #endif /* ! __IBMC__ */
137 #ifndef _MSC_VER
139 #ifdef HAVE_UNISTD_H
140 #include <unistd.h>
141 #endif
143 #ifdef NeXT
144 /* NeXT's <unistd.h> and <utime.h> aren't worth much */
145 #undef HAVE_UNISTD_H
146 #undef HAVE_UTIME_H
147 #define HAVE_WAITPID
148 /* #undef HAVE_GETCWD */
149 #define UNION_WAIT /* This should really be checked for by autoconf */
150 #endif
152 #ifdef HAVE_UNISTD_H
153 /* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
154 extern int rename();
155 extern int pclose();
156 extern int lstat();
157 extern int symlink();
158 extern int fsync();
159 #else /* !HAVE_UNISTD_H */
160 #if defined(PYCC_VACPP)
161 extern int mkdir Py_PROTO((char *));
162 #else
163 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
164 extern int mkdir Py_PROTO((const char *));
165 #else
166 extern int mkdir Py_PROTO((const char *, mode_t));
167 #endif
168 #endif
169 #if defined(__IBMC__) || defined(__IBMCPP__)
170 extern int chdir Py_PROTO((char *));
171 extern int rmdir Py_PROTO((char *));
172 #else
173 extern int chdir Py_PROTO((const char *));
174 extern int rmdir Py_PROTO((const char *));
175 #endif
176 extern int chmod Py_PROTO((const char *, mode_t));
177 extern int chown Py_PROTO((const char *, uid_t, gid_t));
178 extern char *getcwd Py_PROTO((char *, int));
179 extern char *strerror Py_PROTO((int));
180 extern int link Py_PROTO((const char *, const char *));
181 extern int rename Py_PROTO((const char *, const char *));
182 extern int stat Py_PROTO((const char *, struct stat *));
183 extern int unlink Py_PROTO((const char *));
184 extern int pclose Py_PROTO((FILE *));
185 #ifdef HAVE_SYMLINK
186 extern int symlink Py_PROTO((const char *, const char *));
187 #endif /* HAVE_SYMLINK */
188 #ifdef HAVE_LSTAT
189 extern int lstat Py_PROTO((const char *, struct stat *));
190 #endif /* HAVE_LSTAT */
191 #endif /* !HAVE_UNISTD_H */
193 #endif /* !_MSC_VER */
195 #ifdef HAVE_UTIME_H
196 #include <utime.h>
197 #endif /* HAVE_UTIME_H */
199 #ifdef HAVE_SYS_UTIME_H
200 #include <sys/utime.h>
201 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
202 #endif /* HAVE_SYS_UTIME_H */
204 #ifdef HAVE_SYS_TIMES_H
205 #include <sys/times.h>
206 #endif /* HAVE_SYS_TIMES_H */
208 #ifdef HAVE_SYS_PARAM_H
209 #include <sys/param.h>
210 #endif /* HAVE_SYS_PARAM_H */
212 #ifdef HAVE_SYS_UTSNAME_H
213 #include <sys/utsname.h>
214 #endif /* HAVE_SYS_UTSNAME_H */
216 #ifndef MAXPATHLEN
217 #define MAXPATHLEN 1024
218 #endif /* MAXPATHLEN */
220 #ifdef HAVE_DIRENT_H
221 #include <dirent.h>
222 #define NAMLEN(dirent) strlen((dirent)->d_name)
223 #else
224 #if defined(__WATCOMC__) && !defined(__QNX__)
225 #include <direct.h>
226 #define NAMLEN(dirent) strlen((dirent)->d_name)
227 #else
228 #define dirent direct
229 #define NAMLEN(dirent) (dirent)->d_namlen
230 #endif
231 #ifdef HAVE_SYS_NDIR_H
232 #include <sys/ndir.h>
233 #endif
234 #ifdef HAVE_SYS_DIR_H
235 #include <sys/dir.h>
236 #endif
237 #ifdef HAVE_NDIR_H
238 #include <ndir.h>
239 #endif
240 #endif
242 #ifdef _MSC_VER
243 #include <direct.h>
244 #include <io.h>
245 #include <process.h>
246 #include <windows.h>
247 #ifdef MS_WIN32
248 #define popen _popen
249 #define pclose _pclose
250 #else /* 16-bit Windows */
251 #include <dos.h>
252 #include <ctype.h>
253 #endif /* MS_WIN32 */
254 #endif /* _MSC_VER */
256 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
257 #include <io.h>
258 #endif /* OS2 */
260 #ifdef UNION_WAIT
261 /* Emulate some macros on systems that have a union instead of macros */
263 #ifndef WIFEXITED
264 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
265 #endif
267 #ifndef WEXITSTATUS
268 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
269 #endif
271 #ifndef WTERMSIG
272 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
273 #endif
275 #endif /* UNION_WAIT */
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()
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()
346 return PyErr_SetFromErrno(PyExc_OSError);
348 static PyObject *
349 posix_error_with_filename(name)
350 char* name;
352 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
356 #if defined(PYOS_OS2)
357 /**********************************************************************
358 * Helper Function to Trim and Format OS/2 Messages
359 **********************************************************************/
360 static void
361 os2_formatmsg(char *msgbuf, int msglen, char *reason)
363 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
365 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
366 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
368 while (lastc > msgbuf && isspace(*lastc))
369 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
372 /* Add Optional Reason Text */
373 if (reason) {
374 strcat(msgbuf, " : ");
375 strcat(msgbuf, reason);
379 /**********************************************************************
380 * Decode an OS/2 Operating System Error Code
382 * A convenience function to lookup an OS/2 error code and return a
383 * text message we can use to raise a Python exception.
385 * Notes:
386 * The messages for errors returned from the OS/2 kernel reside in
387 * the file OSO001.MSG in the \OS2 directory hierarchy.
389 **********************************************************************/
390 static char *
391 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
393 APIRET rc;
394 ULONG msglen;
396 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
397 Py_BEGIN_ALLOW_THREADS
398 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
399 errorcode, "oso001.msg", &msglen);
400 Py_END_ALLOW_THREADS
402 if (rc == NO_ERROR)
403 os2_formatmsg(msgbuf, msglen, reason);
404 else
405 sprintf(msgbuf, "unknown OS error #%d", errorcode);
407 return msgbuf;
410 /* Set an OS/2-specific error and return NULL. OS/2 kernel
411 errors are not in a global variable e.g. 'errno' nor are
412 they congruent with posix error numbers. */
414 static PyObject * os2_error(int code)
416 char text[1024];
417 PyObject *v;
419 os2_strerror(text, sizeof(text), code, "");
421 v = Py_BuildValue("(is)", code, text);
422 if (v != NULL) {
423 PyErr_SetObject(PyExc_OSError, v);
424 Py_DECREF(v);
426 return NULL; /* Signal to Python that an Exception is Pending */
429 #endif /* OS2 */
431 /* POSIX generic methods */
433 static PyObject *
434 posix_int(args, func)
435 PyObject *args;
436 int (*func) Py_FPROTO((int));
438 int fd;
439 int res;
440 if (!PyArg_Parse(args, "i", &fd))
441 return NULL;
442 Py_BEGIN_ALLOW_THREADS
443 res = (*func)(fd);
444 Py_END_ALLOW_THREADS
445 if (res < 0)
446 return posix_error();
447 Py_INCREF(Py_None);
448 return Py_None;
452 static PyObject *
453 posix_1str(args, func)
454 PyObject *args;
455 int (*func) Py_FPROTO((const char *));
457 char *path1;
458 int res;
459 if (!PyArg_Parse(args, "s", &path1))
460 return NULL;
461 Py_BEGIN_ALLOW_THREADS
462 res = (*func)(path1);
463 Py_END_ALLOW_THREADS
464 if (res < 0)
465 return posix_error_with_filename(path1);
466 Py_INCREF(Py_None);
467 return Py_None;
470 static PyObject *
471 posix_2str(args, func)
472 PyObject *args;
473 int (*func) Py_FPROTO((const char *, const char *));
475 char *path1, *path2;
476 int res;
477 if (!PyArg_Parse(args, "(ss)", &path1, &path2))
478 return NULL;
479 Py_BEGIN_ALLOW_THREADS
480 res = (*func)(path1, path2);
481 Py_END_ALLOW_THREADS
482 if (res != 0)
483 /* XXX how to report both path1 and path2??? */
484 return posix_error();
485 Py_INCREF(Py_None);
486 return Py_None;
489 static PyObject *
490 posix_strint(args, func)
491 PyObject *args;
492 int (*func) Py_FPROTO((const char *, int));
494 char *path;
495 int i;
496 int res;
497 if (!PyArg_Parse(args, "(si)", &path, &i))
498 return NULL;
499 Py_BEGIN_ALLOW_THREADS
500 res = (*func)(path, i);
501 Py_END_ALLOW_THREADS
502 if (res < 0)
503 return posix_error_with_filename(path);
504 Py_INCREF(Py_None);
505 return Py_None;
508 static PyObject *
509 posix_strintint(args, func)
510 PyObject *args;
511 int (*func) Py_FPROTO((const char *, int, int));
513 char *path;
514 int i,i2;
515 int res;
516 if (!PyArg_Parse(args, "(sii)", &path, &i, &i2))
517 return NULL;
518 Py_BEGIN_ALLOW_THREADS
519 res = (*func)(path, i, i2);
520 Py_END_ALLOW_THREADS
521 if (res < 0)
522 return posix_error_with_filename(path);
523 Py_INCREF(Py_None);
524 return Py_None;
527 static PyObject *
528 posix_do_stat(self, args, statfunc)
529 PyObject *self;
530 PyObject *args;
531 int (*statfunc) Py_FPROTO((const char *, struct stat *));
533 struct stat st;
534 char *path;
535 int res;
536 if (!PyArg_Parse(args, "s", &path))
537 return NULL;
538 Py_BEGIN_ALLOW_THREADS
539 res = (*statfunc)(path, &st);
540 Py_END_ALLOW_THREADS
541 if (res != 0)
542 return posix_error_with_filename(path);
543 #if !defined(HAVE_LARGEFILE_SUPPORT)
544 return Py_BuildValue("(llllllllll)",
545 (long)st.st_mode,
546 (long)st.st_ino,
547 (long)st.st_dev,
548 (long)st.st_nlink,
549 (long)st.st_uid,
550 (long)st.st_gid,
551 (long)st.st_size,
552 (long)st.st_atime,
553 (long)st.st_mtime,
554 (long)st.st_ctime);
555 #else
556 return Py_BuildValue("(lLllllLlll)",
557 (long)st.st_mode,
558 (LONG_LONG)st.st_ino,
559 (long)st.st_dev,
560 (long)st.st_nlink,
561 (long)st.st_uid,
562 (long)st.st_gid,
563 (LONG_LONG)st.st_size,
564 (long)st.st_atime,
565 (long)st.st_mtime,
566 (long)st.st_ctime);
567 #endif
571 /* POSIX methods */
573 static char posix_access__doc__[] =
574 "access(path, mode) -> 1 if granted, 0 otherwise\n\
575 Test for access to a file.";
577 static PyObject *
578 posix_access(self, args)
579 PyObject *self;
580 PyObject *args;
582 char *path;
583 int mode;
584 int res;
586 if (!PyArg_Parse(args, "(si)", &path, &mode))
587 return NULL;
588 Py_BEGIN_ALLOW_THREADS
589 res = access(path, mode);
590 Py_END_ALLOW_THREADS
591 return(PyInt_FromLong(res == 0 ? 1L : 0L));
594 #ifndef F_OK
595 #define F_OK 0
596 #endif
597 #ifndef R_OK
598 #define R_OK 4
599 #endif
600 #ifndef W_OK
601 #define W_OK 2
602 #endif
603 #ifndef X_OK
604 #define X_OK 1
605 #endif
607 #ifdef HAVE_TTYNAME
608 static char posix_ttyname__doc__[] =
609 "ttyname(fd) -> String\n\
610 Return the name of the terminal device connected to 'fd'.";
612 static PyObject *
613 posix_ttyname(self, args)
614 PyObject *self;
615 PyObject *args;
617 PyObject *file;
618 int id;
619 char *ret;
621 if (!PyArg_Parse(args, "i", &id))
622 return NULL;
624 ret = ttyname(id);
625 if (ret == NULL)
626 return(posix_error());
627 return(PyString_FromString(ret));
629 #endif
631 static char posix_chdir__doc__[] =
632 "chdir(path) -> None\n\
633 Change the current working directory to the specified path.";
635 static PyObject *
636 posix_chdir(self, args)
637 PyObject *self;
638 PyObject *args;
640 return posix_1str(args, chdir);
644 static char posix_chmod__doc__[] =
645 "chmod(path, mode) -> None\n\
646 Change the access permissions of a file.";
648 static PyObject *
649 posix_chmod(self, args)
650 PyObject *self;
651 PyObject *args;
653 return posix_strint(args, chmod);
657 #ifdef HAVE_FSYNC
658 static char posix_fsync__doc__[] =
659 "fsync(fildes) -> None\n\
660 force write of file with filedescriptor to disk.";
662 static PyObject *
663 posix_fsync(self, args)
664 PyObject *self;
665 PyObject *args;
667 return posix_int(args, fsync);
669 #endif /* HAVE_FSYNC */
671 #ifdef HAVE_FDATASYNC
672 static char posix_fdatasync__doc__[] =
673 "fdatasync(fildes) -> None\n\
674 force write of file with filedescriptor to disk.\n\
675 does not force update of metadata.";
677 extern int fdatasync(int); /* Prototype just in case */
679 static PyObject *
680 posix_fdatasync(self, args)
681 PyObject *self;
682 PyObject *args;
684 return posix_int(args, fdatasync);
686 #endif /* HAVE_FDATASYNC */
689 #ifdef HAVE_CHOWN
690 static char posix_chown__doc__[] =
691 "chown(path, uid, gid) -> None\n\
692 Change the owner and group id of path to the numeric uid and gid.";
694 static PyObject *
695 posix_chown(self, args)
696 PyObject *self;
697 PyObject *args;
699 return posix_strintint(args, chown);
701 #endif /* HAVE_CHOWN */
704 #ifdef HAVE_GETCWD
705 static char posix_getcwd__doc__[] =
706 "getcwd() -> path\n\
707 Return a string representing the current working directory.";
709 static PyObject *
710 posix_getcwd(self, args)
711 PyObject *self;
712 PyObject *args;
714 char buf[1026];
715 char *res;
716 if (!PyArg_NoArgs(args))
717 return NULL;
718 Py_BEGIN_ALLOW_THREADS
719 res = getcwd(buf, sizeof buf);
720 Py_END_ALLOW_THREADS
721 if (res == NULL)
722 return posix_error();
723 return PyString_FromString(buf);
725 #endif
728 #ifdef HAVE_LINK
729 static char posix_link__doc__[] =
730 "link(src, dst) -> None\n\
731 Create a hard link to a file.";
733 static PyObject *
734 posix_link(self, args)
735 PyObject *self;
736 PyObject *args;
738 return posix_2str(args, link);
740 #endif /* HAVE_LINK */
743 static char posix_listdir__doc__[] =
744 "listdir(path) -> list_of_strings\n\
745 Return a list containing the names of the entries in the directory.\n\
747 path: path of directory to list\n\
749 The list is in arbitrary order. It does not include the special\n\
750 entries '.' and '..' even if they are present in the directory.";
752 static PyObject *
753 posix_listdir(self, args)
754 PyObject *self;
755 PyObject *args;
757 /* XXX Should redo this putting the (now four) versions of opendir
758 in separate files instead of having them all here... */
759 #if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
761 char *name;
762 int len;
763 PyObject *d, *v;
764 HANDLE hFindFile;
765 WIN32_FIND_DATA FileData;
766 char namebuf[MAX_PATH+5];
768 if (!PyArg_Parse(args, "t#", &name, &len))
769 return NULL;
770 if (len >= MAX_PATH) {
771 PyErr_SetString(PyExc_ValueError, "path too long");
772 return NULL;
774 strcpy(namebuf, name);
775 if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
776 namebuf[len++] = '/';
777 strcpy(namebuf + len, "*.*");
779 if ((d = PyList_New(0)) == NULL)
780 return NULL;
782 hFindFile = FindFirstFile(namebuf, &FileData);
783 if (hFindFile == INVALID_HANDLE_VALUE) {
784 errno = GetLastError();
785 if (errno == ERROR_FILE_NOT_FOUND)
786 return PyList_New(0);
787 return posix_error_with_filename(name);
789 do {
790 if (FileData.cFileName[0] == '.' &&
791 (FileData.cFileName[1] == '\0' ||
792 FileData.cFileName[1] == '.' &&
793 FileData.cFileName[2] == '\0'))
794 continue;
795 v = PyString_FromString(FileData.cFileName);
796 if (v == NULL) {
797 Py_DECREF(d);
798 d = NULL;
799 break;
801 if (PyList_Append(d, v) != 0) {
802 Py_DECREF(v);
803 Py_DECREF(d);
804 d = NULL;
805 break;
807 Py_DECREF(v);
808 } while (FindNextFile(hFindFile, &FileData) == TRUE);
810 if (FindClose(hFindFile) == FALSE) {
811 errno = GetLastError();
812 return posix_error_with_filename(&name);
815 return d;
817 #else /* !MS_WIN32 */
818 #ifdef _MSC_VER /* 16-bit Windows */
820 #ifndef MAX_PATH
821 #define MAX_PATH 250
822 #endif
823 char *name, *pt;
824 int len;
825 PyObject *d, *v;
826 char namebuf[MAX_PATH+5];
827 struct _find_t ep;
829 if (!PyArg_Parse(args, "t#", &name, &len))
830 return NULL;
831 if (len >= MAX_PATH) {
832 PyErr_SetString(PyExc_ValueError, "path too long");
833 return NULL;
835 strcpy(namebuf, name);
836 for (pt = namebuf; *pt; pt++)
837 if (*pt == '/')
838 *pt = '\\';
839 if (namebuf[len-1] != '\\')
840 namebuf[len++] = '\\';
841 strcpy(namebuf + len, "*.*");
843 if ((d = PyList_New(0)) == NULL)
844 return NULL;
846 if (_dos_findfirst(namebuf, _A_RDONLY |
847 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
849 errno = ENOENT;
850 return posix_error_with_filename(name);
852 do {
853 if (ep.name[0] == '.' &&
854 (ep.name[1] == '\0' ||
855 ep.name[1] == '.' &&
856 ep.name[2] == '\0'))
857 continue;
858 strcpy(namebuf, ep.name);
859 for (pt = namebuf; *pt; pt++)
860 if (isupper(*pt))
861 *pt = tolower(*pt);
862 v = PyString_FromString(namebuf);
863 if (v == NULL) {
864 Py_DECREF(d);
865 d = NULL;
866 break;
868 if (PyList_Append(d, v) != 0) {
869 Py_DECREF(v);
870 Py_DECREF(d);
871 d = NULL;
872 break;
874 Py_DECREF(v);
875 } while (_dos_findnext(&ep) == 0);
877 return d;
879 #else
880 #if defined(PYOS_OS2)
882 #ifndef MAX_PATH
883 #define MAX_PATH CCHMAXPATH
884 #endif
885 char *name, *pt;
886 int len;
887 PyObject *d, *v;
888 char namebuf[MAX_PATH+5];
889 HDIR hdir = 1;
890 ULONG srchcnt = 1;
891 FILEFINDBUF3 ep;
892 APIRET rc;
894 if (!PyArg_Parse(args, "t#", &name, &len))
895 return NULL;
896 if (len >= MAX_PATH) {
897 PyErr_SetString(PyExc_ValueError, "path too long");
898 return NULL;
900 strcpy(namebuf, name);
901 for (pt = namebuf; *pt; pt++)
902 if (*pt == '/')
903 *pt = '\\';
904 if (namebuf[len-1] != '\\')
905 namebuf[len++] = '\\';
906 strcpy(namebuf + len, "*.*");
908 if ((d = PyList_New(0)) == NULL)
909 return NULL;
911 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
912 &hdir, /* Handle to Use While Search Directory */
913 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
914 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
915 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
916 FIL_STANDARD); /* Format of Entry (EAs or Not) */
918 if (rc != NO_ERROR) {
919 errno = ENOENT;
920 return posix_error_with_filename(name);
923 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
924 do {
925 if (ep.achName[0] == '.'
926 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
927 continue; /* Skip Over "." and ".." Names */
929 strcpy(namebuf, ep.achName);
931 /* Leave Case of Name Alone -- In Native Form */
932 /* (Removed Forced Lowercasing Code) */
934 v = PyString_FromString(namebuf);
935 if (v == NULL) {
936 Py_DECREF(d);
937 d = NULL;
938 break;
940 if (PyList_Append(d, v) != 0) {
941 Py_DECREF(v);
942 Py_DECREF(d);
943 d = NULL;
944 break;
946 Py_DECREF(v);
947 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
950 return d;
951 #else
953 char *name;
954 PyObject *d, *v;
955 DIR *dirp;
956 struct dirent *ep;
957 if (!PyArg_Parse(args, "s", &name))
958 return NULL;
959 Py_BEGIN_ALLOW_THREADS
960 if ((dirp = opendir(name)) == NULL) {
961 Py_BLOCK_THREADS
962 return posix_error_with_filename(name);
964 if ((d = PyList_New(0)) == NULL) {
965 closedir(dirp);
966 Py_BLOCK_THREADS
967 return NULL;
969 while ((ep = readdir(dirp)) != NULL) {
970 if (ep->d_name[0] == '.' &&
971 (NAMLEN(ep) == 1 ||
972 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
973 continue;
974 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
975 if (v == NULL) {
976 Py_DECREF(d);
977 d = NULL;
978 break;
980 if (PyList_Append(d, v) != 0) {
981 Py_DECREF(v);
982 Py_DECREF(d);
983 d = NULL;
984 break;
986 Py_DECREF(v);
988 closedir(dirp);
989 Py_END_ALLOW_THREADS
991 return d;
993 #endif /* !PYOS_OS2 */
994 #endif /* !_MSC_VER */
995 #endif /* !MS_WIN32 */
998 static char posix_mkdir__doc__[] =
999 "mkdir(path [, mode=0777]) -> None\n\
1000 Create a directory.";
1002 static PyObject *
1003 posix_mkdir(self, args)
1004 PyObject *self;
1005 PyObject *args;
1007 int res;
1008 char *path;
1009 int mode = 0777;
1010 if (!PyArg_ParseTuple(args, "s|i", &path, &mode))
1011 return NULL;
1012 Py_BEGIN_ALLOW_THREADS
1013 #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1014 res = mkdir(path);
1015 #else
1016 res = mkdir(path, mode);
1017 #endif
1018 Py_END_ALLOW_THREADS
1019 if (res < 0)
1020 return posix_error_with_filename(path);
1021 Py_INCREF(Py_None);
1022 return Py_None;
1026 #ifdef HAVE_NICE
1027 static char posix_nice__doc__[] =
1028 "nice(inc) -> new_priority\n\
1029 Decrease the priority of process and return new priority.";
1031 static PyObject *
1032 posix_nice(self, args)
1033 PyObject *self;
1034 PyObject *args;
1036 int increment, value;
1038 if (!PyArg_Parse(args, "i", &increment))
1039 return NULL;
1040 value = nice(increment);
1041 if (value == -1)
1042 return posix_error();
1043 return PyInt_FromLong((long) value);
1045 #endif /* HAVE_NICE */
1048 static char posix_rename__doc__[] =
1049 "rename(old, new) -> None\n\
1050 Rename a file or directory.";
1052 static PyObject *
1053 posix_rename(self, args)
1054 PyObject *self;
1055 PyObject *args;
1057 return posix_2str(args, rename);
1061 static char posix_rmdir__doc__[] =
1062 "rmdir(path) -> None\n\
1063 Remove a directory.";
1065 static PyObject *
1066 posix_rmdir(self, args)
1067 PyObject *self;
1068 PyObject *args;
1070 return posix_1str(args, rmdir);
1074 static char posix_stat__doc__[] =
1075 "stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1076 Perform a stat system call on the given path.";
1078 static PyObject *
1079 posix_stat(self, args)
1080 PyObject *self;
1081 PyObject *args;
1083 return posix_do_stat(self, args, stat);
1087 #ifdef HAVE_SYSTEM
1088 static char posix_system__doc__[] =
1089 "system(command) -> exit_status\n\
1090 Execute the command (a string) in a subshell.";
1092 static PyObject *
1093 posix_system(self, args)
1094 PyObject *self;
1095 PyObject *args;
1097 char *command;
1098 long sts;
1099 if (!PyArg_Parse(args, "s", &command))
1100 return NULL;
1101 Py_BEGIN_ALLOW_THREADS
1102 sts = system(command);
1103 Py_END_ALLOW_THREADS
1104 return PyInt_FromLong(sts);
1106 #endif
1109 static char posix_umask__doc__[] =
1110 "umask(new_mask) -> old_mask\n\
1111 Set the current numeric umask and return the previous umask.";
1113 static PyObject *
1114 posix_umask(self, args)
1115 PyObject *self;
1116 PyObject *args;
1118 int i;
1119 if (!PyArg_Parse(args, "i", &i))
1120 return NULL;
1121 i = umask(i);
1122 if (i < 0)
1123 return posix_error();
1124 return PyInt_FromLong((long)i);
1128 static char posix_unlink__doc__[] =
1129 "unlink(path) -> None\n\
1130 Remove a file (same as remove(path)).";
1132 static char posix_remove__doc__[] =
1133 "remove(path) -> None\n\
1134 Remove a file (same as unlink(path)).";
1136 static PyObject *
1137 posix_unlink(self, args)
1138 PyObject *self;
1139 PyObject *args;
1141 return posix_1str(args, unlink);
1145 #ifdef HAVE_UNAME
1146 static char posix_uname__doc__[] =
1147 "uname() -> (sysname, nodename, release, version, machine)\n\
1148 Return a tuple identifying the current operating system.";
1150 static PyObject *
1151 posix_uname(self, args)
1152 PyObject *self;
1153 PyObject *args;
1155 struct utsname u;
1156 int res;
1157 if (!PyArg_NoArgs(args))
1158 return NULL;
1159 Py_BEGIN_ALLOW_THREADS
1160 res = uname(&u);
1161 Py_END_ALLOW_THREADS
1162 if (res < 0)
1163 return posix_error();
1164 return Py_BuildValue("(sssss)",
1165 u.sysname,
1166 u.nodename,
1167 u.release,
1168 u.version,
1169 u.machine);
1171 #endif /* HAVE_UNAME */
1174 static char posix_utime__doc__[] =
1175 "utime(path, (atime, utime)) -> None\n\
1176 Set the access and modified time of the file to the given values.";
1178 static PyObject *
1179 posix_utime(self, args)
1180 PyObject *self;
1181 PyObject *args;
1183 char *path;
1184 long atime, mtime;
1185 int res;
1187 /* XXX should define struct utimbuf instead, above */
1188 #ifdef HAVE_UTIME_H
1189 struct utimbuf buf;
1190 #define ATIME buf.actime
1191 #define MTIME buf.modtime
1192 #define UTIME_ARG &buf
1193 #else /* HAVE_UTIME_H */
1194 time_t buf[2];
1195 #define ATIME buf[0]
1196 #define MTIME buf[1]
1197 #define UTIME_ARG buf
1198 #endif /* HAVE_UTIME_H */
1200 if (!PyArg_Parse(args, "(s(ll))", &path, &atime, &mtime))
1201 return NULL;
1202 ATIME = atime;
1203 MTIME = mtime;
1204 Py_BEGIN_ALLOW_THREADS
1205 res = utime(path, UTIME_ARG);
1206 Py_END_ALLOW_THREADS
1207 if (res < 0)
1208 return posix_error_with_filename(path);
1209 Py_INCREF(Py_None);
1210 return Py_None;
1211 #undef UTIME_ARG
1212 #undef ATIME
1213 #undef MTIME
1217 /* Process operations */
1219 static char posix__exit__doc__[] =
1220 "_exit(status)\n\
1221 Exit to the system with specified status, without normal exit processing.";
1223 static PyObject *
1224 posix__exit(self, args)
1225 PyObject *self;
1226 PyObject *args;
1228 int sts;
1229 if (!PyArg_Parse(args, "i", &sts))
1230 return NULL;
1231 _exit(sts);
1232 return NULL; /* Make gcc -Wall happy */
1236 #ifdef HAVE_EXECV
1237 static char posix_execv__doc__[] =
1238 "execv(path, args)\n\
1239 Execute an executable path with arguments, replacing current process.\n\
1241 path: path of executable file\n\
1242 args: tuple or list of strings";
1244 static PyObject *
1245 posix_execv(self, args)
1246 PyObject *self;
1247 PyObject *args;
1249 char *path;
1250 PyObject *argv;
1251 char **argvlist;
1252 int i, argc;
1253 PyObject *(*getitem) Py_PROTO((PyObject *, int));
1255 /* execv has two arguments: (path, argv), where
1256 argv is a list or tuple of strings. */
1258 if (!PyArg_Parse(args, "(sO)", &path, &argv))
1259 return NULL;
1260 if (PyList_Check(argv)) {
1261 argc = PyList_Size(argv);
1262 getitem = PyList_GetItem;
1264 else if (PyTuple_Check(argv)) {
1265 argc = PyTuple_Size(argv);
1266 getitem = PyTuple_GetItem;
1268 else {
1269 badarg:
1270 PyErr_BadArgument();
1271 return NULL;
1274 argvlist = PyMem_NEW(char *, argc+1);
1275 if (argvlist == NULL)
1276 return NULL;
1277 for (i = 0; i < argc; i++) {
1278 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1279 PyMem_DEL(argvlist);
1280 goto badarg;
1283 argvlist[argc] = NULL;
1285 #ifdef BAD_EXEC_PROTOTYPES
1286 execv(path, (const char **) argvlist);
1287 #else /* BAD_EXEC_PROTOTYPES */
1288 execv(path, argvlist);
1289 #endif /* BAD_EXEC_PROTOTYPES */
1291 /* If we get here it's definitely an error */
1293 PyMem_DEL(argvlist);
1294 return posix_error();
1298 static char posix_execve__doc__[] =
1299 "execve(path, args, env)\n\
1300 Execute a path with arguments and environment, replacing current process.\n\
1302 path: path of executable file\n\
1303 args: tuple or list of arguments\n\
1304 env: dictonary of strings mapping to strings";
1306 static PyObject *
1307 posix_execve(self, args)
1308 PyObject *self;
1309 PyObject *args;
1311 char *path;
1312 PyObject *argv, *env;
1313 char **argvlist;
1314 char **envlist;
1315 PyObject *key, *val, *keys=NULL, *vals=NULL;
1316 int i, pos, argc, envc;
1317 PyObject *(*getitem) Py_PROTO((PyObject *, int));
1319 /* execve has three arguments: (path, argv, env), where
1320 argv is a list or tuple of strings and env is a dictionary
1321 like posix.environ. */
1323 if (!PyArg_Parse(args, "(sOO)", &path, &argv, &env))
1324 return NULL;
1325 if (PyList_Check(argv)) {
1326 argc = PyList_Size(argv);
1327 getitem = PyList_GetItem;
1329 else if (PyTuple_Check(argv)) {
1330 argc = PyTuple_Size(argv);
1331 getitem = PyTuple_GetItem;
1333 else {
1334 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1335 return NULL;
1337 if (!PyMapping_Check(env)) {
1338 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1339 return NULL;
1342 argvlist = PyMem_NEW(char *, argc+1);
1343 if (argvlist == NULL) {
1344 PyErr_NoMemory();
1345 return NULL;
1347 for (i = 0; i < argc; i++) {
1348 if (!PyArg_Parse((*getitem)(argv, i),
1349 "s;argv must be list of strings",
1350 &argvlist[i]))
1352 goto fail_1;
1355 argvlist[argc] = NULL;
1357 i = PyMapping_Length(env);
1358 envlist = PyMem_NEW(char *, i + 1);
1359 if (envlist == NULL) {
1360 PyErr_NoMemory();
1361 goto fail_1;
1363 envc = 0;
1364 keys = PyMapping_Keys(env);
1365 vals = PyMapping_Values(env);
1366 if (!keys || !vals)
1367 goto fail_2;
1369 for (pos = 0; pos < i; pos++) {
1370 char *p, *k, *v;
1372 key = PyList_GetItem(keys, pos);
1373 val = PyList_GetItem(vals, pos);
1374 if (!key || !val)
1375 goto fail_2;
1377 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1378 !PyArg_Parse(val, "s;non-string value in env", &v))
1380 goto fail_2;
1383 #if defined(PYOS_OS2)
1384 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1385 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1386 #endif
1387 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1388 if (p == NULL) {
1389 PyErr_NoMemory();
1390 goto fail_2;
1392 sprintf(p, "%s=%s", k, v);
1393 envlist[envc++] = p;
1394 #if defined(PYOS_OS2)
1396 #endif
1398 envlist[envc] = 0;
1401 #ifdef BAD_EXEC_PROTOTYPES
1402 execve(path, (const char **)argvlist, envlist);
1403 #else /* BAD_EXEC_PROTOTYPES */
1404 execve(path, argvlist, envlist);
1405 #endif /* BAD_EXEC_PROTOTYPES */
1407 /* If we get here it's definitely an error */
1409 (void) posix_error();
1411 fail_2:
1412 while (--envc >= 0)
1413 PyMem_DEL(envlist[envc]);
1414 PyMem_DEL(envlist);
1415 fail_1:
1416 PyMem_DEL(argvlist);
1417 Py_XDECREF(vals);
1418 Py_XDECREF(keys);
1419 return NULL;
1421 #endif /* HAVE_EXECV */
1424 #ifdef HAVE_SPAWNV
1425 static char posix_spawnv__doc__[] =
1426 "spawnv(mode, path, args)\n\
1427 Execute an executable path with arguments, replacing current process.\n\
1429 mode: mode of process creation\n\
1430 path: path of executable file\n\
1431 args: tuple or list of strings";
1433 static PyObject *
1434 posix_spawnv(self, args)
1435 PyObject *self;
1436 PyObject *args;
1438 char *path;
1439 PyObject *argv;
1440 char **argvlist;
1441 int mode, i, argc;
1442 PyObject *(*getitem) Py_PROTO((PyObject *, int));
1444 /* spawnv has three arguments: (mode, path, argv), where
1445 argv is a list or tuple of strings. */
1447 if (!PyArg_Parse(args, "(isO)", &mode, &path, &argv))
1448 return NULL;
1449 if (PyList_Check(argv)) {
1450 argc = PyList_Size(argv);
1451 getitem = PyList_GetItem;
1453 else if (PyTuple_Check(argv)) {
1454 argc = PyTuple_Size(argv);
1455 getitem = PyTuple_GetItem;
1457 else {
1458 badarg:
1459 PyErr_BadArgument();
1460 return NULL;
1463 argvlist = PyMem_NEW(char *, argc+1);
1464 if (argvlist == NULL)
1465 return NULL;
1466 for (i = 0; i < argc; i++) {
1467 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1468 PyMem_DEL(argvlist);
1469 goto badarg;
1472 argvlist[argc] = NULL;
1474 if (mode == _OLD_P_OVERLAY)
1475 mode = _P_OVERLAY;
1476 i = _spawnv(mode, path, argvlist);
1478 PyMem_DEL(argvlist);
1480 if (i == -1)
1481 return posix_error();
1482 else
1483 return Py_BuildValue("i", i);
1487 static char posix_spawnve__doc__[] =
1488 "spawnve(mode, path, args, env)\n\
1489 Execute a path with arguments and environment, replacing current process.\n\
1491 mode: mode of process creation\n\
1492 path: path of executable file\n\
1493 args: tuple or list of arguments\n\
1494 env: dictonary of strings mapping to strings";
1496 static PyObject *
1497 posix_spawnve(self, args)
1498 PyObject *self;
1499 PyObject *args;
1501 char *path;
1502 PyObject *argv, *env;
1503 char **argvlist;
1504 char **envlist;
1505 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1506 int mode, i, pos, argc, envc;
1507 PyObject *(*getitem) Py_PROTO((PyObject *, int));
1509 /* spawnve has four arguments: (mode, path, argv, env), where
1510 argv is a list or tuple of strings and env is a dictionary
1511 like posix.environ. */
1513 if (!PyArg_Parse(args, "(isOO)", &mode, &path, &argv, &env))
1514 return NULL;
1515 if (PyList_Check(argv)) {
1516 argc = PyList_Size(argv);
1517 getitem = PyList_GetItem;
1519 else if (PyTuple_Check(argv)) {
1520 argc = PyTuple_Size(argv);
1521 getitem = PyTuple_GetItem;
1523 else {
1524 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1525 return NULL;
1527 if (!PyMapping_Check(env)) {
1528 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1529 return NULL;
1532 argvlist = PyMem_NEW(char *, argc+1);
1533 if (argvlist == NULL) {
1534 PyErr_NoMemory();
1535 return NULL;
1537 for (i = 0; i < argc; i++) {
1538 if (!PyArg_Parse((*getitem)(argv, i),
1539 "s;argv must be list of strings",
1540 &argvlist[i]))
1542 goto fail_1;
1545 argvlist[argc] = NULL;
1547 i = PyMapping_Length(env);
1548 envlist = PyMem_NEW(char *, i + 1);
1549 if (envlist == NULL) {
1550 PyErr_NoMemory();
1551 goto fail_1;
1553 envc = 0;
1554 keys = PyMapping_Keys(env);
1555 vals = PyMapping_Values(env);
1556 if (!keys || !vals)
1557 goto fail_2;
1559 for (pos = 0; pos < i; pos++) {
1560 char *p, *k, *v;
1562 key = PyList_GetItem(keys, pos);
1563 val = PyList_GetItem(vals, pos);
1564 if (!key || !val)
1565 goto fail_2;
1567 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1568 !PyArg_Parse(val, "s;non-string value in env", &v))
1570 goto fail_2;
1572 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1573 if (p == NULL) {
1574 PyErr_NoMemory();
1575 goto fail_2;
1577 sprintf(p, "%s=%s", k, v);
1578 envlist[envc++] = p;
1580 envlist[envc] = 0;
1582 if (mode == _OLD_P_OVERLAY)
1583 mode = _P_OVERLAY;
1584 i = _spawnve(mode, path, argvlist, envlist);
1585 if (i == -1)
1586 (void) posix_error();
1587 else
1588 res = Py_BuildValue("i", i);
1590 fail_2:
1591 while (--envc >= 0)
1592 PyMem_DEL(envlist[envc]);
1593 PyMem_DEL(envlist);
1594 fail_1:
1595 PyMem_DEL(argvlist);
1596 Py_XDECREF(vals);
1597 Py_XDECREF(keys);
1598 return res;
1600 #endif /* HAVE_SPAWNV */
1603 #ifdef HAVE_FORK
1604 static char posix_fork__doc__[] =
1605 "fork() -> pid\n\
1606 Fork a child process.\n\
1608 Return 0 to child process and PID of child to parent process.";
1610 static PyObject *
1611 posix_fork(self, args)
1612 PyObject *self;
1613 PyObject *args;
1615 int pid;
1616 if (!PyArg_NoArgs(args))
1617 return NULL;
1618 pid = fork();
1619 if (pid == -1)
1620 return posix_error();
1621 PyOS_AfterFork();
1622 return PyInt_FromLong((long)pid);
1624 #endif
1627 #ifdef HAVE_GETEGID
1628 static char posix_getegid__doc__[] =
1629 "getegid() -> egid\n\
1630 Return the current process's effective group id.";
1632 static PyObject *
1633 posix_getegid(self, args)
1634 PyObject *self;
1635 PyObject *args;
1637 if (!PyArg_NoArgs(args))
1638 return NULL;
1639 return PyInt_FromLong((long)getegid());
1641 #endif
1644 #ifdef HAVE_GETEUID
1645 static char posix_geteuid__doc__[] =
1646 "geteuid() -> euid\n\
1647 Return the current process's effective user id.";
1649 static PyObject *
1650 posix_geteuid(self, args)
1651 PyObject *self;
1652 PyObject *args;
1654 if (!PyArg_NoArgs(args))
1655 return NULL;
1656 return PyInt_FromLong((long)geteuid());
1658 #endif
1661 #ifdef HAVE_GETGID
1662 static char posix_getgid__doc__[] =
1663 "getgid() -> gid\n\
1664 Return the current process's group id.";
1666 static PyObject *
1667 posix_getgid(self, args)
1668 PyObject *self;
1669 PyObject *args;
1671 if (!PyArg_NoArgs(args))
1672 return NULL;
1673 return PyInt_FromLong((long)getgid());
1675 #endif
1678 static char posix_getpid__doc__[] =
1679 "getpid() -> pid\n\
1680 Return the current process id";
1682 static PyObject *
1683 posix_getpid(self, args)
1684 PyObject *self;
1685 PyObject *args;
1687 if (!PyArg_NoArgs(args))
1688 return NULL;
1689 return PyInt_FromLong((long)getpid());
1693 #ifdef HAVE_GETPGRP
1694 static char posix_getpgrp__doc__[] =
1695 "getpgrp() -> pgrp\n\
1696 Return the current process group id.";
1698 static PyObject *
1699 posix_getpgrp(self, args)
1700 PyObject *self;
1701 PyObject *args;
1703 if (!PyArg_NoArgs(args))
1704 return NULL;
1705 #ifdef GETPGRP_HAVE_ARG
1706 return PyInt_FromLong((long)getpgrp(0));
1707 #else /* GETPGRP_HAVE_ARG */
1708 return PyInt_FromLong((long)getpgrp());
1709 #endif /* GETPGRP_HAVE_ARG */
1711 #endif /* HAVE_GETPGRP */
1714 #ifdef HAVE_SETPGRP
1715 static char posix_setpgrp__doc__[] =
1716 "setpgrp() -> None\n\
1717 Make this process a session leader.";
1719 static PyObject *
1720 posix_setpgrp(self, args)
1721 PyObject *self;
1722 PyObject *args;
1724 if (!PyArg_NoArgs(args))
1725 return NULL;
1726 #ifdef SETPGRP_HAVE_ARG
1727 if (setpgrp(0, 0) < 0)
1728 #else /* SETPGRP_HAVE_ARG */
1729 if (setpgrp() < 0)
1730 #endif /* SETPGRP_HAVE_ARG */
1731 return posix_error();
1732 Py_INCREF(Py_None);
1733 return Py_None;
1736 #endif /* HAVE_SETPGRP */
1738 #ifdef HAVE_GETPPID
1739 static char posix_getppid__doc__[] =
1740 "getppid() -> ppid\n\
1741 Return the parent's process id.";
1743 static PyObject *
1744 posix_getppid(self, args)
1745 PyObject *self;
1746 PyObject *args;
1748 if (!PyArg_NoArgs(args))
1749 return NULL;
1750 return PyInt_FromLong((long)getppid());
1752 #endif
1755 #ifdef HAVE_GETUID
1756 static char posix_getuid__doc__[] =
1757 "getuid() -> uid\n\
1758 Return the current process's user id.";
1760 static PyObject *
1761 posix_getuid(self, args)
1762 PyObject *self;
1763 PyObject *args;
1765 if (!PyArg_NoArgs(args))
1766 return NULL;
1767 return PyInt_FromLong((long)getuid());
1769 #endif
1772 #ifdef HAVE_KILL
1773 static char posix_kill__doc__[] =
1774 "kill(pid, sig) -> None\n\
1775 Kill a process with a signal.";
1777 static PyObject *
1778 posix_kill(self, args)
1779 PyObject *self;
1780 PyObject *args;
1782 int pid, sig;
1783 if (!PyArg_Parse(args, "(ii)", &pid, &sig))
1784 return NULL;
1785 #if defined(PYOS_OS2)
1786 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1787 APIRET rc;
1788 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
1789 return os2_error(rc);
1791 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1792 APIRET rc;
1793 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
1794 return os2_error(rc);
1796 } else
1797 return NULL; /* Unrecognized Signal Requested */
1798 #else
1799 if (kill(pid, sig) == -1)
1800 return posix_error();
1801 #endif
1802 Py_INCREF(Py_None);
1803 return Py_None;
1805 #endif
1807 #ifdef HAVE_PLOCK
1809 #ifdef HAVE_SYS_LOCK_H
1810 #include <sys/lock.h>
1811 #endif
1813 static char posix_plock__doc__[] =
1814 "plock(op) -> None\n\
1815 Lock program segments into memory.";
1817 static PyObject *
1818 posix_plock(self, args)
1819 PyObject *self;
1820 PyObject *args;
1822 int op;
1823 if (!PyArg_Parse(args, "i", &op))
1824 return NULL;
1825 if (plock(op) == -1)
1826 return posix_error();
1827 Py_INCREF(Py_None);
1828 return Py_None;
1830 #endif
1833 #ifdef HAVE_POPEN
1834 static char posix_popen__doc__[] =
1835 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\
1836 Open a pipe to/from a command returning a file object.";
1838 #if defined(PYOS_OS2)
1839 static int
1840 async_system(const char *command)
1842 char *p, errormsg[256], args[1024];
1843 RESULTCODES rcodes;
1844 APIRET rc;
1845 char *shell = getenv("COMSPEC");
1846 if (!shell)
1847 shell = "cmd";
1849 strcpy(args, shell);
1850 p = &args[ strlen(args)+1 ];
1851 strcpy(p, "/c ");
1852 strcat(p, command);
1853 p += strlen(p) + 1;
1854 *p = '\0';
1856 rc = DosExecPgm(errormsg, sizeof(errormsg),
1857 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
1858 args,
1859 NULL, /* Inherit Parent's Environment */
1860 &rcodes, shell);
1861 return rc;
1864 static FILE *
1865 popen(const char *command, const char *mode, int pipesize, int *err)
1867 HFILE rhan, whan;
1868 FILE *retfd = NULL;
1869 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
1871 if (rc != NO_ERROR) {
1872 *err = rc;
1873 return NULL; /* ERROR - Unable to Create Anon Pipe */
1876 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
1877 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
1879 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
1880 close(1); /* Make STDOUT Available for Reallocation */
1882 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
1883 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
1885 if (async_system(command) == NO_ERROR)
1886 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
1889 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
1890 DosExitCritSec(); /* Now Allow Other Threads to Run */
1892 close(oldfd); /* And Close Saved STDOUT Handle */
1893 return retfd; /* Return fd of Pipe or NULL if Error */
1895 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
1896 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
1898 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
1899 close(0); /* Make STDIN Available for Reallocation */
1901 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
1902 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
1904 if (async_system(command) == NO_ERROR)
1905 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
1908 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
1909 DosExitCritSec(); /* Now Allow Other Threads to Run */
1911 close(oldfd); /* And Close Saved STDIN Handle */
1912 return retfd; /* Return fd of Pipe or NULL if Error */
1914 } else {
1915 *err = ERROR_INVALID_ACCESS;
1916 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
1920 static PyObject *
1921 posix_popen(self, args)
1922 PyObject *self;
1923 PyObject *args;
1925 char *name;
1926 char *mode = "r";
1927 int err, bufsize = -1;
1928 FILE *fp;
1929 PyObject *f;
1930 if (!PyArg_ParseTuple(args, "s|si", &name, &mode, &bufsize))
1931 return NULL;
1932 Py_BEGIN_ALLOW_THREADS
1933 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
1934 Py_END_ALLOW_THREADS
1935 if (fp == NULL)
1936 return os2_error(err);
1938 f = PyFile_FromFile(fp, name, mode, fclose);
1939 if (f != NULL)
1940 PyFile_SetBufSize(f, bufsize);
1941 return f;
1944 #else
1945 static PyObject *
1946 posix_popen(self, args)
1947 PyObject *self;
1948 PyObject *args;
1950 char *name;
1951 char *mode = "r";
1952 int bufsize = -1;
1953 FILE *fp;
1954 PyObject *f;
1955 if (!PyArg_ParseTuple(args, "s|si", &name, &mode, &bufsize))
1956 return NULL;
1957 Py_BEGIN_ALLOW_THREADS
1958 fp = popen(name, mode);
1959 Py_END_ALLOW_THREADS
1960 if (fp == NULL)
1961 return posix_error();
1962 f = PyFile_FromFile(fp, name, mode, pclose);
1963 if (f != NULL)
1964 PyFile_SetBufSize(f, bufsize);
1965 return f;
1967 #endif
1969 #endif /* HAVE_POPEN */
1972 #ifdef HAVE_SETUID
1973 static char posix_setuid__doc__[] =
1974 "setuid(uid) -> None\n\
1975 Set the current process's user id.";
1976 static PyObject *
1977 posix_setuid(self, args)
1978 PyObject *self;
1979 PyObject *args;
1981 int uid;
1982 if (!PyArg_Parse(args, "i", &uid))
1983 return NULL;
1984 if (setuid(uid) < 0)
1985 return posix_error();
1986 Py_INCREF(Py_None);
1987 return Py_None;
1989 #endif /* HAVE_SETUID */
1992 #ifdef HAVE_SETGID
1993 static char posix_setgid__doc__[] =
1994 "setgid(gid) -> None\n\
1995 Set the current process's group id.";
1997 static PyObject *
1998 posix_setgid(self, args)
1999 PyObject *self;
2000 PyObject *args;
2002 int gid;
2003 if (!PyArg_Parse(args, "i", &gid))
2004 return NULL;
2005 if (setgid(gid) < 0)
2006 return posix_error();
2007 Py_INCREF(Py_None);
2008 return Py_None;
2010 #endif /* HAVE_SETGID */
2013 #ifdef HAVE_WAITPID
2014 static char posix_waitpid__doc__[] =
2015 "waitpid(pid, options) -> (pid, status)\n\
2016 Wait for completion of a give child process.";
2018 static PyObject *
2019 posix_waitpid(self, args)
2020 PyObject *self;
2021 PyObject *args;
2023 int pid, options;
2024 #ifdef UNION_WAIT
2025 union wait status;
2026 #define status_i (status.w_status)
2027 #else
2028 int status;
2029 #define status_i status
2030 #endif
2031 status_i = 0;
2033 if (!PyArg_Parse(args, "(ii)", &pid, &options))
2034 return NULL;
2035 Py_BEGIN_ALLOW_THREADS
2036 #ifdef NeXT
2037 pid = wait4(pid, &status, options, NULL);
2038 #else
2039 pid = waitpid(pid, &status, options);
2040 #endif
2041 Py_END_ALLOW_THREADS
2042 if (pid == -1)
2043 return posix_error();
2044 else
2045 return Py_BuildValue("ii", pid, status_i);
2047 #endif /* HAVE_WAITPID */
2050 #ifdef HAVE_WAIT
2051 static char posix_wait__doc__[] =
2052 "wait() -> (pid, status)\n\
2053 Wait for completion of a child process.";
2055 static PyObject *
2056 posix_wait(self, args)
2057 PyObject *self;
2058 PyObject *args;
2060 int pid, sts;
2061 #ifdef UNION_WAIT
2062 union wait status;
2063 #define status_i (status.w_status)
2064 #else
2065 int status;
2066 #define status_i status
2067 #endif
2068 status_i = 0;
2069 Py_BEGIN_ALLOW_THREADS
2070 pid = wait(&status);
2071 Py_END_ALLOW_THREADS
2072 if (pid == -1)
2073 return posix_error();
2074 else
2075 return Py_BuildValue("ii", pid, status_i);
2077 #endif
2080 static char posix_lstat__doc__[] =
2081 "lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
2082 Like stat(path), but do not follow symbolic links.";
2084 static PyObject *
2085 posix_lstat(self, args)
2086 PyObject *self;
2087 PyObject *args;
2089 #ifdef HAVE_LSTAT
2090 return posix_do_stat(self, args, lstat);
2091 #else /* !HAVE_LSTAT */
2092 return posix_do_stat(self, args, stat);
2093 #endif /* !HAVE_LSTAT */
2097 #ifdef HAVE_READLINK
2098 static char posix_readlink__doc__[] =
2099 "readlink(path) -> path\n\
2100 Return a string representing the path to which the symbolic link points.";
2102 static PyObject *
2103 posix_readlink(self, args)
2104 PyObject *self;
2105 PyObject *args;
2107 char buf[MAXPATHLEN];
2108 char *path;
2109 int n;
2110 if (!PyArg_Parse(args, "s", &path))
2111 return NULL;
2112 Py_BEGIN_ALLOW_THREADS
2113 n = readlink(path, buf, (int) sizeof buf);
2114 Py_END_ALLOW_THREADS
2115 if (n < 0)
2116 return posix_error_with_filename(path);
2117 return PyString_FromStringAndSize(buf, n);
2119 #endif /* HAVE_READLINK */
2122 #ifdef HAVE_SYMLINK
2123 static char posix_symlink__doc__[] =
2124 "symlink(src, dst) -> None\n\
2125 Create a symbolic link.";
2127 static PyObject *
2128 posix_symlink(self, args)
2129 PyObject *self;
2130 PyObject *args;
2132 return posix_2str(args, symlink);
2134 #endif /* HAVE_SYMLINK */
2137 #ifdef HAVE_TIMES
2138 #ifndef HZ
2139 #define HZ 60 /* Universal constant :-) */
2140 #endif /* HZ */
2142 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
2143 static long
2144 system_uptime()
2146 ULONG value = 0;
2148 Py_BEGIN_ALLOW_THREADS
2149 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
2150 Py_END_ALLOW_THREADS
2152 return value;
2155 static PyObject *
2156 posix_times(self, args)
2157 PyObject *self;
2158 PyObject *args;
2160 if (!PyArg_NoArgs(args))
2161 return NULL;
2163 /* Currently Only Uptime is Provided -- Others Later */
2164 return Py_BuildValue("ddddd",
2165 (double)0 /* t.tms_utime / HZ */,
2166 (double)0 /* t.tms_stime / HZ */,
2167 (double)0 /* t.tms_cutime / HZ */,
2168 (double)0 /* t.tms_cstime / HZ */,
2169 (double)system_uptime() / 1000);
2171 #else /* not OS2 */
2172 static PyObject *
2173 posix_times(self, args)
2174 PyObject *self;
2175 PyObject *args;
2177 struct tms t;
2178 clock_t c;
2179 if (!PyArg_NoArgs(args))
2180 return NULL;
2181 errno = 0;
2182 c = times(&t);
2183 if (c == (clock_t) -1)
2184 return posix_error();
2185 return Py_BuildValue("ddddd",
2186 (double)t.tms_utime / HZ,
2187 (double)t.tms_stime / HZ,
2188 (double)t.tms_cutime / HZ,
2189 (double)t.tms_cstime / HZ,
2190 (double)c / HZ);
2192 #endif /* not OS2 */
2193 #endif /* HAVE_TIMES */
2196 #ifdef MS_WIN32
2197 #define HAVE_TIMES /* so the method table will pick it up */
2198 static PyObject *
2199 posix_times(self, args)
2200 PyObject *self;
2201 PyObject *args;
2203 FILETIME create, exit, kernel, user;
2204 HANDLE hProc;
2205 if (!PyArg_NoArgs(args))
2206 return NULL;
2207 hProc = GetCurrentProcess();
2208 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
2209 /* The fields of a FILETIME structure are the hi and lo part
2210 of a 64-bit value expressed in 100 nanosecond units.
2211 1e7 is one second in such units; 1e-7 the inverse.
2212 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
2214 return Py_BuildValue(
2215 "ddddd",
2216 (double)(kernel.dwHighDateTime*429.4967296 +
2217 kernel.dwLowDateTime*1e-7),
2218 (double)(user.dwHighDateTime*429.4967296 +
2219 user.dwLowDateTime*1e-7),
2220 (double)0,
2221 (double)0,
2222 (double)0);
2224 #endif /* MS_WIN32 */
2226 #ifdef HAVE_TIMES
2227 static char posix_times__doc__[] =
2228 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
2229 Return a tuple of floating point numbers indicating process times.";
2230 #endif
2233 #ifdef HAVE_SETSID
2234 static char posix_setsid__doc__[] =
2235 "setsid() -> None\n\
2236 Call the system call setsid().";
2238 static PyObject *
2239 posix_setsid(self, args)
2240 PyObject *self;
2241 PyObject *args;
2243 if (!PyArg_NoArgs(args))
2244 return NULL;
2245 if (setsid() < 0)
2246 return posix_error();
2247 Py_INCREF(Py_None);
2248 return Py_None;
2250 #endif /* HAVE_SETSID */
2252 #ifdef HAVE_SETPGID
2253 static char posix_setpgid__doc__[] =
2254 "setpgid(pid, pgrp) -> None\n\
2255 Call the system call setpgid().";
2257 static PyObject *
2258 posix_setpgid(self, args)
2259 PyObject *self;
2260 PyObject *args;
2262 int pid, pgrp;
2263 if (!PyArg_Parse(args, "(ii)", &pid, &pgrp))
2264 return NULL;
2265 if (setpgid(pid, pgrp) < 0)
2266 return posix_error();
2267 Py_INCREF(Py_None);
2268 return Py_None;
2270 #endif /* HAVE_SETPGID */
2273 #ifdef HAVE_TCGETPGRP
2274 static char posix_tcgetpgrp__doc__[] =
2275 "tcgetpgrp(fd) -> pgid\n\
2276 Return the process group associated with the terminal given by a fd.";
2278 static PyObject *
2279 posix_tcgetpgrp(self, args)
2280 PyObject *self;
2281 PyObject *args;
2283 int fd, pgid;
2284 if (!PyArg_Parse(args, "i", &fd))
2285 return NULL;
2286 pgid = tcgetpgrp(fd);
2287 if (pgid < 0)
2288 return posix_error();
2289 return PyInt_FromLong((long)pgid);
2291 #endif /* HAVE_TCGETPGRP */
2294 #ifdef HAVE_TCSETPGRP
2295 static char posix_tcsetpgrp__doc__[] =
2296 "tcsetpgrp(fd, pgid) -> None\n\
2297 Set the process group associated with the terminal given by a fd.";
2299 static PyObject *
2300 posix_tcsetpgrp(self, args)
2301 PyObject *self;
2302 PyObject *args;
2304 int fd, pgid;
2305 if (!PyArg_Parse(args, "(ii)", &fd, &pgid))
2306 return NULL;
2307 if (tcsetpgrp(fd, pgid) < 0)
2308 return posix_error();
2309 Py_INCREF(Py_None);
2310 return Py_None;
2312 #endif /* HAVE_TCSETPGRP */
2314 /* Functions acting on file descriptors */
2316 static char posix_open__doc__[] =
2317 "open(filename, flag [, mode=0777]) -> fd\n\
2318 Open a file (for low level IO).";
2320 static PyObject *
2321 posix_open(self, args)
2322 PyObject *self;
2323 PyObject *args;
2325 char *file;
2326 int flag;
2327 int mode = 0777;
2328 int fd;
2329 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
2330 return NULL;
2332 Py_BEGIN_ALLOW_THREADS
2333 fd = open(file, flag, mode);
2334 Py_END_ALLOW_THREADS
2335 if (fd < 0)
2336 return posix_error_with_filename(file);
2337 return PyInt_FromLong((long)fd);
2341 static char posix_close__doc__[] =
2342 "close(fd) -> None\n\
2343 Close a file descriptor (for low level IO).";
2345 static PyObject *
2346 posix_close(self, args)
2347 PyObject *self;
2348 PyObject *args;
2350 int fd, res;
2351 if (!PyArg_Parse(args, "i", &fd))
2352 return NULL;
2353 Py_BEGIN_ALLOW_THREADS
2354 res = close(fd);
2355 Py_END_ALLOW_THREADS
2356 if (res < 0)
2357 return posix_error();
2358 Py_INCREF(Py_None);
2359 return Py_None;
2363 static char posix_dup__doc__[] =
2364 "dup(fd) -> fd2\n\
2365 Return a duplicate of a file descriptor.";
2367 static PyObject *
2368 posix_dup(self, args)
2369 PyObject *self;
2370 PyObject *args;
2372 int fd;
2373 if (!PyArg_Parse(args, "i", &fd))
2374 return NULL;
2375 Py_BEGIN_ALLOW_THREADS
2376 fd = dup(fd);
2377 Py_END_ALLOW_THREADS
2378 if (fd < 0)
2379 return posix_error();
2380 return PyInt_FromLong((long)fd);
2384 static char posix_dup2__doc__[] =
2385 "dup2(fd, fd2) -> None\n\
2386 Duplicate file descriptor.";
2388 static PyObject *
2389 posix_dup2(self, args)
2390 PyObject *self;
2391 PyObject *args;
2393 int fd, fd2, res;
2394 if (!PyArg_Parse(args, "(ii)", &fd, &fd2))
2395 return NULL;
2396 Py_BEGIN_ALLOW_THREADS
2397 res = dup2(fd, fd2);
2398 Py_END_ALLOW_THREADS
2399 if (res < 0)
2400 return posix_error();
2401 Py_INCREF(Py_None);
2402 return Py_None;
2406 static char posix_lseek__doc__[] =
2407 "lseek(fd, pos, how) -> newpos\n\
2408 Set the current position of a file descriptor.";
2410 static PyObject *
2411 posix_lseek(self, args)
2412 PyObject *self;
2413 PyObject *args;
2415 int fd, how;
2416 off_t pos, res;
2417 PyObject *posobj;
2418 if (!PyArg_Parse(args, "(iOi)", &fd, &posobj, &how))
2419 return NULL;
2420 #ifdef SEEK_SET
2421 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
2422 switch (how) {
2423 case 0: how = SEEK_SET; break;
2424 case 1: how = SEEK_CUR; break;
2425 case 2: how = SEEK_END; break;
2427 #endif /* SEEK_END */
2429 #if !defined(HAVE_LARGEFILE_SUPPORT)
2430 pos = PyInt_AsLong(posobj);
2431 #else
2432 pos = PyLong_Check(posobj) ?
2433 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
2434 #endif
2435 if (PyErr_Occurred())
2436 return NULL;
2438 Py_BEGIN_ALLOW_THREADS
2439 res = lseek(fd, pos, how);
2440 Py_END_ALLOW_THREADS
2441 if (res < 0)
2442 return posix_error();
2444 #if !defined(HAVE_LARGEFILE_SUPPORT)
2445 return PyInt_FromLong(res);
2446 #else
2447 return PyLong_FromLongLong(res);
2448 #endif
2452 static char posix_read__doc__[] =
2453 "read(fd, buffersize) -> string\n\
2454 Read a file descriptor.";
2456 static PyObject *
2457 posix_read(self, args)
2458 PyObject *self;
2459 PyObject *args;
2461 int fd, size, n;
2462 PyObject *buffer;
2463 if (!PyArg_Parse(args, "(ii)", &fd, &size))
2464 return NULL;
2465 buffer = PyString_FromStringAndSize((char *)NULL, size);
2466 if (buffer == NULL)
2467 return NULL;
2468 Py_BEGIN_ALLOW_THREADS
2469 n = read(fd, PyString_AsString(buffer), size);
2470 Py_END_ALLOW_THREADS
2471 if (n < 0) {
2472 Py_DECREF(buffer);
2473 return posix_error();
2475 if (n != size)
2476 _PyString_Resize(&buffer, n);
2477 return buffer;
2481 static char posix_write__doc__[] =
2482 "write(fd, string) -> byteswritten\n\
2483 Write a string to a file descriptor.";
2485 static PyObject *
2486 posix_write(self, args)
2487 PyObject *self;
2488 PyObject *args;
2490 int fd, size;
2491 char *buffer;
2492 if (!PyArg_Parse(args, "(is#)", &fd, &buffer, &size))
2493 return NULL;
2494 Py_BEGIN_ALLOW_THREADS
2495 size = write(fd, buffer, size);
2496 Py_END_ALLOW_THREADS
2497 if (size < 0)
2498 return posix_error();
2499 return PyInt_FromLong((long)size);
2503 static char posix_fstat__doc__[]=
2504 "fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
2505 Like stat(), but for an open file descriptor.";
2507 static PyObject *
2508 posix_fstat(self, args)
2509 PyObject *self;
2510 PyObject *args;
2512 int fd;
2513 struct stat st;
2514 int res;
2515 if (!PyArg_Parse(args, "i", &fd))
2516 return NULL;
2517 Py_BEGIN_ALLOW_THREADS
2518 res = fstat(fd, &st);
2519 Py_END_ALLOW_THREADS
2520 if (res != 0)
2521 return posix_error();
2522 #if !defined(HAVE_LARGEFILE_SUPPORT)
2523 return Py_BuildValue("(llllllllll)",
2524 (long)st.st_mode,
2525 (long)st.st_ino,
2526 (long)st.st_dev,
2527 (long)st.st_nlink,
2528 (long)st.st_uid,
2529 (long)st.st_gid,
2530 (long)st.st_size,
2531 (long)st.st_atime,
2532 (long)st.st_mtime,
2533 (long)st.st_ctime);
2534 #else
2535 return Py_BuildValue("(lLllllLlll)",
2536 (long)st.st_mode,
2537 (LONG_LONG)st.st_ino,
2538 (long)st.st_dev,
2539 (long)st.st_nlink,
2540 (long)st.st_uid,
2541 (long)st.st_gid,
2542 (LONG_LONG)st.st_size,
2543 (long)st.st_atime,
2544 (long)st.st_mtime,
2545 (long)st.st_ctime);
2546 #endif
2550 static char posix_fdopen__doc__[] =
2551 "fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
2552 Return an open file object connected to a file descriptor.";
2554 static PyObject *
2555 posix_fdopen(self, args)
2556 PyObject *self;
2557 PyObject *args;
2559 extern int fclose Py_PROTO((FILE *));
2560 int fd;
2561 char *mode = "r";
2562 int bufsize = -1;
2563 FILE *fp;
2564 PyObject *f;
2565 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
2566 return NULL;
2568 Py_BEGIN_ALLOW_THREADS
2569 fp = fdopen(fd, mode);
2570 Py_END_ALLOW_THREADS
2571 if (fp == NULL)
2572 return posix_error();
2573 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
2574 if (f != NULL)
2575 PyFile_SetBufSize(f, bufsize);
2576 return f;
2580 #ifdef HAVE_PIPE
2581 static char posix_pipe__doc__[] =
2582 "pipe() -> (read_end, write_end)\n\
2583 Create a pipe.";
2585 static PyObject *
2586 posix_pipe(self, args)
2587 PyObject *self;
2588 PyObject *args;
2590 #if defined(PYOS_OS2)
2591 HFILE read, write;
2592 APIRET rc;
2594 if (!PyArg_Parse(args, ""))
2595 return NULL;
2597 Py_BEGIN_ALLOW_THREADS
2598 rc = DosCreatePipe( &read, &write, 4096);
2599 Py_END_ALLOW_THREADS
2600 if (rc != NO_ERROR)
2601 return os2_error(rc);
2603 return Py_BuildValue("(ii)", read, write);
2604 #else
2605 #if !defined(MS_WIN32)
2606 int fds[2];
2607 int res;
2608 if (!PyArg_Parse(args, ""))
2609 return NULL;
2610 Py_BEGIN_ALLOW_THREADS
2611 res = pipe(fds);
2612 Py_END_ALLOW_THREADS
2613 if (res != 0)
2614 return posix_error();
2615 return Py_BuildValue("(ii)", fds[0], fds[1]);
2616 #else /* MS_WIN32 */
2617 HANDLE read, write;
2618 int read_fd, write_fd;
2619 BOOL ok;
2620 if (!PyArg_Parse(args, ""))
2621 return NULL;
2622 Py_BEGIN_ALLOW_THREADS
2623 ok = CreatePipe(&read, &write, NULL, 0);
2624 Py_END_ALLOW_THREADS
2625 if (!ok)
2626 return posix_error();
2627 read_fd = _open_osfhandle((long)read, 0);
2628 write_fd = _open_osfhandle((long)write, 1);
2629 return Py_BuildValue("(ii)", read_fd, write_fd);
2630 #endif /* MS_WIN32 */
2631 #endif
2633 #endif /* HAVE_PIPE */
2636 #ifdef HAVE_MKFIFO
2637 static char posix_mkfifo__doc__[] =
2638 "mkfifo(file, [, mode=0666]) -> None\n\
2639 Create a FIFO (a POSIX named pipe).";
2641 static PyObject *
2642 posix_mkfifo(self, args)
2643 PyObject *self;
2644 PyObject *args;
2646 char *file;
2647 int mode = 0666;
2648 int res;
2649 if (!PyArg_ParseTuple(args, "s|i", &file, &mode))
2650 return NULL;
2651 Py_BEGIN_ALLOW_THREADS
2652 res = mkfifo(file, mode);
2653 Py_END_ALLOW_THREADS
2654 if (res < 0)
2655 return posix_error();
2656 Py_INCREF(Py_None);
2657 return Py_None;
2659 #endif
2662 #ifdef HAVE_FTRUNCATE
2663 static char posix_ftruncate__doc__[] =
2664 "ftruncate(fd, length) -> None\n\
2665 Truncate a file to a specified length.";
2667 static PyObject *
2668 posix_ftruncate(self, args)
2669 PyObject *self; /* Not used */
2670 PyObject *args;
2672 int fd;
2673 off_t length;
2674 int res;
2675 PyObject *lenobj;
2677 if (!PyArg_Parse(args, "(iO)", &fd, &lenobj))
2678 return NULL;
2680 #if !defined(HAVE_LARGEFILE_SUPPORT)
2681 length = PyInt_AsLong(lenobj);
2682 #else
2683 length = PyLong_Check(lenobj) ?
2684 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
2685 #endif
2686 if (PyErr_Occurred())
2687 return NULL;
2689 Py_BEGIN_ALLOW_THREADS
2690 res = ftruncate(fd, length);
2691 Py_END_ALLOW_THREADS
2692 if (res < 0) {
2693 PyErr_SetFromErrno(PyExc_IOError);
2694 return NULL;
2696 Py_INCREF(Py_None);
2697 return Py_None;
2699 #endif
2701 #ifdef NeXT
2702 #define HAVE_PUTENV
2703 /* Steve Spicklemire got this putenv from NeXTAnswers */
2704 static int
2705 putenv(char *newval)
2707 extern char **environ;
2709 static int firstTime = 1;
2710 char **ep;
2711 char *cp;
2712 int esiz;
2713 char *np;
2715 if (!(np = strchr(newval, '=')))
2716 return 1;
2717 *np = '\0';
2719 /* look it up */
2720 for (ep=environ ; *ep ; ep++)
2722 /* this should always be true... */
2723 if (cp = strchr(*ep, '='))
2725 *cp = '\0';
2726 if (!strcmp(*ep, newval))
2728 /* got it! */
2729 *cp = '=';
2730 break;
2732 *cp = '=';
2734 else
2736 *np = '=';
2737 return 1;
2741 *np = '=';
2742 if (*ep)
2744 /* the string was already there:
2745 just replace it with the new one */
2746 *ep = newval;
2747 return 0;
2750 /* expand environ by one */
2751 for (esiz=2, ep=environ ; *ep ; ep++)
2752 esiz++;
2753 if (firstTime)
2755 char **epp;
2756 char **newenv;
2757 if (!(newenv = malloc(esiz * sizeof(char *))))
2758 return 1;
2760 for (ep=environ, epp=newenv ; *ep ;)
2761 *epp++ = *ep++;
2762 *epp++ = newval;
2763 *epp = (char *) 0;
2764 environ = newenv;
2766 else
2768 if (!(environ = realloc(environ, esiz * sizeof(char *))))
2769 return 1;
2770 environ[esiz - 2] = newval;
2771 environ[esiz - 1] = (char *) 0;
2772 firstTime = 0;
2775 return 0;
2777 #endif /* NeXT */
2780 #ifdef HAVE_PUTENV
2781 static char posix_putenv__doc__[] =
2782 "putenv(key, value) -> None\n\
2783 Change or add an environment variable.";
2785 #ifdef __BEOS__
2786 /* We have putenv(), but not in the headers (as of PR2). - [cjh] */
2787 int putenv( const char *str );
2788 #endif
2790 /* Save putenv() parameters as values here, so we can collect them when they
2791 * get re-set with another call for the same key. */
2792 static PyObject *posix_putenv_garbage;
2794 static PyObject *
2795 posix_putenv(self, args)
2796 PyObject *self;
2797 PyObject *args;
2799 char *s1, *s2;
2800 char *new;
2801 PyObject *newstr;
2803 if (!PyArg_ParseTuple(args, "ss", &s1, &s2))
2804 return NULL;
2806 #if defined(PYOS_OS2)
2807 if (stricmp(s1, "BEGINLIBPATH") == 0) {
2808 APIRET rc;
2810 if (strlen(s2) == 0) /* If New Value is an Empty String */
2811 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
2813 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
2814 if (rc != NO_ERROR)
2815 return os2_error(rc);
2817 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
2818 APIRET rc;
2820 if (strlen(s2) == 0) /* If New Value is an Empty String */
2821 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
2823 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
2824 if (rc != NO_ERROR)
2825 return os2_error(rc);
2826 } else {
2827 #endif
2829 /* XXX This can leak memory -- not easy to fix :-( */
2830 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
2831 if (newstr == NULL)
2832 return PyErr_NoMemory();
2833 new = PyString_AS_STRING(newstr);
2834 (void) sprintf(new, "%s=%s", s1, s2);
2835 if (putenv(new)) {
2836 posix_error();
2837 return NULL;
2839 /* Install the first arg and newstr in posix_putenv_garbage;
2840 * this will cause previous value to be collected. This has to
2841 * happen after the real putenv() call because the old value
2842 * was still accessible until then. */
2843 if (PyDict_SetItem(posix_putenv_garbage,
2844 PyTuple_GET_ITEM(args, 0), newstr)) {
2845 /* really not much we can do; just leak */
2846 PyErr_Clear();
2848 else {
2849 Py_DECREF(newstr);
2852 #if defined(PYOS_OS2)
2854 #endif
2855 Py_INCREF(Py_None);
2856 return Py_None;
2858 #endif /* putenv */
2860 #ifdef HAVE_STRERROR
2861 static char posix_strerror__doc__[] =
2862 "strerror(code) -> string\n\
2863 Translate an error code to a message string.";
2865 PyObject *
2866 posix_strerror(self, args)
2867 PyObject *self;
2868 PyObject *args;
2870 int code;
2871 char *message;
2872 if (!PyArg_ParseTuple(args, "i", &code))
2873 return NULL;
2874 message = strerror(code);
2875 if (message == NULL) {
2876 PyErr_SetString(PyExc_ValueError,
2877 "strerror code out of range");
2878 return NULL;
2880 return PyString_FromString(message);
2882 #endif /* strerror */
2885 #ifdef HAVE_SYS_WAIT_H
2887 #ifdef WIFSTOPPED
2888 static char posix_WIFSTOPPED__doc__[] =
2889 "WIFSTOPPED(status) -> Boolean\n\
2890 Return true if the process returning 'status' was stopped.";
2892 static PyObject *
2893 posix_WIFSTOPPED(self, args)
2894 PyObject *self;
2895 PyObject *args;
2897 #ifdef UNION_WAIT
2898 union wait status;
2899 #define status_i (status.w_status)
2900 #else
2901 int status;
2902 #define status_i status
2903 #endif
2904 status_i = 0;
2906 if (!PyArg_Parse(args, "i", &status_i))
2908 return NULL;
2911 return Py_BuildValue("i", WIFSTOPPED(status));
2913 #endif /* WIFSTOPPED */
2915 #ifdef WIFSIGNALED
2916 static char posix_WIFSIGNALED__doc__[] =
2917 "WIFSIGNALED(status) -> Boolean\n\
2918 Return true if the process returning 'status' was terminated by a signal.";
2920 static PyObject *
2921 posix_WIFSIGNALED(self, args)
2922 PyObject *self;
2923 PyObject *args;
2925 #ifdef UNION_WAIT
2926 union wait status;
2927 #define status_i (status.w_status)
2928 #else
2929 int status;
2930 #define status_i status
2931 #endif
2932 status_i = 0;
2934 if (!PyArg_Parse(args, "i", &status_i))
2936 return NULL;
2939 return Py_BuildValue("i", WIFSIGNALED(status));
2941 #endif /* WIFSIGNALED */
2943 #ifdef WIFEXITED
2944 static char posix_WIFEXITED__doc__[] =
2945 "WIFEXITED(status) -> Boolean\n\
2946 Return true if the process returning 'status' exited using the exit()\n\
2947 system call.";
2949 static PyObject *
2950 posix_WIFEXITED(self, args)
2951 PyObject *self;
2952 PyObject *args;
2954 #ifdef UNION_WAIT
2955 union wait status;
2956 #define status_i (status.w_status)
2957 #else
2958 int status;
2959 #define status_i status
2960 #endif
2961 status_i = 0;
2963 if (!PyArg_Parse(args, "i", &status_i))
2965 return NULL;
2968 return Py_BuildValue("i", WIFEXITED(status));
2970 #endif /* WIFEXITED */
2972 #ifdef WEXITSTATUS
2973 static char posix_WEXITSTATUS__doc__[] =
2974 "WEXITSTATUS(status) -> integer\n\
2975 Return the process return code from 'status'.";
2977 static PyObject *
2978 posix_WEXITSTATUS(self, args)
2979 PyObject *self;
2980 PyObject *args;
2982 #ifdef UNION_WAIT
2983 union wait status;
2984 #define status_i (status.w_status)
2985 #else
2986 int status;
2987 #define status_i status
2988 #endif
2989 status_i = 0;
2991 if (!PyArg_Parse(args, "i", &status_i))
2993 return NULL;
2996 return Py_BuildValue("i", WEXITSTATUS(status));
2998 #endif /* WEXITSTATUS */
3000 #ifdef WTERMSIG
3001 static char posix_WTERMSIG__doc__[] =
3002 "WTERMSIG(status) -> integer\n\
3003 Return the signal that terminated the process that provided the 'status'\n\
3004 value.";
3006 static PyObject *
3007 posix_WTERMSIG(self, args)
3008 PyObject *self;
3009 PyObject *args;
3011 #ifdef UNION_WAIT
3012 union wait status;
3013 #define status_i (status.w_status)
3014 #else
3015 int status;
3016 #define status_i status
3017 #endif
3018 status_i = 0;
3020 if (!PyArg_Parse(args, "i", &status_i))
3022 return NULL;
3025 return Py_BuildValue("i", WTERMSIG(status));
3027 #endif /* WTERMSIG */
3029 #ifdef WSTOPSIG
3030 static char posix_WSTOPSIG__doc__[] =
3031 "WSTOPSIG(status) -> integer\n\
3032 Return the signal that stopped the process that provided the 'status' value.";
3034 static PyObject *
3035 posix_WSTOPSIG(self, args)
3036 PyObject *self;
3037 PyObject *args;
3039 #ifdef UNION_WAIT
3040 union wait status;
3041 #define status_i (status.w_status)
3042 #else
3043 int status;
3044 #define status_i status
3045 #endif
3046 status_i = 0;
3048 if (!PyArg_Parse(args, "i", &status_i))
3050 return NULL;
3053 return Py_BuildValue("i", WSTOPSIG(status));
3055 #endif /* WSTOPSIG */
3057 #endif /* HAVE_SYS_WAIT_H */
3060 #if defined(HAVE_FSTATVFS)
3061 #include <sys/statvfs.h>
3063 static char posix_fstatvfs__doc__[] =
3064 "fstatvfs(fd) -> \n\
3065 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
3066 Perform an fstatvfs system call on the given fd.";
3068 static PyObject *
3069 posix_fstatvfs(self, args)
3070 PyObject *self;
3071 PyObject *args;
3073 int fd, res;
3074 struct statvfs st;
3075 if (!PyArg_ParseTuple(args, "i", &fd))
3076 return NULL;
3077 Py_BEGIN_ALLOW_THREADS
3078 res = fstatvfs(fd, &st);
3079 Py_END_ALLOW_THREADS
3080 if (res != 0)
3081 return posix_error();
3082 #if !defined(HAVE_LARGEFILE_SUPPORT)
3083 return Py_BuildValue("(llllllllll)",
3084 (long) st.f_bsize,
3085 (long) st.f_frsize,
3086 (long) st.f_blocks,
3087 (long) st.f_bfree,
3088 (long) st.f_bavail,
3089 (long) st.f_files,
3090 (long) st.f_ffree,
3091 (long) st.f_favail,
3092 (long) st.f_flag,
3093 (long) st.f_namemax);
3094 #else
3095 return Py_BuildValue("(llLLLLLLll)",
3096 (long) st.f_bsize,
3097 (long) st.f_frsize,
3098 (LONG_LONG) st.f_blocks,
3099 (LONG_LONG) st.f_bfree,
3100 (LONG_LONG) st.f_bavail,
3101 (LONG_LONG) st.f_files,
3102 (LONG_LONG) st.f_ffree,
3103 (LONG_LONG) st.f_favail,
3104 (long) st.f_flag,
3105 (long) st.f_namemax);
3106 #endif
3108 #endif /* HAVE_FSTATVFS */
3111 #if defined(HAVE_STATVFS)
3112 #include <sys/statvfs.h>
3114 static char posix_statvfs__doc__[] =
3115 "statvfs(path) -> \n\
3116 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
3117 Perform a statvfs system call on the given path.";
3119 static PyObject *
3120 posix_statvfs(self, args)
3121 PyObject *self;
3122 PyObject *args;
3124 char *path;
3125 int res;
3126 struct statvfs st;
3127 if (!PyArg_ParseTuple(args, "s", &path))
3128 return NULL;
3129 Py_BEGIN_ALLOW_THREADS
3130 res = statvfs(path, &st);
3131 Py_END_ALLOW_THREADS
3132 if (res != 0)
3133 return posix_error_with_filename(path);
3134 #if !defined(HAVE_LARGEFILE_SUPPORT)
3135 return Py_BuildValue("(llllllllll)",
3136 (long) st.f_bsize,
3137 (long) st.f_frsize,
3138 (long) st.f_blocks,
3139 (long) st.f_bfree,
3140 (long) st.f_bavail,
3141 (long) st.f_files,
3142 (long) st.f_ffree,
3143 (long) st.f_favail,
3144 (long) st.f_flag,
3145 (long) st.f_namemax);
3146 #else /* HAVE_LARGEFILE_SUPPORT */
3147 return Py_BuildValue("(llLLLLLLll)",
3148 (long) st.f_bsize,
3149 (long) st.f_frsize,
3150 (LONG_LONG) st.f_blocks,
3151 (LONG_LONG) st.f_bfree,
3152 (LONG_LONG) st.f_bavail,
3153 (LONG_LONG) st.f_files,
3154 (LONG_LONG) st.f_ffree,
3155 (LONG_LONG) st.f_favail,
3156 (long) st.f_flag,
3157 (long) st.f_namemax);
3158 #endif
3160 #endif /* HAVE_STATVFS */
3163 static PyMethodDef posix_methods[] = {
3164 {"access", posix_access, 0, posix_access__doc__},
3165 #ifdef HAVE_TTYNAME
3166 {"ttyname", posix_ttyname, 0, posix_ttyname__doc__},
3167 #endif
3168 {"chdir", posix_chdir, 0, posix_chdir__doc__},
3169 {"chmod", posix_chmod, 0, posix_chmod__doc__},
3170 #ifdef HAVE_CHOWN
3171 {"chown", posix_chown, 0, posix_chown__doc__},
3172 #endif /* HAVE_CHOWN */
3173 #ifdef HAVE_GETCWD
3174 {"getcwd", posix_getcwd, 0, posix_getcwd__doc__},
3175 #endif
3176 #ifdef HAVE_LINK
3177 {"link", posix_link, 0, posix_link__doc__},
3178 #endif /* HAVE_LINK */
3179 {"listdir", posix_listdir, 0, posix_listdir__doc__},
3180 {"lstat", posix_lstat, 0, posix_lstat__doc__},
3181 {"mkdir", posix_mkdir, 1, posix_mkdir__doc__},
3182 #ifdef HAVE_NICE
3183 {"nice", posix_nice, 0, posix_nice__doc__},
3184 #endif /* HAVE_NICE */
3185 #ifdef HAVE_READLINK
3186 {"readlink", posix_readlink, 0, posix_readlink__doc__},
3187 #endif /* HAVE_READLINK */
3188 {"rename", posix_rename, 0, posix_rename__doc__},
3189 {"rmdir", posix_rmdir, 0, posix_rmdir__doc__},
3190 {"stat", posix_stat, 0, posix_stat__doc__},
3191 #ifdef HAVE_SYMLINK
3192 {"symlink", posix_symlink, 0, posix_symlink__doc__},
3193 #endif /* HAVE_SYMLINK */
3194 #ifdef HAVE_SYSTEM
3195 {"system", posix_system, 0, posix_system__doc__},
3196 #endif
3197 {"umask", posix_umask, 0, posix_umask__doc__},
3198 #ifdef HAVE_UNAME
3199 {"uname", posix_uname, 0, posix_uname__doc__},
3200 #endif /* HAVE_UNAME */
3201 {"unlink", posix_unlink, 0, posix_unlink__doc__},
3202 {"remove", posix_unlink, 0, posix_remove__doc__},
3203 {"utime", posix_utime, 0, posix_utime__doc__},
3204 #ifdef HAVE_TIMES
3205 {"times", posix_times, 0, posix_times__doc__},
3206 #endif /* HAVE_TIMES */
3207 {"_exit", posix__exit, 0, posix__exit__doc__},
3208 #ifdef HAVE_EXECV
3209 {"execv", posix_execv, 0, posix_execv__doc__},
3210 {"execve", posix_execve, 0, posix_execve__doc__},
3211 #endif /* HAVE_EXECV */
3212 #ifdef HAVE_SPAWNV
3213 {"spawnv", posix_spawnv, 0, posix_spawnv__doc__},
3214 {"spawnve", posix_spawnve, 0, posix_spawnve__doc__},
3215 #endif /* HAVE_SPAWNV */
3216 #ifdef HAVE_FORK
3217 {"fork", posix_fork, 0, posix_fork__doc__},
3218 #endif /* HAVE_FORK */
3219 #ifdef HAVE_GETEGID
3220 {"getegid", posix_getegid, 0, posix_getegid__doc__},
3221 #endif /* HAVE_GETEGID */
3222 #ifdef HAVE_GETEUID
3223 {"geteuid", posix_geteuid, 0, posix_geteuid__doc__},
3224 #endif /* HAVE_GETEUID */
3225 #ifdef HAVE_GETGID
3226 {"getgid", posix_getgid, 0, posix_getgid__doc__},
3227 #endif /* HAVE_GETGID */
3228 {"getpid", posix_getpid, 0, posix_getpid__doc__},
3229 #ifdef HAVE_GETPGRP
3230 {"getpgrp", posix_getpgrp, 0, posix_getpgrp__doc__},
3231 #endif /* HAVE_GETPGRP */
3232 #ifdef HAVE_GETPPID
3233 {"getppid", posix_getppid, 0, posix_getppid__doc__},
3234 #endif /* HAVE_GETPPID */
3235 #ifdef HAVE_GETUID
3236 {"getuid", posix_getuid, 0, posix_getuid__doc__},
3237 #endif /* HAVE_GETUID */
3238 #ifdef HAVE_KILL
3239 {"kill", posix_kill, 0, posix_kill__doc__},
3240 #endif /* HAVE_KILL */
3241 #ifdef HAVE_PLOCK
3242 {"plock", posix_plock, 0, posix_plock__doc__},
3243 #endif /* HAVE_PLOCK */
3244 #ifdef HAVE_POPEN
3245 {"popen", posix_popen, 1, posix_popen__doc__},
3246 #endif /* HAVE_POPEN */
3247 #ifdef HAVE_SETUID
3248 {"setuid", posix_setuid, 0, posix_setuid__doc__},
3249 #endif /* HAVE_SETUID */
3250 #ifdef HAVE_SETGID
3251 {"setgid", posix_setgid, 0, posix_setgid__doc__},
3252 #endif /* HAVE_SETGID */
3253 #ifdef HAVE_SETPGRP
3254 {"setpgrp", posix_setpgrp, 0, posix_setpgrp__doc__},
3255 #endif /* HAVE_SETPGRP */
3256 #ifdef HAVE_WAIT
3257 {"wait", posix_wait, 0, posix_wait__doc__},
3258 #endif /* HAVE_WAIT */
3259 #ifdef HAVE_WAITPID
3260 {"waitpid", posix_waitpid, 0, posix_waitpid__doc__},
3261 #endif /* HAVE_WAITPID */
3262 #ifdef HAVE_SETSID
3263 {"setsid", posix_setsid, 0, posix_setsid__doc__},
3264 #endif /* HAVE_SETSID */
3265 #ifdef HAVE_SETPGID
3266 {"setpgid", posix_setpgid, 0, posix_setpgid__doc__},
3267 #endif /* HAVE_SETPGID */
3268 #ifdef HAVE_TCGETPGRP
3269 {"tcgetpgrp", posix_tcgetpgrp, 0, posix_tcgetpgrp__doc__},
3270 #endif /* HAVE_TCGETPGRP */
3271 #ifdef HAVE_TCSETPGRP
3272 {"tcsetpgrp", posix_tcsetpgrp, 0, posix_tcsetpgrp__doc__},
3273 #endif /* HAVE_TCSETPGRP */
3274 {"open", posix_open, 1, posix_open__doc__},
3275 {"close", posix_close, 0, posix_close__doc__},
3276 {"dup", posix_dup, 0, posix_dup__doc__},
3277 {"dup2", posix_dup2, 0, posix_dup2__doc__},
3278 {"lseek", posix_lseek, 0, posix_lseek__doc__},
3279 {"read", posix_read, 0, posix_read__doc__},
3280 {"write", posix_write, 0, posix_write__doc__},
3281 {"fstat", posix_fstat, 0, posix_fstat__doc__},
3282 {"fdopen", posix_fdopen, 1, posix_fdopen__doc__},
3283 #ifdef HAVE_PIPE
3284 {"pipe", posix_pipe, 0, posix_pipe__doc__},
3285 #endif
3286 #ifdef HAVE_MKFIFO
3287 {"mkfifo", posix_mkfifo, 1, posix_mkfifo__doc__},
3288 #endif
3289 #ifdef HAVE_FTRUNCATE
3290 {"ftruncate", posix_ftruncate, 1, posix_ftruncate__doc__},
3291 #endif
3292 #ifdef HAVE_PUTENV
3293 {"putenv", posix_putenv, 1, posix_putenv__doc__},
3294 #endif
3295 #ifdef HAVE_STRERROR
3296 {"strerror", posix_strerror, 1, posix_strerror__doc__},
3297 #endif
3298 #ifdef HAVE_FSYNC
3299 {"fsync", posix_fsync, 0, posix_fsync__doc__},
3300 #endif
3301 #ifdef HAVE_FDATASYNC
3302 {"fdatasync", posix_fdatasync, 0, posix_fdatasync__doc__},
3303 #endif
3304 #ifdef HAVE_SYS_WAIT_H
3305 #ifdef WIFSTOPPED
3306 {"WIFSTOPPED", posix_WIFSTOPPED, 0, posix_WIFSTOPPED__doc__},
3307 #endif /* WIFSTOPPED */
3308 #ifdef WIFSIGNALED
3309 {"WIFSIGNALED", posix_WIFSIGNALED, 0, posix_WIFSIGNALED__doc__},
3310 #endif /* WIFSIGNALED */
3311 #ifdef WIFEXITED
3312 {"WIFEXITED", posix_WIFEXITED, 0, posix_WIFEXITED__doc__},
3313 #endif /* WIFEXITED */
3314 #ifdef WEXITSTATUS
3315 {"WEXITSTATUS", posix_WEXITSTATUS, 0, posix_WEXITSTATUS__doc__},
3316 #endif /* WEXITSTATUS */
3317 #ifdef WTERMSIG
3318 {"WTERMSIG", posix_WTERMSIG, 0, posix_WTERMSIG__doc__},
3319 #endif /* WTERMSIG */
3320 #ifdef WSTOPSIG
3321 {"WSTOPSIG", posix_WSTOPSIG, 0, posix_WSTOPSIG__doc__},
3322 #endif /* WSTOPSIG */
3323 #endif /* HAVE_SYS_WAIT_H */
3324 #ifdef HAVE_FSTATVFS
3325 {"fstatvfs", posix_fstatvfs, 1, posix_fstatvfs__doc__},
3326 #endif
3327 #ifdef HAVE_STATVFS
3328 {"statvfs", posix_statvfs, 1, posix_statvfs__doc__},
3329 #endif
3330 {NULL, NULL} /* Sentinel */
3334 static int
3335 ins(d, symbol, value)
3336 PyObject* d;
3337 char* symbol;
3338 long value;
3340 PyObject* v = PyInt_FromLong(value);
3341 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
3342 return -1; /* triggers fatal error */
3344 Py_DECREF(v);
3345 return 0;
3348 #if defined(PYOS_OS2)
3349 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
3350 static int insertvalues(PyObject *d)
3352 APIRET rc;
3353 ULONG values[QSV_MAX+1];
3354 PyObject *v;
3355 char *ver, tmp[10];
3357 Py_BEGIN_ALLOW_THREADS
3358 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
3359 Py_END_ALLOW_THREADS
3361 if (rc != NO_ERROR) {
3362 os2_error(rc);
3363 return -1;
3366 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
3367 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
3368 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
3369 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
3370 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
3371 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
3372 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
3374 switch (values[QSV_VERSION_MINOR]) {
3375 case 0: ver = "2.00"; break;
3376 case 10: ver = "2.10"; break;
3377 case 11: ver = "2.11"; break;
3378 case 30: ver = "3.00"; break;
3379 case 40: ver = "4.00"; break;
3380 case 50: ver = "5.00"; break;
3381 default:
3382 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
3383 values[QSV_VERSION_MINOR]);
3384 ver = &tmp[0];
3387 /* Add Indicator of the Version of the Operating System */
3388 v = PyString_FromString(ver);
3389 if (!v || PyDict_SetItemString(d, "version", v) < 0)
3390 return -1;
3391 Py_DECREF(v);
3393 /* Add Indicator of Which Drive was Used to Boot the System */
3394 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
3395 tmp[1] = ':';
3396 tmp[2] = '\0';
3398 v = PyString_FromString(tmp);
3399 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
3400 return -1;
3401 Py_DECREF(v);
3403 return 0;
3405 #endif
3407 static int
3408 all_ins(d)
3409 PyObject* d;
3411 #ifdef F_OK
3412 if (ins(d, "F_OK", (long)F_OK)) return -1;
3413 #endif
3414 #ifdef R_OK
3415 if (ins(d, "R_OK", (long)R_OK)) return -1;
3416 #endif
3417 #ifdef W_OK
3418 if (ins(d, "W_OK", (long)W_OK)) return -1;
3419 #endif
3420 #ifdef X_OK
3421 if (ins(d, "X_OK", (long)X_OK)) return -1;
3422 #endif
3423 #ifdef WNOHANG
3424 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
3425 #endif
3426 #ifdef O_RDONLY
3427 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
3428 #endif
3429 #ifdef O_WRONLY
3430 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
3431 #endif
3432 #ifdef O_RDWR
3433 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
3434 #endif
3435 #ifdef O_NDELAY
3436 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
3437 #endif
3438 #ifdef O_NONBLOCK
3439 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
3440 #endif
3441 #ifdef O_APPEND
3442 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
3443 #endif
3444 #ifdef O_DSYNC
3445 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
3446 #endif
3447 #ifdef O_RSYNC
3448 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
3449 #endif
3450 #ifdef O_SYNC
3451 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
3452 #endif
3453 #ifdef O_NOCTTY
3454 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
3455 #endif
3456 #ifdef O_CREAT
3457 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
3458 #endif
3459 #ifdef O_EXCL
3460 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
3461 #endif
3462 #ifdef O_TRUNC
3463 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
3464 #endif
3465 #ifdef O_BINARY
3466 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
3467 #endif
3468 #ifdef O_TEXT
3469 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
3470 #endif
3472 #ifdef HAVE_SPAWNV
3473 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
3474 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
3475 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
3476 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
3477 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
3478 #endif
3480 #if defined(PYOS_OS2)
3481 if (insertvalues(d)) return -1;
3482 #endif
3483 return 0;
3487 #if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
3488 #define INITFUNC initnt
3489 #define MODNAME "nt"
3490 #else
3491 #if defined(PYOS_OS2)
3492 #define INITFUNC initos2
3493 #define MODNAME "os2"
3494 #else
3495 #define INITFUNC initposix
3496 #define MODNAME "posix"
3497 #endif
3498 #endif
3500 DL_EXPORT(void)
3501 INITFUNC()
3503 PyObject *m, *d, *v;
3505 m = Py_InitModule4(MODNAME,
3506 posix_methods,
3507 posix__doc__,
3508 (PyObject *)NULL,
3509 PYTHON_API_VERSION);
3510 d = PyModule_GetDict(m);
3512 /* Initialize environ dictionary */
3513 v = convertenviron();
3514 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
3515 return;
3516 Py_DECREF(v);
3518 if (all_ins(d))
3519 return;
3521 PyDict_SetItemString(d, "error", PyExc_OSError);
3523 posix_putenv_garbage = PyDict_New();