Issue #5768: Change to Unicode output logic and test case for same.
[python.git] / Modules / posixmodule.c
blob7a96300e2502e47fbe69c993f619269abdb62bac
2 /* POSIX module implementation */
4 /* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
7 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
8 of the compiler used. Different compilers define their own feature
9 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
14 /* See also ../Dos/dosmodule.c */
16 #ifdef __APPLE__
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
22 # pragma weak lchown
23 # pragma weak statvfs
24 # pragma weak fstatvfs
26 #endif /* __APPLE__ */
28 #define PY_SSIZE_T_CLEAN
30 #include "Python.h"
31 #include "structseq.h"
33 #if defined(__VMS)
34 # include <unixio.h>
35 #endif /* defined(__VMS) */
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
41 PyDoc_STRVAR(posix__doc__,
42 "This module provides access to operating system functionality that is\n\
43 standardized by the C Standard and the POSIX standard (a thinly\n\
44 disguised Unix interface). Refer to the library manual and\n\
45 corresponding Unix manual entries for more information on calls.");
47 #ifndef Py_USING_UNICODE
48 /* This is used in signatures of functions. */
49 #define Py_UNICODE void
50 #endif
52 #if defined(PYOS_OS2)
53 #define INCL_DOS
54 #define INCL_DOSERRORS
55 #define INCL_DOSPROCESS
56 #define INCL_NOPMAPI
57 #include <os2.h>
58 #if defined(PYCC_GCC)
59 #include <ctype.h>
60 #include <io.h>
61 #include <stdio.h>
62 #include <process.h>
63 #endif
64 #include "osdefs.h"
65 #endif
67 #ifdef HAVE_SYS_TYPES_H
68 #include <sys/types.h>
69 #endif /* HAVE_SYS_TYPES_H */
71 #ifdef HAVE_SYS_STAT_H
72 #include <sys/stat.h>
73 #endif /* HAVE_SYS_STAT_H */
75 #ifdef HAVE_SYS_WAIT_H
76 #include <sys/wait.h> /* For WNOHANG */
77 #endif
79 #ifdef HAVE_SIGNAL_H
80 #include <signal.h>
81 #endif
83 #ifdef HAVE_FCNTL_H
84 #include <fcntl.h>
85 #endif /* HAVE_FCNTL_H */
87 #ifdef HAVE_GRP_H
88 #include <grp.h>
89 #endif
91 #ifdef HAVE_SYSEXITS_H
92 #include <sysexits.h>
93 #endif /* HAVE_SYSEXITS_H */
95 #ifdef HAVE_SYS_LOADAVG_H
96 #include <sys/loadavg.h>
97 #endif
99 /* Various compilers have only certain posix functions */
100 /* XXX Gosh I wish these were all moved into pyconfig.h */
101 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
102 #include <process.h>
103 #else
104 #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
105 #define HAVE_GETCWD 1
106 #define HAVE_OPENDIR 1
107 #define HAVE_SYSTEM 1
108 #if defined(__OS2__)
109 #define HAVE_EXECV 1
110 #define HAVE_WAIT 1
111 #endif
112 #include <process.h>
113 #else
114 #ifdef __BORLANDC__ /* Borland compiler */
115 #define HAVE_EXECV 1
116 #define HAVE_GETCWD 1
117 #define HAVE_OPENDIR 1
118 #define HAVE_PIPE 1
119 #define HAVE_POPEN 1
120 #define HAVE_SYSTEM 1
121 #define HAVE_WAIT 1
122 #else
123 #ifdef _MSC_VER /* Microsoft compiler */
124 #define HAVE_GETCWD 1
125 #define HAVE_SPAWNV 1
126 #define HAVE_EXECV 1
127 #define HAVE_PIPE 1
128 #define HAVE_POPEN 1
129 #define HAVE_SYSTEM 1
130 #define HAVE_CWAIT 1
131 #define HAVE_FSYNC 1
132 #define fsync _commit
133 #else
134 #if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135 /* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
136 #else /* all other compilers */
137 /* Unix functions that the configure script doesn't check for */
138 #define HAVE_EXECV 1
139 #define HAVE_FORK 1
140 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
141 #define HAVE_FORK1 1
142 #endif
143 #define HAVE_GETCWD 1
144 #define HAVE_GETEGID 1
145 #define HAVE_GETEUID 1
146 #define HAVE_GETGID 1
147 #define HAVE_GETPPID 1
148 #define HAVE_GETUID 1
149 #define HAVE_KILL 1
150 #define HAVE_OPENDIR 1
151 #define HAVE_PIPE 1
152 #ifndef __rtems__
153 #define HAVE_POPEN 1
154 #endif
155 #define HAVE_SYSTEM 1
156 #define HAVE_WAIT 1
157 #define HAVE_TTYNAME 1
158 #endif /* PYOS_OS2 && PYCC_GCC && __VMS */
159 #endif /* _MSC_VER */
160 #endif /* __BORLANDC__ */
161 #endif /* ! __WATCOMC__ || __QNX__ */
162 #endif /* ! __IBMC__ */
164 #ifndef _MSC_VER
166 #if defined(__sgi)&&_COMPILER_VERSION>=700
167 /* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
168 (default) */
169 extern char *ctermid_r(char *);
170 #endif
172 #ifndef HAVE_UNISTD_H
173 #if defined(PYCC_VACPP)
174 extern int mkdir(char *);
175 #else
176 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
177 extern int mkdir(const char *);
178 #else
179 extern int mkdir(const char *, mode_t);
180 #endif
181 #endif
182 #if defined(__IBMC__) || defined(__IBMCPP__)
183 extern int chdir(char *);
184 extern int rmdir(char *);
185 #else
186 extern int chdir(const char *);
187 extern int rmdir(const char *);
188 #endif
189 #ifdef __BORLANDC__
190 extern int chmod(const char *, int);
191 #else
192 extern int chmod(const char *, mode_t);
193 #endif
194 /*#ifdef HAVE_FCHMOD
195 extern int fchmod(int, mode_t);
196 #endif*/
197 /*#ifdef HAVE_LCHMOD
198 extern int lchmod(const char *, mode_t);
199 #endif*/
200 extern int chown(const char *, uid_t, gid_t);
201 extern char *getcwd(char *, int);
202 extern char *strerror(int);
203 extern int link(const char *, const char *);
204 extern int rename(const char *, const char *);
205 extern int stat(const char *, struct stat *);
206 extern int unlink(const char *);
207 extern int pclose(FILE *);
208 #ifdef HAVE_SYMLINK
209 extern int symlink(const char *, const char *);
210 #endif /* HAVE_SYMLINK */
211 #ifdef HAVE_LSTAT
212 extern int lstat(const char *, struct stat *);
213 #endif /* HAVE_LSTAT */
214 #endif /* !HAVE_UNISTD_H */
216 #endif /* !_MSC_VER */
218 #ifdef HAVE_UTIME_H
219 #include <utime.h>
220 #endif /* HAVE_UTIME_H */
222 #ifdef HAVE_SYS_UTIME_H
223 #include <sys/utime.h>
224 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
225 #endif /* HAVE_SYS_UTIME_H */
227 #ifdef HAVE_SYS_TIMES_H
228 #include <sys/times.h>
229 #endif /* HAVE_SYS_TIMES_H */
231 #ifdef HAVE_SYS_PARAM_H
232 #include <sys/param.h>
233 #endif /* HAVE_SYS_PARAM_H */
235 #ifdef HAVE_SYS_UTSNAME_H
236 #include <sys/utsname.h>
237 #endif /* HAVE_SYS_UTSNAME_H */
239 #ifdef HAVE_DIRENT_H
240 #include <dirent.h>
241 #define NAMLEN(dirent) strlen((dirent)->d_name)
242 #else
243 #if defined(__WATCOMC__) && !defined(__QNX__)
244 #include <direct.h>
245 #define NAMLEN(dirent) strlen((dirent)->d_name)
246 #else
247 #define dirent direct
248 #define NAMLEN(dirent) (dirent)->d_namlen
249 #endif
250 #ifdef HAVE_SYS_NDIR_H
251 #include <sys/ndir.h>
252 #endif
253 #ifdef HAVE_SYS_DIR_H
254 #include <sys/dir.h>
255 #endif
256 #ifdef HAVE_NDIR_H
257 #include <ndir.h>
258 #endif
259 #endif
261 #ifdef _MSC_VER
262 #ifdef HAVE_DIRECT_H
263 #include <direct.h>
264 #endif
265 #ifdef HAVE_IO_H
266 #include <io.h>
267 #endif
268 #ifdef HAVE_PROCESS_H
269 #include <process.h>
270 #endif
271 #include "osdefs.h"
272 #include <malloc.h>
273 #include <windows.h>
274 #include <shellapi.h> /* for ShellExecute() */
275 #define popen _popen
276 #define pclose _pclose
277 #endif /* _MSC_VER */
279 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
280 #include <io.h>
281 #endif /* OS2 */
283 #ifndef MAXPATHLEN
284 #if defined(PATH_MAX) && PATH_MAX > 1024
285 #define MAXPATHLEN PATH_MAX
286 #else
287 #define MAXPATHLEN 1024
288 #endif
289 #endif /* MAXPATHLEN */
291 #ifdef UNION_WAIT
292 /* Emulate some macros on systems that have a union instead of macros */
294 #ifndef WIFEXITED
295 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
296 #endif
298 #ifndef WEXITSTATUS
299 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
300 #endif
302 #ifndef WTERMSIG
303 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
304 #endif
306 #define WAIT_TYPE union wait
307 #define WAIT_STATUS_INT(s) (s.w_status)
309 #else /* !UNION_WAIT */
310 #define WAIT_TYPE int
311 #define WAIT_STATUS_INT(s) (s)
312 #endif /* UNION_WAIT */
314 /* Don't use the "_r" form if we don't need it (also, won't have a
315 prototype for it, at least on Solaris -- maybe others as well?). */
316 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
317 #define USE_CTERMID_R
318 #endif
320 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
321 #define USE_TMPNAM_R
322 #endif
324 /* choose the appropriate stat and fstat functions and return structs */
325 #undef STAT
326 #if defined(MS_WIN64) || defined(MS_WINDOWS)
327 # define STAT win32_stat
328 # define FSTAT win32_fstat
329 # define STRUCT_STAT struct win32_stat
330 #else
331 # define STAT stat
332 # define FSTAT fstat
333 # define STRUCT_STAT struct stat
334 #endif
336 #if defined(MAJOR_IN_MKDEV)
337 #include <sys/mkdev.h>
338 #else
339 #if defined(MAJOR_IN_SYSMACROS)
340 #include <sys/sysmacros.h>
341 #endif
342 #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
343 #include <sys/mkdev.h>
344 #endif
345 #endif
347 #if defined _MSC_VER && _MSC_VER >= 1400
348 /* Microsoft CRT in VS2005 and higher will verify that a filehandle is
349 * valid and throw an assertion if it isn't.
350 * Normally, an invalid fd is likely to be a C program error and therefore
351 * an assertion can be useful, but it does contradict the POSIX standard
352 * which for write(2) states:
353 * "Otherwise, -1 shall be returned and errno set to indicate the error."
354 * "[EBADF] The fildes argument is not a valid file descriptor open for
355 * writing."
356 * Furthermore, python allows the user to enter any old integer
357 * as a fd and should merely raise a python exception on error.
358 * The Microsoft CRT doesn't provide an official way to check for the
359 * validity of a file descriptor, but we can emulate its internal behaviour
360 * by using the exported __pinfo data member and knowledge of the
361 * internal structures involved.
362 * The structures below must be updated for each version of visual studio
363 * according to the file internal.h in the CRT source, until MS comes
364 * up with a less hacky way to do this.
365 * (all of this is to avoid globally modifying the CRT behaviour using
366 * _set_invalid_parameter_handler() and _CrtSetReportMode())
368 /* The actual size of the structure is determined at runtime.
369 * Only the first items must be present.
371 typedef struct {
372 intptr_t osfhnd;
373 char osfile;
374 } my_ioinfo;
376 extern __declspec(dllimport) char * __pioinfo[];
377 #define IOINFO_L2E 5
378 #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
379 #define IOINFO_ARRAYS 64
380 #define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
381 #define FOPEN 0x01
382 #define _NO_CONSOLE_FILENO (intptr_t)-2
384 /* This function emulates what the windows CRT does to validate file handles */
386 _PyVerify_fd(int fd)
388 const int i1 = fd >> IOINFO_L2E;
389 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
391 static int sizeof_ioinfo = 0;
393 /* Determine the actual size of the ioinfo structure,
394 * as used by the CRT loaded in memory
396 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
397 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
399 if (sizeof_ioinfo == 0) {
400 /* This should not happen... */
401 goto fail;
404 /* See that it isn't a special CLEAR fileno */
405 if (fd != _NO_CONSOLE_FILENO) {
406 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
407 * we check pointer validity and other info
409 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
410 /* finally, check that the file is open */
411 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
412 if (info->osfile & FOPEN) {
413 return 1;
417 fail:
418 errno = EBADF;
419 return 0;
422 /* the special case of checking dup2. The target fd must be in a sensible range */
423 static int
424 _PyVerify_fd_dup2(int fd1, int fd2)
426 if (!_PyVerify_fd(fd1))
427 return 0;
428 if (fd2 == _NO_CONSOLE_FILENO)
429 return 0;
430 if ((unsigned)fd2 < _NHANDLE_)
431 return 1;
432 else
433 return 0;
435 #else
436 /* dummy version. _PyVerify_fd() is already defined in fileobject.h */
437 #define _PyVerify_fd_dup2(A, B) (1)
438 #endif
440 /* Return a dictionary corresponding to the POSIX environment table */
441 #ifdef WITH_NEXT_FRAMEWORK
442 /* On Darwin/MacOSX a shared library or framework has no access to
443 ** environ directly, we must obtain it with _NSGetEnviron().
445 #include <crt_externs.h>
446 static char **environ;
447 #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
448 extern char **environ;
449 #endif /* !_MSC_VER */
451 static PyObject *
452 convertenviron(void)
454 PyObject *d;
455 char **e;
456 d = PyDict_New();
457 if (d == NULL)
458 return NULL;
459 #ifdef WITH_NEXT_FRAMEWORK
460 if (environ == NULL)
461 environ = *_NSGetEnviron();
462 #endif
463 if (environ == NULL)
464 return d;
465 /* This part ignores errors */
466 for (e = environ; *e != NULL; e++) {
467 PyObject *k;
468 PyObject *v;
469 char *p = strchr(*e, '=');
470 if (p == NULL)
471 continue;
472 k = PyString_FromStringAndSize(*e, (int)(p-*e));
473 if (k == NULL) {
474 PyErr_Clear();
475 continue;
477 v = PyString_FromString(p+1);
478 if (v == NULL) {
479 PyErr_Clear();
480 Py_DECREF(k);
481 continue;
483 if (PyDict_GetItem(d, k) == NULL) {
484 if (PyDict_SetItem(d, k, v) != 0)
485 PyErr_Clear();
487 Py_DECREF(k);
488 Py_DECREF(v);
490 #if defined(PYOS_OS2)
492 APIRET rc;
493 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
495 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
496 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
497 PyObject *v = PyString_FromString(buffer);
498 PyDict_SetItemString(d, "BEGINLIBPATH", v);
499 Py_DECREF(v);
501 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
502 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
503 PyObject *v = PyString_FromString(buffer);
504 PyDict_SetItemString(d, "ENDLIBPATH", v);
505 Py_DECREF(v);
508 #endif
509 return d;
513 /* Set a POSIX-specific error from errno, and return NULL */
515 static PyObject *
516 posix_error(void)
518 return PyErr_SetFromErrno(PyExc_OSError);
520 static PyObject *
521 posix_error_with_filename(char* name)
523 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
526 #ifdef Py_WIN_WIDE_FILENAMES
527 static PyObject *
528 posix_error_with_unicode_filename(Py_UNICODE* name)
530 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
532 #endif /* Py_WIN_WIDE_FILENAMES */
535 static PyObject *
536 posix_error_with_allocated_filename(char* name)
538 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
539 PyMem_Free(name);
540 return rc;
543 #ifdef MS_WINDOWS
544 static PyObject *
545 win32_error(char* function, char* filename)
547 /* XXX We should pass the function name along in the future.
548 (_winreg.c also wants to pass the function name.)
549 This would however require an additional param to the
550 Windows error object, which is non-trivial.
552 errno = GetLastError();
553 if (filename)
554 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
555 else
556 return PyErr_SetFromWindowsErr(errno);
559 #ifdef Py_WIN_WIDE_FILENAMES
560 static PyObject *
561 win32_error_unicode(char* function, Py_UNICODE* filename)
563 /* XXX - see win32_error for comments on 'function' */
564 errno = GetLastError();
565 if (filename)
566 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
567 else
568 return PyErr_SetFromWindowsErr(errno);
571 static int
572 convert_to_unicode(PyObject **param)
574 if (PyUnicode_CheckExact(*param))
575 Py_INCREF(*param);
576 else if (PyUnicode_Check(*param))
577 /* For a Unicode subtype that's not a Unicode object,
578 return a true Unicode object with the same data. */
579 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
580 PyUnicode_GET_SIZE(*param));
581 else
582 *param = PyUnicode_FromEncodedObject(*param,
583 Py_FileSystemDefaultEncoding,
584 "strict");
585 return (*param) != NULL;
588 #endif /* Py_WIN_WIDE_FILENAMES */
590 #endif
592 #if defined(PYOS_OS2)
593 /**********************************************************************
594 * Helper Function to Trim and Format OS/2 Messages
595 **********************************************************************/
596 static void
597 os2_formatmsg(char *msgbuf, int msglen, char *reason)
599 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
601 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
602 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
604 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
605 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
608 /* Add Optional Reason Text */
609 if (reason) {
610 strcat(msgbuf, " : ");
611 strcat(msgbuf, reason);
615 /**********************************************************************
616 * Decode an OS/2 Operating System Error Code
618 * A convenience function to lookup an OS/2 error code and return a
619 * text message we can use to raise a Python exception.
621 * Notes:
622 * The messages for errors returned from the OS/2 kernel reside in
623 * the file OSO001.MSG in the \OS2 directory hierarchy.
625 **********************************************************************/
626 static char *
627 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
629 APIRET rc;
630 ULONG msglen;
632 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
633 Py_BEGIN_ALLOW_THREADS
634 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
635 errorcode, "oso001.msg", &msglen);
636 Py_END_ALLOW_THREADS
638 if (rc == NO_ERROR)
639 os2_formatmsg(msgbuf, msglen, reason);
640 else
641 PyOS_snprintf(msgbuf, msgbuflen,
642 "unknown OS error #%d", errorcode);
644 return msgbuf;
647 /* Set an OS/2-specific error and return NULL. OS/2 kernel
648 errors are not in a global variable e.g. 'errno' nor are
649 they congruent with posix error numbers. */
651 static PyObject * os2_error(int code)
653 char text[1024];
654 PyObject *v;
656 os2_strerror(text, sizeof(text), code, "");
658 v = Py_BuildValue("(is)", code, text);
659 if (v != NULL) {
660 PyErr_SetObject(PyExc_OSError, v);
661 Py_DECREF(v);
663 return NULL; /* Signal to Python that an Exception is Pending */
666 #endif /* OS2 */
668 /* POSIX generic methods */
670 static PyObject *
671 posix_fildes(PyObject *fdobj, int (*func)(int))
673 int fd;
674 int res;
675 fd = PyObject_AsFileDescriptor(fdobj);
676 if (fd < 0)
677 return NULL;
678 if (!_PyVerify_fd(fd))
679 return posix_error();
680 Py_BEGIN_ALLOW_THREADS
681 res = (*func)(fd);
682 Py_END_ALLOW_THREADS
683 if (res < 0)
684 return posix_error();
685 Py_INCREF(Py_None);
686 return Py_None;
689 #ifdef Py_WIN_WIDE_FILENAMES
690 static int
691 unicode_file_names(void)
693 static int canusewide = -1;
694 if (canusewide == -1) {
695 /* As per doc for ::GetVersion(), this is the correct test for
696 the Windows NT family. */
697 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
699 return canusewide;
701 #endif
703 static PyObject *
704 posix_1str(PyObject *args, char *format, int (*func)(const char*))
706 char *path1 = NULL;
707 int res;
708 if (!PyArg_ParseTuple(args, format,
709 Py_FileSystemDefaultEncoding, &path1))
710 return NULL;
711 Py_BEGIN_ALLOW_THREADS
712 res = (*func)(path1);
713 Py_END_ALLOW_THREADS
714 if (res < 0)
715 return posix_error_with_allocated_filename(path1);
716 PyMem_Free(path1);
717 Py_INCREF(Py_None);
718 return Py_None;
721 static PyObject *
722 posix_2str(PyObject *args,
723 char *format,
724 int (*func)(const char *, const char *))
726 char *path1 = NULL, *path2 = NULL;
727 int res;
728 if (!PyArg_ParseTuple(args, format,
729 Py_FileSystemDefaultEncoding, &path1,
730 Py_FileSystemDefaultEncoding, &path2))
731 return NULL;
732 Py_BEGIN_ALLOW_THREADS
733 res = (*func)(path1, path2);
734 Py_END_ALLOW_THREADS
735 PyMem_Free(path1);
736 PyMem_Free(path2);
737 if (res != 0)
738 /* XXX how to report both path1 and path2??? */
739 return posix_error();
740 Py_INCREF(Py_None);
741 return Py_None;
744 #ifdef Py_WIN_WIDE_FILENAMES
745 static PyObject*
746 win32_1str(PyObject* args, char* func,
747 char* format, BOOL (__stdcall *funcA)(LPCSTR),
748 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
750 PyObject *uni;
751 char *ansi;
752 BOOL result;
753 if (unicode_file_names()) {
754 if (!PyArg_ParseTuple(args, wformat, &uni))
755 PyErr_Clear();
756 else {
757 Py_BEGIN_ALLOW_THREADS
758 result = funcW(PyUnicode_AsUnicode(uni));
759 Py_END_ALLOW_THREADS
760 if (!result)
761 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
762 Py_INCREF(Py_None);
763 return Py_None;
766 if (!PyArg_ParseTuple(args, format, &ansi))
767 return NULL;
768 Py_BEGIN_ALLOW_THREADS
769 result = funcA(ansi);
770 Py_END_ALLOW_THREADS
771 if (!result)
772 return win32_error(func, ansi);
773 Py_INCREF(Py_None);
774 return Py_None;
778 /* This is a reimplementation of the C library's chdir function,
779 but one that produces Win32 errors instead of DOS error codes.
780 chdir is essentially a wrapper around SetCurrentDirectory; however,
781 it also needs to set "magic" environment variables indicating
782 the per-drive current directory, which are of the form =<drive>: */
783 static BOOL __stdcall
784 win32_chdir(LPCSTR path)
786 char new_path[MAX_PATH+1];
787 int result;
788 char env[4] = "=x:";
790 if(!SetCurrentDirectoryA(path))
791 return FALSE;
792 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
793 if (!result)
794 return FALSE;
795 /* In the ANSI API, there should not be any paths longer
796 than MAX_PATH. */
797 assert(result <= MAX_PATH+1);
798 if (strncmp(new_path, "\\\\", 2) == 0 ||
799 strncmp(new_path, "//", 2) == 0)
800 /* UNC path, nothing to do. */
801 return TRUE;
802 env[1] = new_path[0];
803 return SetEnvironmentVariableA(env, new_path);
806 /* The Unicode version differs from the ANSI version
807 since the current directory might exceed MAX_PATH characters */
808 static BOOL __stdcall
809 win32_wchdir(LPCWSTR path)
811 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
812 int result;
813 wchar_t env[4] = L"=x:";
815 if(!SetCurrentDirectoryW(path))
816 return FALSE;
817 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
818 if (!result)
819 return FALSE;
820 if (result > MAX_PATH+1) {
821 new_path = malloc(result * sizeof(wchar_t));
822 if (!new_path) {
823 SetLastError(ERROR_OUTOFMEMORY);
824 return FALSE;
826 result = GetCurrentDirectoryW(result, new_path);
827 if (!result) {
828 free(new_path);
829 return FALSE;
832 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
833 wcsncmp(new_path, L"//", 2) == 0)
834 /* UNC path, nothing to do. */
835 return TRUE;
836 env[1] = new_path[0];
837 result = SetEnvironmentVariableW(env, new_path);
838 if (new_path != _new_path)
839 free(new_path);
840 return result;
842 #endif
844 #ifdef MS_WINDOWS
845 /* The CRT of Windows has a number of flaws wrt. its stat() implementation:
846 - time stamps are restricted to second resolution
847 - file modification times suffer from forth-and-back conversions between
848 UTC and local time
849 Therefore, we implement our own stat, based on the Win32 API directly.
851 #define HAVE_STAT_NSEC 1
853 struct win32_stat{
854 int st_dev;
855 __int64 st_ino;
856 unsigned short st_mode;
857 int st_nlink;
858 int st_uid;
859 int st_gid;
860 int st_rdev;
861 __int64 st_size;
862 int st_atime;
863 int st_atime_nsec;
864 int st_mtime;
865 int st_mtime_nsec;
866 int st_ctime;
867 int st_ctime_nsec;
870 static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
872 static void
873 FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
875 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
876 /* Cannot simply cast and dereference in_ptr,
877 since it might not be aligned properly */
878 __int64 in;
879 memcpy(&in, in_ptr, sizeof(in));
880 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
881 /* XXX Win32 supports time stamps past 2038; we currently don't */
882 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
885 static void
886 time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
888 /* XXX endianness */
889 __int64 out;
890 out = time_in + secs_between_epochs;
891 out = out * 10000000 + nsec_in / 100;
892 memcpy(out_ptr, &out, sizeof(out));
895 /* Below, we *know* that ugo+r is 0444 */
896 #if _S_IREAD != 0400
897 #error Unsupported C library
898 #endif
899 static int
900 attributes_to_mode(DWORD attr)
902 int m = 0;
903 if (attr & FILE_ATTRIBUTE_DIRECTORY)
904 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
905 else
906 m |= _S_IFREG;
907 if (attr & FILE_ATTRIBUTE_READONLY)
908 m |= 0444;
909 else
910 m |= 0666;
911 return m;
914 static int
915 attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
917 memset(result, 0, sizeof(*result));
918 result->st_mode = attributes_to_mode(info->dwFileAttributes);
919 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
920 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
921 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
922 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
924 return 0;
927 /* Emulate GetFileAttributesEx[AW] on Windows 95 */
928 static int checked = 0;
929 static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
930 static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
931 static void
932 check_gfax()
934 HINSTANCE hKernel32;
935 if (checked)
936 return;
937 checked = 1;
938 hKernel32 = GetModuleHandle("KERNEL32");
939 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
940 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
943 static BOOL
944 attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
946 HANDLE hFindFile;
947 WIN32_FIND_DATAA FileData;
948 hFindFile = FindFirstFileA(pszFile, &FileData);
949 if (hFindFile == INVALID_HANDLE_VALUE)
950 return FALSE;
951 FindClose(hFindFile);
952 pfad->dwFileAttributes = FileData.dwFileAttributes;
953 pfad->ftCreationTime = FileData.ftCreationTime;
954 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
955 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
956 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
957 pfad->nFileSizeLow = FileData.nFileSizeLow;
958 return TRUE;
961 static BOOL
962 attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
964 HANDLE hFindFile;
965 WIN32_FIND_DATAW FileData;
966 hFindFile = FindFirstFileW(pszFile, &FileData);
967 if (hFindFile == INVALID_HANDLE_VALUE)
968 return FALSE;
969 FindClose(hFindFile);
970 pfad->dwFileAttributes = FileData.dwFileAttributes;
971 pfad->ftCreationTime = FileData.ftCreationTime;
972 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
973 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
974 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
975 pfad->nFileSizeLow = FileData.nFileSizeLow;
976 return TRUE;
979 static BOOL WINAPI
980 Py_GetFileAttributesExA(LPCSTR pszFile,
981 GET_FILEEX_INFO_LEVELS level,
982 LPVOID pv)
984 BOOL result;
985 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
986 /* First try to use the system's implementation, if that is
987 available and either succeeds to gives an error other than
988 that it isn't implemented. */
989 check_gfax();
990 if (gfaxa) {
991 result = gfaxa(pszFile, level, pv);
992 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
993 return result;
995 /* It's either not present, or not implemented.
996 Emulate using FindFirstFile. */
997 if (level != GetFileExInfoStandard) {
998 SetLastError(ERROR_INVALID_PARAMETER);
999 return FALSE;
1001 /* Use GetFileAttributes to validate that the file name
1002 does not contain wildcards (which FindFirstFile would
1003 accept). */
1004 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1005 return FALSE;
1006 return attributes_from_dir(pszFile, pfad);
1009 static BOOL WINAPI
1010 Py_GetFileAttributesExW(LPCWSTR pszFile,
1011 GET_FILEEX_INFO_LEVELS level,
1012 LPVOID pv)
1014 BOOL result;
1015 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1016 /* First try to use the system's implementation, if that is
1017 available and either succeeds to gives an error other than
1018 that it isn't implemented. */
1019 check_gfax();
1020 if (gfaxa) {
1021 result = gfaxw(pszFile, level, pv);
1022 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1023 return result;
1025 /* It's either not present, or not implemented.
1026 Emulate using FindFirstFile. */
1027 if (level != GetFileExInfoStandard) {
1028 SetLastError(ERROR_INVALID_PARAMETER);
1029 return FALSE;
1031 /* Use GetFileAttributes to validate that the file name
1032 does not contain wildcards (which FindFirstFile would
1033 accept). */
1034 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1035 return FALSE;
1036 return attributes_from_dir_w(pszFile, pfad);
1039 static int
1040 win32_stat(const char* path, struct win32_stat *result)
1042 WIN32_FILE_ATTRIBUTE_DATA info;
1043 int code;
1044 char *dot;
1045 /* XXX not supported on Win95 and NT 3.x */
1046 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1047 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1048 /* Protocol violation: we explicitly clear errno, instead of
1049 setting it to a POSIX error. Callers should use GetLastError. */
1050 errno = 0;
1051 return -1;
1052 } else {
1053 /* Could not get attributes on open file. Fall back to
1054 reading the directory. */
1055 if (!attributes_from_dir(path, &info)) {
1056 /* Very strange. This should not fail now */
1057 errno = 0;
1058 return -1;
1062 code = attribute_data_to_stat(&info, result);
1063 if (code != 0)
1064 return code;
1065 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1066 dot = strrchr(path, '.');
1067 if (dot) {
1068 if (stricmp(dot, ".bat") == 0 ||
1069 stricmp(dot, ".cmd") == 0 ||
1070 stricmp(dot, ".exe") == 0 ||
1071 stricmp(dot, ".com") == 0)
1072 result->st_mode |= 0111;
1074 return code;
1077 static int
1078 win32_wstat(const wchar_t* path, struct win32_stat *result)
1080 int code;
1081 const wchar_t *dot;
1082 WIN32_FILE_ATTRIBUTE_DATA info;
1083 /* XXX not supported on Win95 and NT 3.x */
1084 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1085 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1086 /* Protocol violation: we explicitly clear errno, instead of
1087 setting it to a POSIX error. Callers should use GetLastError. */
1088 errno = 0;
1089 return -1;
1090 } else {
1091 /* Could not get attributes on open file. Fall back to
1092 reading the directory. */
1093 if (!attributes_from_dir_w(path, &info)) {
1094 /* Very strange. This should not fail now */
1095 errno = 0;
1096 return -1;
1100 code = attribute_data_to_stat(&info, result);
1101 if (code < 0)
1102 return code;
1103 /* Set IFEXEC if it is an .exe, .bat, ... */
1104 dot = wcsrchr(path, '.');
1105 if (dot) {
1106 if (_wcsicmp(dot, L".bat") == 0 ||
1107 _wcsicmp(dot, L".cmd") == 0 ||
1108 _wcsicmp(dot, L".exe") == 0 ||
1109 _wcsicmp(dot, L".com") == 0)
1110 result->st_mode |= 0111;
1112 return code;
1115 static int
1116 win32_fstat(int file_number, struct win32_stat *result)
1118 BY_HANDLE_FILE_INFORMATION info;
1119 HANDLE h;
1120 int type;
1122 h = (HANDLE)_get_osfhandle(file_number);
1124 /* Protocol violation: we explicitly clear errno, instead of
1125 setting it to a POSIX error. Callers should use GetLastError. */
1126 errno = 0;
1128 if (h == INVALID_HANDLE_VALUE) {
1129 /* This is really a C library error (invalid file handle).
1130 We set the Win32 error to the closes one matching. */
1131 SetLastError(ERROR_INVALID_HANDLE);
1132 return -1;
1134 memset(result, 0, sizeof(*result));
1136 type = GetFileType(h);
1137 if (type == FILE_TYPE_UNKNOWN) {
1138 DWORD error = GetLastError();
1139 if (error != 0) {
1140 return -1;
1142 /* else: valid but unknown file */
1145 if (type != FILE_TYPE_DISK) {
1146 if (type == FILE_TYPE_CHAR)
1147 result->st_mode = _S_IFCHR;
1148 else if (type == FILE_TYPE_PIPE)
1149 result->st_mode = _S_IFIFO;
1150 return 0;
1153 if (!GetFileInformationByHandle(h, &info)) {
1154 return -1;
1157 /* similar to stat() */
1158 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1159 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1160 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1161 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1162 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1163 /* specific to fstat() */
1164 result->st_nlink = info.nNumberOfLinks;
1165 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1166 return 0;
1169 #endif /* MS_WINDOWS */
1171 PyDoc_STRVAR(stat_result__doc__,
1172 "stat_result: Result from stat or lstat.\n\n\
1173 This object may be accessed either as a tuple of\n\
1174 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
1175 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1177 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1178 or st_flags, they are available as attributes only.\n\
1180 See os.stat for more information.");
1182 static PyStructSequence_Field stat_result_fields[] = {
1183 {"st_mode", "protection bits"},
1184 {"st_ino", "inode"},
1185 {"st_dev", "device"},
1186 {"st_nlink", "number of hard links"},
1187 {"st_uid", "user ID of owner"},
1188 {"st_gid", "group ID of owner"},
1189 {"st_size", "total size, in bytes"},
1190 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1191 {NULL, "integer time of last access"},
1192 {NULL, "integer time of last modification"},
1193 {NULL, "integer time of last change"},
1194 {"st_atime", "time of last access"},
1195 {"st_mtime", "time of last modification"},
1196 {"st_ctime", "time of last change"},
1197 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1198 {"st_blksize", "blocksize for filesystem I/O"},
1199 #endif
1200 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1201 {"st_blocks", "number of blocks allocated"},
1202 #endif
1203 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1204 {"st_rdev", "device type (if inode device)"},
1205 #endif
1206 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1207 {"st_flags", "user defined flags for file"},
1208 #endif
1209 #ifdef HAVE_STRUCT_STAT_ST_GEN
1210 {"st_gen", "generation number"},
1211 #endif
1212 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1213 {"st_birthtime", "time of creation"},
1214 #endif
1218 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1219 #define ST_BLKSIZE_IDX 13
1220 #else
1221 #define ST_BLKSIZE_IDX 12
1222 #endif
1224 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1225 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1226 #else
1227 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1228 #endif
1230 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1231 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1232 #else
1233 #define ST_RDEV_IDX ST_BLOCKS_IDX
1234 #endif
1236 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1237 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1238 #else
1239 #define ST_FLAGS_IDX ST_RDEV_IDX
1240 #endif
1242 #ifdef HAVE_STRUCT_STAT_ST_GEN
1243 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
1244 #else
1245 #define ST_GEN_IDX ST_FLAGS_IDX
1246 #endif
1248 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1249 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1250 #else
1251 #define ST_BIRTHTIME_IDX ST_GEN_IDX
1252 #endif
1254 static PyStructSequence_Desc stat_result_desc = {
1255 "stat_result", /* name */
1256 stat_result__doc__, /* doc */
1257 stat_result_fields,
1261 PyDoc_STRVAR(statvfs_result__doc__,
1262 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
1263 This object may be accessed either as a tuple of\n\
1264 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
1265 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
1267 See os.statvfs for more information.");
1269 static PyStructSequence_Field statvfs_result_fields[] = {
1270 {"f_bsize", },
1271 {"f_frsize", },
1272 {"f_blocks", },
1273 {"f_bfree", },
1274 {"f_bavail", },
1275 {"f_files", },
1276 {"f_ffree", },
1277 {"f_favail", },
1278 {"f_flag", },
1279 {"f_namemax",},
1283 static PyStructSequence_Desc statvfs_result_desc = {
1284 "statvfs_result", /* name */
1285 statvfs_result__doc__, /* doc */
1286 statvfs_result_fields,
1290 static int initialized;
1291 static PyTypeObject StatResultType;
1292 static PyTypeObject StatVFSResultType;
1293 static newfunc structseq_new;
1295 static PyObject *
1296 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1298 PyStructSequence *result;
1299 int i;
1301 result = (PyStructSequence*)structseq_new(type, args, kwds);
1302 if (!result)
1303 return NULL;
1304 /* If we have been initialized from a tuple,
1305 st_?time might be set to None. Initialize it
1306 from the int slots. */
1307 for (i = 7; i <= 9; i++) {
1308 if (result->ob_item[i+3] == Py_None) {
1309 Py_DECREF(Py_None);
1310 Py_INCREF(result->ob_item[i]);
1311 result->ob_item[i+3] = result->ob_item[i];
1314 return (PyObject*)result;
1319 /* If true, st_?time is float. */
1320 static int _stat_float_times = 1;
1322 PyDoc_STRVAR(stat_float_times__doc__,
1323 "stat_float_times([newval]) -> oldval\n\n\
1324 Determine whether os.[lf]stat represents time stamps as float objects.\n\
1325 If newval is True, future calls to stat() return floats, if it is False,\n\
1326 future calls return ints. \n\
1327 If newval is omitted, return the current setting.\n");
1329 static PyObject*
1330 stat_float_times(PyObject* self, PyObject *args)
1332 int newval = -1;
1333 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1334 return NULL;
1335 if (newval == -1)
1336 /* Return old value */
1337 return PyBool_FromLong(_stat_float_times);
1338 _stat_float_times = newval;
1339 Py_INCREF(Py_None);
1340 return Py_None;
1343 static void
1344 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1346 PyObject *fval,*ival;
1347 #if SIZEOF_TIME_T > SIZEOF_LONG
1348 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
1349 #else
1350 ival = PyInt_FromLong((long)sec);
1351 #endif
1352 if (!ival)
1353 return;
1354 if (_stat_float_times) {
1355 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1356 } else {
1357 fval = ival;
1358 Py_INCREF(fval);
1360 PyStructSequence_SET_ITEM(v, index, ival);
1361 PyStructSequence_SET_ITEM(v, index+3, fval);
1364 /* pack a system stat C structure into the Python stat tuple
1365 (used by posix_stat() and posix_fstat()) */
1366 static PyObject*
1367 _pystat_fromstructstat(STRUCT_STAT *st)
1369 unsigned long ansec, mnsec, cnsec;
1370 PyObject *v = PyStructSequence_New(&StatResultType);
1371 if (v == NULL)
1372 return NULL;
1374 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
1375 #ifdef HAVE_LARGEFILE_SUPPORT
1376 PyStructSequence_SET_ITEM(v, 1,
1377 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
1378 #else
1379 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
1380 #endif
1381 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
1382 PyStructSequence_SET_ITEM(v, 2,
1383 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
1384 #else
1385 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
1386 #endif
1387 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1388 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1389 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
1390 #ifdef HAVE_LARGEFILE_SUPPORT
1391 PyStructSequence_SET_ITEM(v, 6,
1392 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
1393 #else
1394 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
1395 #endif
1397 #if defined(HAVE_STAT_TV_NSEC)
1398 ansec = st->st_atim.tv_nsec;
1399 mnsec = st->st_mtim.tv_nsec;
1400 cnsec = st->st_ctim.tv_nsec;
1401 #elif defined(HAVE_STAT_TV_NSEC2)
1402 ansec = st->st_atimespec.tv_nsec;
1403 mnsec = st->st_mtimespec.tv_nsec;
1404 cnsec = st->st_ctimespec.tv_nsec;
1405 #elif defined(HAVE_STAT_NSEC)
1406 ansec = st->st_atime_nsec;
1407 mnsec = st->st_mtime_nsec;
1408 cnsec = st->st_ctime_nsec;
1409 #else
1410 ansec = mnsec = cnsec = 0;
1411 #endif
1412 fill_time(v, 7, st->st_atime, ansec);
1413 fill_time(v, 8, st->st_mtime, mnsec);
1414 fill_time(v, 9, st->st_ctime, cnsec);
1416 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1417 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1418 PyInt_FromLong((long)st->st_blksize));
1419 #endif
1420 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1421 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1422 PyInt_FromLong((long)st->st_blocks));
1423 #endif
1424 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1425 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1426 PyInt_FromLong((long)st->st_rdev));
1427 #endif
1428 #ifdef HAVE_STRUCT_STAT_ST_GEN
1429 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1430 PyInt_FromLong((long)st->st_gen));
1431 #endif
1432 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1434 PyObject *val;
1435 unsigned long bsec,bnsec;
1436 bsec = (long)st->st_birthtime;
1437 #ifdef HAVE_STAT_TV_NSEC2
1438 bnsec = st->st_birthtimespec.tv_nsec;
1439 #else
1440 bnsec = 0;
1441 #endif
1442 if (_stat_float_times) {
1443 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1444 } else {
1445 val = PyInt_FromLong((long)bsec);
1447 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1448 val);
1450 #endif
1451 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1452 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1453 PyInt_FromLong((long)st->st_flags));
1454 #endif
1456 if (PyErr_Occurred()) {
1457 Py_DECREF(v);
1458 return NULL;
1461 return v;
1464 #ifdef MS_WINDOWS
1466 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1467 where / can be used in place of \ and the trailing slash is optional.
1468 Both SERVER and SHARE must have at least one character.
1471 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1472 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1473 #ifndef ARRAYSIZE
1474 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1475 #endif
1477 static BOOL
1478 IsUNCRootA(char *path, int pathlen)
1480 #define ISSLASH ISSLASHA
1482 int i, share;
1484 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1485 /* minimum UNCRoot is \\x\y */
1486 return FALSE;
1487 for (i = 2; i < pathlen ; i++)
1488 if (ISSLASH(path[i])) break;
1489 if (i == 2 || i == pathlen)
1490 /* do not allow \\\SHARE or \\SERVER */
1491 return FALSE;
1492 share = i+1;
1493 for (i = share; i < pathlen; i++)
1494 if (ISSLASH(path[i])) break;
1495 return (i != share && (i == pathlen || i == pathlen-1));
1497 #undef ISSLASH
1500 #ifdef Py_WIN_WIDE_FILENAMES
1501 static BOOL
1502 IsUNCRootW(Py_UNICODE *path, int pathlen)
1504 #define ISSLASH ISSLASHW
1506 int i, share;
1508 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1509 /* minimum UNCRoot is \\x\y */
1510 return FALSE;
1511 for (i = 2; i < pathlen ; i++)
1512 if (ISSLASH(path[i])) break;
1513 if (i == 2 || i == pathlen)
1514 /* do not allow \\\SHARE or \\SERVER */
1515 return FALSE;
1516 share = i+1;
1517 for (i = share; i < pathlen; i++)
1518 if (ISSLASH(path[i])) break;
1519 return (i != share && (i == pathlen || i == pathlen-1));
1521 #undef ISSLASH
1523 #endif /* Py_WIN_WIDE_FILENAMES */
1524 #endif /* MS_WINDOWS */
1526 static PyObject *
1527 posix_do_stat(PyObject *self, PyObject *args,
1528 char *format,
1529 #ifdef __VMS
1530 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1531 #else
1532 int (*statfunc)(const char *, STRUCT_STAT *),
1533 #endif
1534 char *wformat,
1535 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
1537 STRUCT_STAT st;
1538 char *path = NULL; /* pass this to stat; do not free() it */
1539 char *pathfree = NULL; /* this memory must be free'd */
1540 int res;
1541 PyObject *result;
1543 #ifdef Py_WIN_WIDE_FILENAMES
1544 /* If on wide-character-capable OS see if argument
1545 is Unicode and if so use wide API. */
1546 if (unicode_file_names()) {
1547 PyUnicodeObject *po;
1548 if (PyArg_ParseTuple(args, wformat, &po)) {
1549 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1551 Py_BEGIN_ALLOW_THREADS
1552 /* PyUnicode_AS_UNICODE result OK without
1553 thread lock as it is a simple dereference. */
1554 res = wstatfunc(wpath, &st);
1555 Py_END_ALLOW_THREADS
1557 if (res != 0)
1558 return win32_error_unicode("stat", wpath);
1559 return _pystat_fromstructstat(&st);
1561 /* Drop the argument parsing error as narrow strings
1562 are also valid. */
1563 PyErr_Clear();
1565 #endif
1567 if (!PyArg_ParseTuple(args, format,
1568 Py_FileSystemDefaultEncoding, &path))
1569 return NULL;
1570 pathfree = path;
1572 Py_BEGIN_ALLOW_THREADS
1573 res = (*statfunc)(path, &st);
1574 Py_END_ALLOW_THREADS
1576 if (res != 0) {
1577 #ifdef MS_WINDOWS
1578 result = win32_error("stat", pathfree);
1579 #else
1580 result = posix_error_with_filename(pathfree);
1581 #endif
1583 else
1584 result = _pystat_fromstructstat(&st);
1586 PyMem_Free(pathfree);
1587 return result;
1590 /* POSIX methods */
1592 PyDoc_STRVAR(posix_access__doc__,
1593 "access(path, mode) -> True if granted, False otherwise\n\n\
1594 Use the real uid/gid to test for access to a path. Note that most\n\
1595 operations will use the effective uid/gid, therefore this routine can\n\
1596 be used in a suid/sgid environment to test if the invoking user has the\n\
1597 specified access to the path. The mode argument can be F_OK to test\n\
1598 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1600 static PyObject *
1601 posix_access(PyObject *self, PyObject *args)
1603 char *path;
1604 int mode;
1606 #ifdef Py_WIN_WIDE_FILENAMES
1607 DWORD attr;
1608 if (unicode_file_names()) {
1609 PyUnicodeObject *po;
1610 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1611 Py_BEGIN_ALLOW_THREADS
1612 /* PyUnicode_AS_UNICODE OK without thread lock as
1613 it is a simple dereference. */
1614 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1615 Py_END_ALLOW_THREADS
1616 goto finish;
1618 /* Drop the argument parsing error as narrow strings
1619 are also valid. */
1620 PyErr_Clear();
1622 if (!PyArg_ParseTuple(args, "eti:access",
1623 Py_FileSystemDefaultEncoding, &path, &mode))
1624 return 0;
1625 Py_BEGIN_ALLOW_THREADS
1626 attr = GetFileAttributesA(path);
1627 Py_END_ALLOW_THREADS
1628 PyMem_Free(path);
1629 finish:
1630 if (attr == 0xFFFFFFFF)
1631 /* File does not exist, or cannot read attributes */
1632 return PyBool_FromLong(0);
1633 /* Access is possible if either write access wasn't requested, or
1634 the file isn't read-only, or if it's a directory, as there are
1635 no read-only directories on Windows. */
1636 return PyBool_FromLong(!(mode & 2)
1637 || !(attr & FILE_ATTRIBUTE_READONLY)
1638 || (attr & FILE_ATTRIBUTE_DIRECTORY));
1639 #else
1640 int res;
1641 if (!PyArg_ParseTuple(args, "eti:access",
1642 Py_FileSystemDefaultEncoding, &path, &mode))
1643 return NULL;
1644 Py_BEGIN_ALLOW_THREADS
1645 res = access(path, mode);
1646 Py_END_ALLOW_THREADS
1647 PyMem_Free(path);
1648 return PyBool_FromLong(res == 0);
1649 #endif
1652 #ifndef F_OK
1653 #define F_OK 0
1654 #endif
1655 #ifndef R_OK
1656 #define R_OK 4
1657 #endif
1658 #ifndef W_OK
1659 #define W_OK 2
1660 #endif
1661 #ifndef X_OK
1662 #define X_OK 1
1663 #endif
1665 #ifdef HAVE_TTYNAME
1666 PyDoc_STRVAR(posix_ttyname__doc__,
1667 "ttyname(fd) -> string\n\n\
1668 Return the name of the terminal device connected to 'fd'.");
1670 static PyObject *
1671 posix_ttyname(PyObject *self, PyObject *args)
1673 int id;
1674 char *ret;
1676 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1677 return NULL;
1679 #if defined(__VMS)
1680 /* file descriptor 0 only, the default input device (stdin) */
1681 if (id == 0) {
1682 ret = ttyname();
1684 else {
1685 ret = NULL;
1687 #else
1688 ret = ttyname(id);
1689 #endif
1690 if (ret == NULL)
1691 return posix_error();
1692 return PyString_FromString(ret);
1694 #endif
1696 #ifdef HAVE_CTERMID
1697 PyDoc_STRVAR(posix_ctermid__doc__,
1698 "ctermid() -> string\n\n\
1699 Return the name of the controlling terminal for this process.");
1701 static PyObject *
1702 posix_ctermid(PyObject *self, PyObject *noargs)
1704 char *ret;
1705 char buffer[L_ctermid];
1707 #ifdef USE_CTERMID_R
1708 ret = ctermid_r(buffer);
1709 #else
1710 ret = ctermid(buffer);
1711 #endif
1712 if (ret == NULL)
1713 return posix_error();
1714 return PyString_FromString(buffer);
1716 #endif
1718 PyDoc_STRVAR(posix_chdir__doc__,
1719 "chdir(path)\n\n\
1720 Change the current working directory to the specified path.");
1722 static PyObject *
1723 posix_chdir(PyObject *self, PyObject *args)
1725 #ifdef MS_WINDOWS
1726 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
1727 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1728 return posix_1str(args, "et:chdir", _chdir2);
1729 #elif defined(__VMS)
1730 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
1731 #else
1732 return posix_1str(args, "et:chdir", chdir);
1733 #endif
1736 #ifdef HAVE_FCHDIR
1737 PyDoc_STRVAR(posix_fchdir__doc__,
1738 "fchdir(fildes)\n\n\
1739 Change to the directory of the given file descriptor. fildes must be\n\
1740 opened on a directory, not a file.");
1742 static PyObject *
1743 posix_fchdir(PyObject *self, PyObject *fdobj)
1745 return posix_fildes(fdobj, fchdir);
1747 #endif /* HAVE_FCHDIR */
1750 PyDoc_STRVAR(posix_chmod__doc__,
1751 "chmod(path, mode)\n\n\
1752 Change the access permissions of a file.");
1754 static PyObject *
1755 posix_chmod(PyObject *self, PyObject *args)
1757 char *path = NULL;
1758 int i;
1759 int res;
1760 #ifdef Py_WIN_WIDE_FILENAMES
1761 DWORD attr;
1762 if (unicode_file_names()) {
1763 PyUnicodeObject *po;
1764 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1765 Py_BEGIN_ALLOW_THREADS
1766 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1767 if (attr != 0xFFFFFFFF) {
1768 if (i & _S_IWRITE)
1769 attr &= ~FILE_ATTRIBUTE_READONLY;
1770 else
1771 attr |= FILE_ATTRIBUTE_READONLY;
1772 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1774 else
1775 res = 0;
1776 Py_END_ALLOW_THREADS
1777 if (!res)
1778 return win32_error_unicode("chmod",
1779 PyUnicode_AS_UNICODE(po));
1780 Py_INCREF(Py_None);
1781 return Py_None;
1783 /* Drop the argument parsing error as narrow strings
1784 are also valid. */
1785 PyErr_Clear();
1787 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1788 &path, &i))
1789 return NULL;
1790 Py_BEGIN_ALLOW_THREADS
1791 attr = GetFileAttributesA(path);
1792 if (attr != 0xFFFFFFFF) {
1793 if (i & _S_IWRITE)
1794 attr &= ~FILE_ATTRIBUTE_READONLY;
1795 else
1796 attr |= FILE_ATTRIBUTE_READONLY;
1797 res = SetFileAttributesA(path, attr);
1799 else
1800 res = 0;
1801 Py_END_ALLOW_THREADS
1802 if (!res) {
1803 win32_error("chmod", path);
1804 PyMem_Free(path);
1805 return NULL;
1807 PyMem_Free(path);
1808 Py_INCREF(Py_None);
1809 return Py_None;
1810 #else /* Py_WIN_WIDE_FILENAMES */
1811 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1812 &path, &i))
1813 return NULL;
1814 Py_BEGIN_ALLOW_THREADS
1815 res = chmod(path, i);
1816 Py_END_ALLOW_THREADS
1817 if (res < 0)
1818 return posix_error_with_allocated_filename(path);
1819 PyMem_Free(path);
1820 Py_INCREF(Py_None);
1821 return Py_None;
1822 #endif
1825 #ifdef HAVE_FCHMOD
1826 PyDoc_STRVAR(posix_fchmod__doc__,
1827 "fchmod(fd, mode)\n\n\
1828 Change the access permissions of the file given by file\n\
1829 descriptor fd.");
1831 static PyObject *
1832 posix_fchmod(PyObject *self, PyObject *args)
1834 int fd, mode, res;
1835 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1836 return NULL;
1837 Py_BEGIN_ALLOW_THREADS
1838 res = fchmod(fd, mode);
1839 Py_END_ALLOW_THREADS
1840 if (res < 0)
1841 return posix_error();
1842 Py_RETURN_NONE;
1844 #endif /* HAVE_FCHMOD */
1846 #ifdef HAVE_LCHMOD
1847 PyDoc_STRVAR(posix_lchmod__doc__,
1848 "lchmod(path, mode)\n\n\
1849 Change the access permissions of a file. If path is a symlink, this\n\
1850 affects the link itself rather than the target.");
1852 static PyObject *
1853 posix_lchmod(PyObject *self, PyObject *args)
1855 char *path = NULL;
1856 int i;
1857 int res;
1858 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1859 &path, &i))
1860 return NULL;
1861 Py_BEGIN_ALLOW_THREADS
1862 res = lchmod(path, i);
1863 Py_END_ALLOW_THREADS
1864 if (res < 0)
1865 return posix_error_with_allocated_filename(path);
1866 PyMem_Free(path);
1867 Py_RETURN_NONE;
1869 #endif /* HAVE_LCHMOD */
1872 #ifdef HAVE_CHFLAGS
1873 PyDoc_STRVAR(posix_chflags__doc__,
1874 "chflags(path, flags)\n\n\
1875 Set file flags.");
1877 static PyObject *
1878 posix_chflags(PyObject *self, PyObject *args)
1880 char *path;
1881 unsigned long flags;
1882 int res;
1883 if (!PyArg_ParseTuple(args, "etk:chflags",
1884 Py_FileSystemDefaultEncoding, &path, &flags))
1885 return NULL;
1886 Py_BEGIN_ALLOW_THREADS
1887 res = chflags(path, flags);
1888 Py_END_ALLOW_THREADS
1889 if (res < 0)
1890 return posix_error_with_allocated_filename(path);
1891 PyMem_Free(path);
1892 Py_INCREF(Py_None);
1893 return Py_None;
1895 #endif /* HAVE_CHFLAGS */
1897 #ifdef HAVE_LCHFLAGS
1898 PyDoc_STRVAR(posix_lchflags__doc__,
1899 "lchflags(path, flags)\n\n\
1900 Set file flags.\n\
1901 This function will not follow symbolic links.");
1903 static PyObject *
1904 posix_lchflags(PyObject *self, PyObject *args)
1906 char *path;
1907 unsigned long flags;
1908 int res;
1909 if (!PyArg_ParseTuple(args, "etk:lchflags",
1910 Py_FileSystemDefaultEncoding, &path, &flags))
1911 return NULL;
1912 Py_BEGIN_ALLOW_THREADS
1913 res = lchflags(path, flags);
1914 Py_END_ALLOW_THREADS
1915 if (res < 0)
1916 return posix_error_with_allocated_filename(path);
1917 PyMem_Free(path);
1918 Py_INCREF(Py_None);
1919 return Py_None;
1921 #endif /* HAVE_LCHFLAGS */
1923 #ifdef HAVE_CHROOT
1924 PyDoc_STRVAR(posix_chroot__doc__,
1925 "chroot(path)\n\n\
1926 Change root directory to path.");
1928 static PyObject *
1929 posix_chroot(PyObject *self, PyObject *args)
1931 return posix_1str(args, "et:chroot", chroot);
1933 #endif
1935 #ifdef HAVE_FSYNC
1936 PyDoc_STRVAR(posix_fsync__doc__,
1937 "fsync(fildes)\n\n\
1938 force write of file with filedescriptor to disk.");
1940 static PyObject *
1941 posix_fsync(PyObject *self, PyObject *fdobj)
1943 return posix_fildes(fdobj, fsync);
1945 #endif /* HAVE_FSYNC */
1947 #ifdef HAVE_FDATASYNC
1949 #ifdef __hpux
1950 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1951 #endif
1953 PyDoc_STRVAR(posix_fdatasync__doc__,
1954 "fdatasync(fildes)\n\n\
1955 force write of file with filedescriptor to disk.\n\
1956 does not force update of metadata.");
1958 static PyObject *
1959 posix_fdatasync(PyObject *self, PyObject *fdobj)
1961 return posix_fildes(fdobj, fdatasync);
1963 #endif /* HAVE_FDATASYNC */
1966 #ifdef HAVE_CHOWN
1967 PyDoc_STRVAR(posix_chown__doc__,
1968 "chown(path, uid, gid)\n\n\
1969 Change the owner and group id of path to the numeric uid and gid.");
1971 static PyObject *
1972 posix_chown(PyObject *self, PyObject *args)
1974 char *path = NULL;
1975 long uid, gid;
1976 int res;
1977 if (!PyArg_ParseTuple(args, "etll:chown",
1978 Py_FileSystemDefaultEncoding, &path,
1979 &uid, &gid))
1980 return NULL;
1981 Py_BEGIN_ALLOW_THREADS
1982 res = chown(path, (uid_t) uid, (gid_t) gid);
1983 Py_END_ALLOW_THREADS
1984 if (res < 0)
1985 return posix_error_with_allocated_filename(path);
1986 PyMem_Free(path);
1987 Py_INCREF(Py_None);
1988 return Py_None;
1990 #endif /* HAVE_CHOWN */
1992 #ifdef HAVE_FCHOWN
1993 PyDoc_STRVAR(posix_fchown__doc__,
1994 "fchown(fd, uid, gid)\n\n\
1995 Change the owner and group id of the file given by file descriptor\n\
1996 fd to the numeric uid and gid.");
1998 static PyObject *
1999 posix_fchown(PyObject *self, PyObject *args)
2001 int fd, uid, gid;
2002 int res;
2003 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
2004 return NULL;
2005 Py_BEGIN_ALLOW_THREADS
2006 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2007 Py_END_ALLOW_THREADS
2008 if (res < 0)
2009 return posix_error();
2010 Py_RETURN_NONE;
2012 #endif /* HAVE_FCHOWN */
2014 #ifdef HAVE_LCHOWN
2015 PyDoc_STRVAR(posix_lchown__doc__,
2016 "lchown(path, uid, gid)\n\n\
2017 Change the owner and group id of path to the numeric uid and gid.\n\
2018 This function will not follow symbolic links.");
2020 static PyObject *
2021 posix_lchown(PyObject *self, PyObject *args)
2023 char *path = NULL;
2024 int uid, gid;
2025 int res;
2026 if (!PyArg_ParseTuple(args, "etii:lchown",
2027 Py_FileSystemDefaultEncoding, &path,
2028 &uid, &gid))
2029 return NULL;
2030 Py_BEGIN_ALLOW_THREADS
2031 res = lchown(path, (uid_t) uid, (gid_t) gid);
2032 Py_END_ALLOW_THREADS
2033 if (res < 0)
2034 return posix_error_with_allocated_filename(path);
2035 PyMem_Free(path);
2036 Py_INCREF(Py_None);
2037 return Py_None;
2039 #endif /* HAVE_LCHOWN */
2042 #ifdef HAVE_GETCWD
2043 PyDoc_STRVAR(posix_getcwd__doc__,
2044 "getcwd() -> path\n\n\
2045 Return a string representing the current working directory.");
2047 static PyObject *
2048 posix_getcwd(PyObject *self, PyObject *noargs)
2050 int bufsize_incr = 1024;
2051 int bufsize = 0;
2052 char *tmpbuf = NULL;
2053 char *res = NULL;
2054 PyObject *dynamic_return;
2056 Py_BEGIN_ALLOW_THREADS
2057 do {
2058 bufsize = bufsize + bufsize_incr;
2059 tmpbuf = malloc(bufsize);
2060 if (tmpbuf == NULL) {
2061 break;
2063 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2064 res = _getcwd2(tmpbuf, bufsize);
2065 #else
2066 res = getcwd(tmpbuf, bufsize);
2067 #endif
2069 if (res == NULL) {
2070 free(tmpbuf);
2072 } while ((res == NULL) && (errno == ERANGE));
2073 Py_END_ALLOW_THREADS
2075 if (res == NULL)
2076 return posix_error();
2078 dynamic_return = PyString_FromString(tmpbuf);
2079 free(tmpbuf);
2081 return dynamic_return;
2084 #ifdef Py_USING_UNICODE
2085 PyDoc_STRVAR(posix_getcwdu__doc__,
2086 "getcwdu() -> path\n\n\
2087 Return a unicode string representing the current working directory.");
2089 static PyObject *
2090 posix_getcwdu(PyObject *self, PyObject *noargs)
2092 char buf[1026];
2093 char *res;
2095 #ifdef Py_WIN_WIDE_FILENAMES
2096 DWORD len;
2097 if (unicode_file_names()) {
2098 wchar_t wbuf[1026];
2099 wchar_t *wbuf2 = wbuf;
2100 PyObject *resobj;
2101 Py_BEGIN_ALLOW_THREADS
2102 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2103 /* If the buffer is large enough, len does not include the
2104 terminating \0. If the buffer is too small, len includes
2105 the space needed for the terminator. */
2106 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2107 wbuf2 = malloc(len * sizeof(wchar_t));
2108 if (wbuf2)
2109 len = GetCurrentDirectoryW(len, wbuf2);
2111 Py_END_ALLOW_THREADS
2112 if (!wbuf2) {
2113 PyErr_NoMemory();
2114 return NULL;
2116 if (!len) {
2117 if (wbuf2 != wbuf) free(wbuf2);
2118 return win32_error("getcwdu", NULL);
2120 resobj = PyUnicode_FromWideChar(wbuf2, len);
2121 if (wbuf2 != wbuf) free(wbuf2);
2122 return resobj;
2124 #endif
2126 Py_BEGIN_ALLOW_THREADS
2127 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2128 res = _getcwd2(buf, sizeof buf);
2129 #else
2130 res = getcwd(buf, sizeof buf);
2131 #endif
2132 Py_END_ALLOW_THREADS
2133 if (res == NULL)
2134 return posix_error();
2135 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2137 #endif
2138 #endif
2141 #ifdef HAVE_LINK
2142 PyDoc_STRVAR(posix_link__doc__,
2143 "link(src, dst)\n\n\
2144 Create a hard link to a file.");
2146 static PyObject *
2147 posix_link(PyObject *self, PyObject *args)
2149 return posix_2str(args, "etet:link", link);
2151 #endif /* HAVE_LINK */
2154 PyDoc_STRVAR(posix_listdir__doc__,
2155 "listdir(path) -> list_of_strings\n\n\
2156 Return a list containing the names of the entries in the directory.\n\
2158 path: path of directory to list\n\
2160 The list is in arbitrary order. It does not include the special\n\
2161 entries '.' and '..' even if they are present in the directory.");
2163 static PyObject *
2164 posix_listdir(PyObject *self, PyObject *args)
2166 /* XXX Should redo this putting the (now four) versions of opendir
2167 in separate files instead of having them all here... */
2168 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
2170 PyObject *d, *v;
2171 HANDLE hFindFile;
2172 BOOL result;
2173 WIN32_FIND_DATA FileData;
2174 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2175 char *bufptr = namebuf;
2176 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
2178 #ifdef Py_WIN_WIDE_FILENAMES
2179 /* If on wide-character-capable OS see if argument
2180 is Unicode and if so use wide API. */
2181 if (unicode_file_names()) {
2182 PyObject *po;
2183 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2184 WIN32_FIND_DATAW wFileData;
2185 Py_UNICODE *wnamebuf;
2186 Py_UNICODE wch;
2187 /* Overallocate for \\*.*\0 */
2188 len = PyUnicode_GET_SIZE(po);
2189 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2190 if (!wnamebuf) {
2191 PyErr_NoMemory();
2192 return NULL;
2194 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2195 wch = len > 0 ? wnamebuf[len-1] : '\0';
2196 if (wch != L'/' && wch != L'\\' && wch != L':')
2197 wnamebuf[len++] = L'\\';
2198 wcscpy(wnamebuf + len, L"*.*");
2199 if ((d = PyList_New(0)) == NULL) {
2200 free(wnamebuf);
2201 return NULL;
2203 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2204 if (hFindFile == INVALID_HANDLE_VALUE) {
2205 int error = GetLastError();
2206 if (error == ERROR_FILE_NOT_FOUND) {
2207 free(wnamebuf);
2208 return d;
2210 Py_DECREF(d);
2211 win32_error_unicode("FindFirstFileW", wnamebuf);
2212 free(wnamebuf);
2213 return NULL;
2215 do {
2216 /* Skip over . and .. */
2217 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2218 wcscmp(wFileData.cFileName, L"..") != 0) {
2219 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2220 if (v == NULL) {
2221 Py_DECREF(d);
2222 d = NULL;
2223 break;
2225 if (PyList_Append(d, v) != 0) {
2226 Py_DECREF(v);
2227 Py_DECREF(d);
2228 d = NULL;
2229 break;
2231 Py_DECREF(v);
2233 Py_BEGIN_ALLOW_THREADS
2234 result = FindNextFileW(hFindFile, &wFileData);
2235 Py_END_ALLOW_THREADS
2236 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2237 it got to the end of the directory. */
2238 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2239 Py_DECREF(d);
2240 win32_error_unicode("FindNextFileW", wnamebuf);
2241 FindClose(hFindFile);
2242 free(wnamebuf);
2243 return NULL;
2245 } while (result == TRUE);
2247 if (FindClose(hFindFile) == FALSE) {
2248 Py_DECREF(d);
2249 win32_error_unicode("FindClose", wnamebuf);
2250 free(wnamebuf);
2251 return NULL;
2253 free(wnamebuf);
2254 return d;
2256 /* Drop the argument parsing error as narrow strings
2257 are also valid. */
2258 PyErr_Clear();
2260 #endif
2262 if (!PyArg_ParseTuple(args, "et#:listdir",
2263 Py_FileSystemDefaultEncoding, &bufptr, &len))
2264 return NULL;
2265 if (len > 0) {
2266 char ch = namebuf[len-1];
2267 if (ch != SEP && ch != ALTSEP && ch != ':')
2268 namebuf[len++] = '/';
2270 strcpy(namebuf + len, "*.*");
2272 if ((d = PyList_New(0)) == NULL)
2273 return NULL;
2275 hFindFile = FindFirstFile(namebuf, &FileData);
2276 if (hFindFile == INVALID_HANDLE_VALUE) {
2277 int error = GetLastError();
2278 if (error == ERROR_FILE_NOT_FOUND)
2279 return d;
2280 Py_DECREF(d);
2281 return win32_error("FindFirstFile", namebuf);
2283 do {
2284 /* Skip over . and .. */
2285 if (strcmp(FileData.cFileName, ".") != 0 &&
2286 strcmp(FileData.cFileName, "..") != 0) {
2287 v = PyString_FromString(FileData.cFileName);
2288 if (v == NULL) {
2289 Py_DECREF(d);
2290 d = NULL;
2291 break;
2293 if (PyList_Append(d, v) != 0) {
2294 Py_DECREF(v);
2295 Py_DECREF(d);
2296 d = NULL;
2297 break;
2299 Py_DECREF(v);
2301 Py_BEGIN_ALLOW_THREADS
2302 result = FindNextFile(hFindFile, &FileData);
2303 Py_END_ALLOW_THREADS
2304 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2305 it got to the end of the directory. */
2306 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2307 Py_DECREF(d);
2308 win32_error("FindNextFile", namebuf);
2309 FindClose(hFindFile);
2310 return NULL;
2312 } while (result == TRUE);
2314 if (FindClose(hFindFile) == FALSE) {
2315 Py_DECREF(d);
2316 return win32_error("FindClose", namebuf);
2319 return d;
2321 #elif defined(PYOS_OS2)
2323 #ifndef MAX_PATH
2324 #define MAX_PATH CCHMAXPATH
2325 #endif
2326 char *name, *pt;
2327 Py_ssize_t len;
2328 PyObject *d, *v;
2329 char namebuf[MAX_PATH+5];
2330 HDIR hdir = 1;
2331 ULONG srchcnt = 1;
2332 FILEFINDBUF3 ep;
2333 APIRET rc;
2335 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
2336 return NULL;
2337 if (len >= MAX_PATH) {
2338 PyErr_SetString(PyExc_ValueError, "path too long");
2339 return NULL;
2341 strcpy(namebuf, name);
2342 for (pt = namebuf; *pt; pt++)
2343 if (*pt == ALTSEP)
2344 *pt = SEP;
2345 if (namebuf[len-1] != SEP)
2346 namebuf[len++] = SEP;
2347 strcpy(namebuf + len, "*.*");
2349 if ((d = PyList_New(0)) == NULL)
2350 return NULL;
2352 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2353 &hdir, /* Handle to Use While Search Directory */
2354 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
2355 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2356 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2357 FIL_STANDARD); /* Format of Entry (EAs or Not) */
2359 if (rc != NO_ERROR) {
2360 errno = ENOENT;
2361 return posix_error_with_filename(name);
2364 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
2365 do {
2366 if (ep.achName[0] == '.'
2367 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
2368 continue; /* Skip Over "." and ".." Names */
2370 strcpy(namebuf, ep.achName);
2372 /* Leave Case of Name Alone -- In Native Form */
2373 /* (Removed Forced Lowercasing Code) */
2375 v = PyString_FromString(namebuf);
2376 if (v == NULL) {
2377 Py_DECREF(d);
2378 d = NULL;
2379 break;
2381 if (PyList_Append(d, v) != 0) {
2382 Py_DECREF(v);
2383 Py_DECREF(d);
2384 d = NULL;
2385 break;
2387 Py_DECREF(v);
2388 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2391 return d;
2392 #else
2394 char *name = NULL;
2395 PyObject *d, *v;
2396 DIR *dirp;
2397 struct dirent *ep;
2398 int arg_is_unicode = 1;
2400 errno = 0;
2401 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2402 arg_is_unicode = 0;
2403 PyErr_Clear();
2405 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2406 return NULL;
2407 if ((dirp = opendir(name)) == NULL) {
2408 return posix_error_with_allocated_filename(name);
2410 if ((d = PyList_New(0)) == NULL) {
2411 closedir(dirp);
2412 PyMem_Free(name);
2413 return NULL;
2415 for (;;) {
2416 errno = 0;
2417 Py_BEGIN_ALLOW_THREADS
2418 ep = readdir(dirp);
2419 Py_END_ALLOW_THREADS
2420 if (ep == NULL) {
2421 if (errno == 0) {
2422 break;
2423 } else {
2424 closedir(dirp);
2425 Py_DECREF(d);
2426 return posix_error_with_allocated_filename(name);
2429 if (ep->d_name[0] == '.' &&
2430 (NAMLEN(ep) == 1 ||
2431 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2432 continue;
2433 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2434 if (v == NULL) {
2435 Py_DECREF(d);
2436 d = NULL;
2437 break;
2439 #ifdef Py_USING_UNICODE
2440 if (arg_is_unicode) {
2441 PyObject *w;
2443 w = PyUnicode_FromEncodedObject(v,
2444 Py_FileSystemDefaultEncoding,
2445 "strict");
2446 if (w != NULL) {
2447 Py_DECREF(v);
2448 v = w;
2450 else {
2451 /* fall back to the original byte string, as
2452 discussed in patch #683592 */
2453 PyErr_Clear();
2456 #endif
2457 if (PyList_Append(d, v) != 0) {
2458 Py_DECREF(v);
2459 Py_DECREF(d);
2460 d = NULL;
2461 break;
2463 Py_DECREF(v);
2465 closedir(dirp);
2466 PyMem_Free(name);
2468 return d;
2470 #endif /* which OS */
2471 } /* end of posix_listdir */
2473 #ifdef MS_WINDOWS
2474 /* A helper function for abspath on win32 */
2475 static PyObject *
2476 posix__getfullpathname(PyObject *self, PyObject *args)
2478 /* assume encoded strings won't more than double no of chars */
2479 char inbuf[MAX_PATH*2];
2480 char *inbufp = inbuf;
2481 Py_ssize_t insize = sizeof(inbuf);
2482 char outbuf[MAX_PATH*2];
2483 char *temp;
2484 #ifdef Py_WIN_WIDE_FILENAMES
2485 if (unicode_file_names()) {
2486 PyUnicodeObject *po;
2487 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2488 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2489 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2490 Py_UNICODE *wtemp;
2491 DWORD result;
2492 PyObject *v;
2493 result = GetFullPathNameW(wpath,
2494 sizeof(woutbuf)/sizeof(woutbuf[0]),
2495 woutbuf, &wtemp);
2496 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2497 woutbufp = malloc(result * sizeof(Py_UNICODE));
2498 if (!woutbufp)
2499 return PyErr_NoMemory();
2500 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2502 if (result)
2503 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2504 else
2505 v = win32_error_unicode("GetFullPathNameW", wpath);
2506 if (woutbufp != woutbuf)
2507 free(woutbufp);
2508 return v;
2510 /* Drop the argument parsing error as narrow strings
2511 are also valid. */
2512 PyErr_Clear();
2514 #endif
2515 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2516 Py_FileSystemDefaultEncoding, &inbufp,
2517 &insize))
2518 return NULL;
2519 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2520 outbuf, &temp))
2521 return win32_error("GetFullPathName", inbuf);
2522 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2523 return PyUnicode_Decode(outbuf, strlen(outbuf),
2524 Py_FileSystemDefaultEncoding, NULL);
2526 return PyString_FromString(outbuf);
2527 } /* end of posix__getfullpathname */
2528 #endif /* MS_WINDOWS */
2530 PyDoc_STRVAR(posix_mkdir__doc__,
2531 "mkdir(path [, mode=0777])\n\n\
2532 Create a directory.");
2534 static PyObject *
2535 posix_mkdir(PyObject *self, PyObject *args)
2537 int res;
2538 char *path = NULL;
2539 int mode = 0777;
2541 #ifdef Py_WIN_WIDE_FILENAMES
2542 if (unicode_file_names()) {
2543 PyUnicodeObject *po;
2544 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2545 Py_BEGIN_ALLOW_THREADS
2546 /* PyUnicode_AS_UNICODE OK without thread lock as
2547 it is a simple dereference. */
2548 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2549 Py_END_ALLOW_THREADS
2550 if (!res)
2551 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2552 Py_INCREF(Py_None);
2553 return Py_None;
2555 /* Drop the argument parsing error as narrow strings
2556 are also valid. */
2557 PyErr_Clear();
2559 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2560 Py_FileSystemDefaultEncoding, &path, &mode))
2561 return NULL;
2562 Py_BEGIN_ALLOW_THREADS
2563 /* PyUnicode_AS_UNICODE OK without thread lock as
2564 it is a simple dereference. */
2565 res = CreateDirectoryA(path, NULL);
2566 Py_END_ALLOW_THREADS
2567 if (!res) {
2568 win32_error("mkdir", path);
2569 PyMem_Free(path);
2570 return NULL;
2572 PyMem_Free(path);
2573 Py_INCREF(Py_None);
2574 return Py_None;
2575 #else
2577 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2578 Py_FileSystemDefaultEncoding, &path, &mode))
2579 return NULL;
2580 Py_BEGIN_ALLOW_THREADS
2581 #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
2582 res = mkdir(path);
2583 #else
2584 res = mkdir(path, mode);
2585 #endif
2586 Py_END_ALLOW_THREADS
2587 if (res < 0)
2588 return posix_error_with_allocated_filename(path);
2589 PyMem_Free(path);
2590 Py_INCREF(Py_None);
2591 return Py_None;
2592 #endif
2596 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2597 #if defined(HAVE_SYS_RESOURCE_H)
2598 #include <sys/resource.h>
2599 #endif
2602 #ifdef HAVE_NICE
2603 PyDoc_STRVAR(posix_nice__doc__,
2604 "nice(inc) -> new_priority\n\n\
2605 Decrease the priority of process by inc and return the new priority.");
2607 static PyObject *
2608 posix_nice(PyObject *self, PyObject *args)
2610 int increment, value;
2612 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2613 return NULL;
2615 /* There are two flavours of 'nice': one that returns the new
2616 priority (as required by almost all standards out there) and the
2617 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2618 the use of getpriority() to get the new priority.
2620 If we are of the nice family that returns the new priority, we
2621 need to clear errno before the call, and check if errno is filled
2622 before calling posix_error() on a returnvalue of -1, because the
2623 -1 may be the actual new priority! */
2625 errno = 0;
2626 value = nice(increment);
2627 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
2628 if (value == 0)
2629 value = getpriority(PRIO_PROCESS, 0);
2630 #endif
2631 if (value == -1 && errno != 0)
2632 /* either nice() or getpriority() returned an error */
2633 return posix_error();
2634 return PyInt_FromLong((long) value);
2636 #endif /* HAVE_NICE */
2638 PyDoc_STRVAR(posix_rename__doc__,
2639 "rename(old, new)\n\n\
2640 Rename a file or directory.");
2642 static PyObject *
2643 posix_rename(PyObject *self, PyObject *args)
2645 #ifdef MS_WINDOWS
2646 PyObject *o1, *o2;
2647 char *p1, *p2;
2648 BOOL result;
2649 if (unicode_file_names()) {
2650 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2651 goto error;
2652 if (!convert_to_unicode(&o1))
2653 goto error;
2654 if (!convert_to_unicode(&o2)) {
2655 Py_DECREF(o1);
2656 goto error;
2658 Py_BEGIN_ALLOW_THREADS
2659 result = MoveFileW(PyUnicode_AsUnicode(o1),
2660 PyUnicode_AsUnicode(o2));
2661 Py_END_ALLOW_THREADS
2662 Py_DECREF(o1);
2663 Py_DECREF(o2);
2664 if (!result)
2665 return win32_error("rename", NULL);
2666 Py_INCREF(Py_None);
2667 return Py_None;
2668 error:
2669 PyErr_Clear();
2671 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2672 return NULL;
2673 Py_BEGIN_ALLOW_THREADS
2674 result = MoveFileA(p1, p2);
2675 Py_END_ALLOW_THREADS
2676 if (!result)
2677 return win32_error("rename", NULL);
2678 Py_INCREF(Py_None);
2679 return Py_None;
2680 #else
2681 return posix_2str(args, "etet:rename", rename);
2682 #endif
2686 PyDoc_STRVAR(posix_rmdir__doc__,
2687 "rmdir(path)\n\n\
2688 Remove a directory.");
2690 static PyObject *
2691 posix_rmdir(PyObject *self, PyObject *args)
2693 #ifdef MS_WINDOWS
2694 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
2695 #else
2696 return posix_1str(args, "et:rmdir", rmdir);
2697 #endif
2701 PyDoc_STRVAR(posix_stat__doc__,
2702 "stat(path) -> stat result\n\n\
2703 Perform a stat system call on the given path.");
2705 static PyObject *
2706 posix_stat(PyObject *self, PyObject *args)
2708 #ifdef MS_WINDOWS
2709 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
2710 #else
2711 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2712 #endif
2716 #ifdef HAVE_SYSTEM
2717 PyDoc_STRVAR(posix_system__doc__,
2718 "system(command) -> exit_status\n\n\
2719 Execute the command (a string) in a subshell.");
2721 static PyObject *
2722 posix_system(PyObject *self, PyObject *args)
2724 char *command;
2725 long sts;
2726 if (!PyArg_ParseTuple(args, "s:system", &command))
2727 return NULL;
2728 Py_BEGIN_ALLOW_THREADS
2729 sts = system(command);
2730 Py_END_ALLOW_THREADS
2731 return PyInt_FromLong(sts);
2733 #endif
2736 PyDoc_STRVAR(posix_umask__doc__,
2737 "umask(new_mask) -> old_mask\n\n\
2738 Set the current numeric umask and return the previous umask.");
2740 static PyObject *
2741 posix_umask(PyObject *self, PyObject *args)
2743 int i;
2744 if (!PyArg_ParseTuple(args, "i:umask", &i))
2745 return NULL;
2746 i = (int)umask(i);
2747 if (i < 0)
2748 return posix_error();
2749 return PyInt_FromLong((long)i);
2753 PyDoc_STRVAR(posix_unlink__doc__,
2754 "unlink(path)\n\n\
2755 Remove a file (same as remove(path)).");
2757 PyDoc_STRVAR(posix_remove__doc__,
2758 "remove(path)\n\n\
2759 Remove a file (same as unlink(path)).");
2761 static PyObject *
2762 posix_unlink(PyObject *self, PyObject *args)
2764 #ifdef MS_WINDOWS
2765 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
2766 #else
2767 return posix_1str(args, "et:remove", unlink);
2768 #endif
2772 #ifdef HAVE_UNAME
2773 PyDoc_STRVAR(posix_uname__doc__,
2774 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2775 Return a tuple identifying the current operating system.");
2777 static PyObject *
2778 posix_uname(PyObject *self, PyObject *noargs)
2780 struct utsname u;
2781 int res;
2783 Py_BEGIN_ALLOW_THREADS
2784 res = uname(&u);
2785 Py_END_ALLOW_THREADS
2786 if (res < 0)
2787 return posix_error();
2788 return Py_BuildValue("(sssss)",
2789 u.sysname,
2790 u.nodename,
2791 u.release,
2792 u.version,
2793 u.machine);
2795 #endif /* HAVE_UNAME */
2797 static int
2798 extract_time(PyObject *t, long* sec, long* usec)
2800 long intval;
2801 if (PyFloat_Check(t)) {
2802 double tval = PyFloat_AsDouble(t);
2803 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
2804 if (!intobj)
2805 return -1;
2806 intval = PyInt_AsLong(intobj);
2807 Py_DECREF(intobj);
2808 if (intval == -1 && PyErr_Occurred())
2809 return -1;
2810 *sec = intval;
2811 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2812 if (*usec < 0)
2813 /* If rounding gave us a negative number,
2814 truncate. */
2815 *usec = 0;
2816 return 0;
2818 intval = PyInt_AsLong(t);
2819 if (intval == -1 && PyErr_Occurred())
2820 return -1;
2821 *sec = intval;
2822 *usec = 0;
2823 return 0;
2826 PyDoc_STRVAR(posix_utime__doc__,
2827 "utime(path, (atime, mtime))\n\
2828 utime(path, None)\n\n\
2829 Set the access and modified time of the file to the given values. If the\n\
2830 second form is used, set the access and modified times to the current time.");
2832 static PyObject *
2833 posix_utime(PyObject *self, PyObject *args)
2835 #ifdef Py_WIN_WIDE_FILENAMES
2836 PyObject *arg;
2837 PyUnicodeObject *obwpath;
2838 wchar_t *wpath = NULL;
2839 char *apath = NULL;
2840 HANDLE hFile;
2841 long atimesec, mtimesec, ausec, musec;
2842 FILETIME atime, mtime;
2843 PyObject *result = NULL;
2845 if (unicode_file_names()) {
2846 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2847 wpath = PyUnicode_AS_UNICODE(obwpath);
2848 Py_BEGIN_ALLOW_THREADS
2849 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2850 NULL, OPEN_EXISTING,
2851 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2852 Py_END_ALLOW_THREADS
2853 if (hFile == INVALID_HANDLE_VALUE)
2854 return win32_error_unicode("utime", wpath);
2855 } else
2856 /* Drop the argument parsing error as narrow strings
2857 are also valid. */
2858 PyErr_Clear();
2860 if (!wpath) {
2861 if (!PyArg_ParseTuple(args, "etO:utime",
2862 Py_FileSystemDefaultEncoding, &apath, &arg))
2863 return NULL;
2864 Py_BEGIN_ALLOW_THREADS
2865 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2866 NULL, OPEN_EXISTING,
2867 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2868 Py_END_ALLOW_THREADS
2869 if (hFile == INVALID_HANDLE_VALUE) {
2870 win32_error("utime", apath);
2871 PyMem_Free(apath);
2872 return NULL;
2874 PyMem_Free(apath);
2877 if (arg == Py_None) {
2878 SYSTEMTIME now;
2879 GetSystemTime(&now);
2880 if (!SystemTimeToFileTime(&now, &mtime) ||
2881 !SystemTimeToFileTime(&now, &atime)) {
2882 win32_error("utime", NULL);
2883 goto done;
2886 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2887 PyErr_SetString(PyExc_TypeError,
2888 "utime() arg 2 must be a tuple (atime, mtime)");
2889 goto done;
2891 else {
2892 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2893 &atimesec, &ausec) == -1)
2894 goto done;
2895 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
2896 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2897 &mtimesec, &musec) == -1)
2898 goto done;
2899 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
2901 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2902 /* Avoid putting the file name into the error here,
2903 as that may confuse the user into believing that
2904 something is wrong with the file, when it also
2905 could be the time stamp that gives a problem. */
2906 win32_error("utime", NULL);
2908 Py_INCREF(Py_None);
2909 result = Py_None;
2910 done:
2911 CloseHandle(hFile);
2912 return result;
2913 #else /* Py_WIN_WIDE_FILENAMES */
2915 char *path = NULL;
2916 long atime, mtime, ausec, musec;
2917 int res;
2918 PyObject* arg;
2920 #if defined(HAVE_UTIMES)
2921 struct timeval buf[2];
2922 #define ATIME buf[0].tv_sec
2923 #define MTIME buf[1].tv_sec
2924 #elif defined(HAVE_UTIME_H)
2925 /* XXX should define struct utimbuf instead, above */
2926 struct utimbuf buf;
2927 #define ATIME buf.actime
2928 #define MTIME buf.modtime
2929 #define UTIME_ARG &buf
2930 #else /* HAVE_UTIMES */
2931 time_t buf[2];
2932 #define ATIME buf[0]
2933 #define MTIME buf[1]
2934 #define UTIME_ARG buf
2935 #endif /* HAVE_UTIMES */
2938 if (!PyArg_ParseTuple(args, "etO:utime",
2939 Py_FileSystemDefaultEncoding, &path, &arg))
2940 return NULL;
2941 if (arg == Py_None) {
2942 /* optional time values not given */
2943 Py_BEGIN_ALLOW_THREADS
2944 res = utime(path, NULL);
2945 Py_END_ALLOW_THREADS
2947 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2948 PyErr_SetString(PyExc_TypeError,
2949 "utime() arg 2 must be a tuple (atime, mtime)");
2950 PyMem_Free(path);
2951 return NULL;
2953 else {
2954 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2955 &atime, &ausec) == -1) {
2956 PyMem_Free(path);
2957 return NULL;
2959 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2960 &mtime, &musec) == -1) {
2961 PyMem_Free(path);
2962 return NULL;
2964 ATIME = atime;
2965 MTIME = mtime;
2966 #ifdef HAVE_UTIMES
2967 buf[0].tv_usec = ausec;
2968 buf[1].tv_usec = musec;
2969 Py_BEGIN_ALLOW_THREADS
2970 res = utimes(path, buf);
2971 Py_END_ALLOW_THREADS
2972 #else
2973 Py_BEGIN_ALLOW_THREADS
2974 res = utime(path, UTIME_ARG);
2975 Py_END_ALLOW_THREADS
2976 #endif /* HAVE_UTIMES */
2978 if (res < 0) {
2979 return posix_error_with_allocated_filename(path);
2981 PyMem_Free(path);
2982 Py_INCREF(Py_None);
2983 return Py_None;
2984 #undef UTIME_ARG
2985 #undef ATIME
2986 #undef MTIME
2987 #endif /* Py_WIN_WIDE_FILENAMES */
2991 /* Process operations */
2993 PyDoc_STRVAR(posix__exit__doc__,
2994 "_exit(status)\n\n\
2995 Exit to the system with specified status, without normal exit processing.");
2997 static PyObject *
2998 posix__exit(PyObject *self, PyObject *args)
3000 int sts;
3001 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3002 return NULL;
3003 _exit(sts);
3004 return NULL; /* Make gcc -Wall happy */
3007 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3008 static void
3009 free_string_array(char **array, Py_ssize_t count)
3011 Py_ssize_t i;
3012 for (i = 0; i < count; i++)
3013 PyMem_Free(array[i]);
3014 PyMem_DEL(array);
3016 #endif
3019 #ifdef HAVE_EXECV
3020 PyDoc_STRVAR(posix_execv__doc__,
3021 "execv(path, args)\n\n\
3022 Execute an executable path with arguments, replacing current process.\n\
3024 path: path of executable file\n\
3025 args: tuple or list of strings");
3027 static PyObject *
3028 posix_execv(PyObject *self, PyObject *args)
3030 char *path;
3031 PyObject *argv;
3032 char **argvlist;
3033 Py_ssize_t i, argc;
3034 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3036 /* execv has two arguments: (path, argv), where
3037 argv is a list or tuple of strings. */
3039 if (!PyArg_ParseTuple(args, "etO:execv",
3040 Py_FileSystemDefaultEncoding,
3041 &path, &argv))
3042 return NULL;
3043 if (PyList_Check(argv)) {
3044 argc = PyList_Size(argv);
3045 getitem = PyList_GetItem;
3047 else if (PyTuple_Check(argv)) {
3048 argc = PyTuple_Size(argv);
3049 getitem = PyTuple_GetItem;
3051 else {
3052 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3053 PyMem_Free(path);
3054 return NULL;
3057 argvlist = PyMem_NEW(char *, argc+1);
3058 if (argvlist == NULL) {
3059 PyMem_Free(path);
3060 return PyErr_NoMemory();
3062 for (i = 0; i < argc; i++) {
3063 if (!PyArg_Parse((*getitem)(argv, i), "et",
3064 Py_FileSystemDefaultEncoding,
3065 &argvlist[i])) {
3066 free_string_array(argvlist, i);
3067 PyErr_SetString(PyExc_TypeError,
3068 "execv() arg 2 must contain only strings");
3069 PyMem_Free(path);
3070 return NULL;
3074 argvlist[argc] = NULL;
3076 execv(path, argvlist);
3078 /* If we get here it's definitely an error */
3080 free_string_array(argvlist, argc);
3081 PyMem_Free(path);
3082 return posix_error();
3086 PyDoc_STRVAR(posix_execve__doc__,
3087 "execve(path, args, env)\n\n\
3088 Execute a path with arguments and environment, replacing current process.\n\
3090 path: path of executable file\n\
3091 args: tuple or list of arguments\n\
3092 env: dictionary of strings mapping to strings");
3094 static PyObject *
3095 posix_execve(PyObject *self, PyObject *args)
3097 char *path;
3098 PyObject *argv, *env;
3099 char **argvlist;
3100 char **envlist;
3101 PyObject *key, *val, *keys=NULL, *vals=NULL;
3102 Py_ssize_t i, pos, argc, envc;
3103 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3104 Py_ssize_t lastarg = 0;
3106 /* execve has three arguments: (path, argv, env), where
3107 argv is a list or tuple of strings and env is a dictionary
3108 like posix.environ. */
3110 if (!PyArg_ParseTuple(args, "etOO:execve",
3111 Py_FileSystemDefaultEncoding,
3112 &path, &argv, &env))
3113 return NULL;
3114 if (PyList_Check(argv)) {
3115 argc = PyList_Size(argv);
3116 getitem = PyList_GetItem;
3118 else if (PyTuple_Check(argv)) {
3119 argc = PyTuple_Size(argv);
3120 getitem = PyTuple_GetItem;
3122 else {
3123 PyErr_SetString(PyExc_TypeError,
3124 "execve() arg 2 must be a tuple or list");
3125 goto fail_0;
3127 if (!PyMapping_Check(env)) {
3128 PyErr_SetString(PyExc_TypeError,
3129 "execve() arg 3 must be a mapping object");
3130 goto fail_0;
3133 argvlist = PyMem_NEW(char *, argc+1);
3134 if (argvlist == NULL) {
3135 PyErr_NoMemory();
3136 goto fail_0;
3138 for (i = 0; i < argc; i++) {
3139 if (!PyArg_Parse((*getitem)(argv, i),
3140 "et;execve() arg 2 must contain only strings",
3141 Py_FileSystemDefaultEncoding,
3142 &argvlist[i]))
3144 lastarg = i;
3145 goto fail_1;
3148 lastarg = argc;
3149 argvlist[argc] = NULL;
3151 i = PyMapping_Size(env);
3152 if (i < 0)
3153 goto fail_1;
3154 envlist = PyMem_NEW(char *, i + 1);
3155 if (envlist == NULL) {
3156 PyErr_NoMemory();
3157 goto fail_1;
3159 envc = 0;
3160 keys = PyMapping_Keys(env);
3161 vals = PyMapping_Values(env);
3162 if (!keys || !vals)
3163 goto fail_2;
3164 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3165 PyErr_SetString(PyExc_TypeError,
3166 "execve(): env.keys() or env.values() is not a list");
3167 goto fail_2;
3170 for (pos = 0; pos < i; pos++) {
3171 char *p, *k, *v;
3172 size_t len;
3174 key = PyList_GetItem(keys, pos);
3175 val = PyList_GetItem(vals, pos);
3176 if (!key || !val)
3177 goto fail_2;
3179 if (!PyArg_Parse(
3180 key,
3181 "s;execve() arg 3 contains a non-string key",
3182 &k) ||
3183 !PyArg_Parse(
3184 val,
3185 "s;execve() arg 3 contains a non-string value",
3186 &v))
3188 goto fail_2;
3191 #if defined(PYOS_OS2)
3192 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3193 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3194 #endif
3195 len = PyString_Size(key) + PyString_Size(val) + 2;
3196 p = PyMem_NEW(char, len);
3197 if (p == NULL) {
3198 PyErr_NoMemory();
3199 goto fail_2;
3201 PyOS_snprintf(p, len, "%s=%s", k, v);
3202 envlist[envc++] = p;
3203 #if defined(PYOS_OS2)
3205 #endif
3207 envlist[envc] = 0;
3209 execve(path, argvlist, envlist);
3211 /* If we get here it's definitely an error */
3213 (void) posix_error();
3215 fail_2:
3216 while (--envc >= 0)
3217 PyMem_DEL(envlist[envc]);
3218 PyMem_DEL(envlist);
3219 fail_1:
3220 free_string_array(argvlist, lastarg);
3221 Py_XDECREF(vals);
3222 Py_XDECREF(keys);
3223 fail_0:
3224 PyMem_Free(path);
3225 return NULL;
3227 #endif /* HAVE_EXECV */
3230 #ifdef HAVE_SPAWNV
3231 PyDoc_STRVAR(posix_spawnv__doc__,
3232 "spawnv(mode, path, args)\n\n\
3233 Execute the program 'path' in a new process.\n\
3235 mode: mode of process creation\n\
3236 path: path of executable file\n\
3237 args: tuple or list of strings");
3239 static PyObject *
3240 posix_spawnv(PyObject *self, PyObject *args)
3242 char *path;
3243 PyObject *argv;
3244 char **argvlist;
3245 int mode, i;
3246 Py_ssize_t argc;
3247 Py_intptr_t spawnval;
3248 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3250 /* spawnv has three arguments: (mode, path, argv), where
3251 argv is a list or tuple of strings. */
3253 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3254 Py_FileSystemDefaultEncoding,
3255 &path, &argv))
3256 return NULL;
3257 if (PyList_Check(argv)) {
3258 argc = PyList_Size(argv);
3259 getitem = PyList_GetItem;
3261 else if (PyTuple_Check(argv)) {
3262 argc = PyTuple_Size(argv);
3263 getitem = PyTuple_GetItem;
3265 else {
3266 PyErr_SetString(PyExc_TypeError,
3267 "spawnv() arg 2 must be a tuple or list");
3268 PyMem_Free(path);
3269 return NULL;
3272 argvlist = PyMem_NEW(char *, argc+1);
3273 if (argvlist == NULL) {
3274 PyMem_Free(path);
3275 return PyErr_NoMemory();
3277 for (i = 0; i < argc; i++) {
3278 if (!PyArg_Parse((*getitem)(argv, i), "et",
3279 Py_FileSystemDefaultEncoding,
3280 &argvlist[i])) {
3281 free_string_array(argvlist, i);
3282 PyErr_SetString(
3283 PyExc_TypeError,
3284 "spawnv() arg 2 must contain only strings");
3285 PyMem_Free(path);
3286 return NULL;
3289 argvlist[argc] = NULL;
3291 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3292 Py_BEGIN_ALLOW_THREADS
3293 spawnval = spawnv(mode, path, argvlist);
3294 Py_END_ALLOW_THREADS
3295 #else
3296 if (mode == _OLD_P_OVERLAY)
3297 mode = _P_OVERLAY;
3299 Py_BEGIN_ALLOW_THREADS
3300 spawnval = _spawnv(mode, path, argvlist);
3301 Py_END_ALLOW_THREADS
3302 #endif
3304 free_string_array(argvlist, argc);
3305 PyMem_Free(path);
3307 if (spawnval == -1)
3308 return posix_error();
3309 else
3310 #if SIZEOF_LONG == SIZEOF_VOID_P
3311 return Py_BuildValue("l", (long) spawnval);
3312 #else
3313 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3314 #endif
3318 PyDoc_STRVAR(posix_spawnve__doc__,
3319 "spawnve(mode, path, args, env)\n\n\
3320 Execute the program 'path' in a new process.\n\
3322 mode: mode of process creation\n\
3323 path: path of executable file\n\
3324 args: tuple or list of arguments\n\
3325 env: dictionary of strings mapping to strings");
3327 static PyObject *
3328 posix_spawnve(PyObject *self, PyObject *args)
3330 char *path;
3331 PyObject *argv, *env;
3332 char **argvlist;
3333 char **envlist;
3334 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3335 int mode, pos, envc;
3336 Py_ssize_t argc, i;
3337 Py_intptr_t spawnval;
3338 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3339 Py_ssize_t lastarg = 0;
3341 /* spawnve has four arguments: (mode, path, argv, env), where
3342 argv is a list or tuple of strings and env is a dictionary
3343 like posix.environ. */
3345 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3346 Py_FileSystemDefaultEncoding,
3347 &path, &argv, &env))
3348 return NULL;
3349 if (PyList_Check(argv)) {
3350 argc = PyList_Size(argv);
3351 getitem = PyList_GetItem;
3353 else if (PyTuple_Check(argv)) {
3354 argc = PyTuple_Size(argv);
3355 getitem = PyTuple_GetItem;
3357 else {
3358 PyErr_SetString(PyExc_TypeError,
3359 "spawnve() arg 2 must be a tuple or list");
3360 goto fail_0;
3362 if (!PyMapping_Check(env)) {
3363 PyErr_SetString(PyExc_TypeError,
3364 "spawnve() arg 3 must be a mapping object");
3365 goto fail_0;
3368 argvlist = PyMem_NEW(char *, argc+1);
3369 if (argvlist == NULL) {
3370 PyErr_NoMemory();
3371 goto fail_0;
3373 for (i = 0; i < argc; i++) {
3374 if (!PyArg_Parse((*getitem)(argv, i),
3375 "et;spawnve() arg 2 must contain only strings",
3376 Py_FileSystemDefaultEncoding,
3377 &argvlist[i]))
3379 lastarg = i;
3380 goto fail_1;
3383 lastarg = argc;
3384 argvlist[argc] = NULL;
3386 i = PyMapping_Size(env);
3387 if (i < 0)
3388 goto fail_1;
3389 envlist = PyMem_NEW(char *, i + 1);
3390 if (envlist == NULL) {
3391 PyErr_NoMemory();
3392 goto fail_1;
3394 envc = 0;
3395 keys = PyMapping_Keys(env);
3396 vals = PyMapping_Values(env);
3397 if (!keys || !vals)
3398 goto fail_2;
3399 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3400 PyErr_SetString(PyExc_TypeError,
3401 "spawnve(): env.keys() or env.values() is not a list");
3402 goto fail_2;
3405 for (pos = 0; pos < i; pos++) {
3406 char *p, *k, *v;
3407 size_t len;
3409 key = PyList_GetItem(keys, pos);
3410 val = PyList_GetItem(vals, pos);
3411 if (!key || !val)
3412 goto fail_2;
3414 if (!PyArg_Parse(
3415 key,
3416 "s;spawnve() arg 3 contains a non-string key",
3417 &k) ||
3418 !PyArg_Parse(
3419 val,
3420 "s;spawnve() arg 3 contains a non-string value",
3421 &v))
3423 goto fail_2;
3425 len = PyString_Size(key) + PyString_Size(val) + 2;
3426 p = PyMem_NEW(char, len);
3427 if (p == NULL) {
3428 PyErr_NoMemory();
3429 goto fail_2;
3431 PyOS_snprintf(p, len, "%s=%s", k, v);
3432 envlist[envc++] = p;
3434 envlist[envc] = 0;
3436 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3437 Py_BEGIN_ALLOW_THREADS
3438 spawnval = spawnve(mode, path, argvlist, envlist);
3439 Py_END_ALLOW_THREADS
3440 #else
3441 if (mode == _OLD_P_OVERLAY)
3442 mode = _P_OVERLAY;
3444 Py_BEGIN_ALLOW_THREADS
3445 spawnval = _spawnve(mode, path, argvlist, envlist);
3446 Py_END_ALLOW_THREADS
3447 #endif
3449 if (spawnval == -1)
3450 (void) posix_error();
3451 else
3452 #if SIZEOF_LONG == SIZEOF_VOID_P
3453 res = Py_BuildValue("l", (long) spawnval);
3454 #else
3455 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3456 #endif
3458 fail_2:
3459 while (--envc >= 0)
3460 PyMem_DEL(envlist[envc]);
3461 PyMem_DEL(envlist);
3462 fail_1:
3463 free_string_array(argvlist, lastarg);
3464 Py_XDECREF(vals);
3465 Py_XDECREF(keys);
3466 fail_0:
3467 PyMem_Free(path);
3468 return res;
3471 /* OS/2 supports spawnvp & spawnvpe natively */
3472 #if defined(PYOS_OS2)
3473 PyDoc_STRVAR(posix_spawnvp__doc__,
3474 "spawnvp(mode, file, args)\n\n\
3475 Execute the program 'file' in a new process, using the environment\n\
3476 search path to find the file.\n\
3478 mode: mode of process creation\n\
3479 file: executable file name\n\
3480 args: tuple or list of strings");
3482 static PyObject *
3483 posix_spawnvp(PyObject *self, PyObject *args)
3485 char *path;
3486 PyObject *argv;
3487 char **argvlist;
3488 int mode, i, argc;
3489 Py_intptr_t spawnval;
3490 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3492 /* spawnvp has three arguments: (mode, path, argv), where
3493 argv is a list or tuple of strings. */
3495 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3496 Py_FileSystemDefaultEncoding,
3497 &path, &argv))
3498 return NULL;
3499 if (PyList_Check(argv)) {
3500 argc = PyList_Size(argv);
3501 getitem = PyList_GetItem;
3503 else if (PyTuple_Check(argv)) {
3504 argc = PyTuple_Size(argv);
3505 getitem = PyTuple_GetItem;
3507 else {
3508 PyErr_SetString(PyExc_TypeError,
3509 "spawnvp() arg 2 must be a tuple or list");
3510 PyMem_Free(path);
3511 return NULL;
3514 argvlist = PyMem_NEW(char *, argc+1);
3515 if (argvlist == NULL) {
3516 PyMem_Free(path);
3517 return PyErr_NoMemory();
3519 for (i = 0; i < argc; i++) {
3520 if (!PyArg_Parse((*getitem)(argv, i), "et",
3521 Py_FileSystemDefaultEncoding,
3522 &argvlist[i])) {
3523 free_string_array(argvlist, i);
3524 PyErr_SetString(
3525 PyExc_TypeError,
3526 "spawnvp() arg 2 must contain only strings");
3527 PyMem_Free(path);
3528 return NULL;
3531 argvlist[argc] = NULL;
3533 Py_BEGIN_ALLOW_THREADS
3534 #if defined(PYCC_GCC)
3535 spawnval = spawnvp(mode, path, argvlist);
3536 #else
3537 spawnval = _spawnvp(mode, path, argvlist);
3538 #endif
3539 Py_END_ALLOW_THREADS
3541 free_string_array(argvlist, argc);
3542 PyMem_Free(path);
3544 if (spawnval == -1)
3545 return posix_error();
3546 else
3547 return Py_BuildValue("l", (long) spawnval);
3551 PyDoc_STRVAR(posix_spawnvpe__doc__,
3552 "spawnvpe(mode, file, args, env)\n\n\
3553 Execute the program 'file' in a new process, using the environment\n\
3554 search path to find the file.\n\
3556 mode: mode of process creation\n\
3557 file: executable file name\n\
3558 args: tuple or list of arguments\n\
3559 env: dictionary of strings mapping to strings");
3561 static PyObject *
3562 posix_spawnvpe(PyObject *self, PyObject *args)
3564 char *path;
3565 PyObject *argv, *env;
3566 char **argvlist;
3567 char **envlist;
3568 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3569 int mode, i, pos, argc, envc;
3570 Py_intptr_t spawnval;
3571 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3572 int lastarg = 0;
3574 /* spawnvpe has four arguments: (mode, path, argv, env), where
3575 argv is a list or tuple of strings and env is a dictionary
3576 like posix.environ. */
3578 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3579 Py_FileSystemDefaultEncoding,
3580 &path, &argv, &env))
3581 return NULL;
3582 if (PyList_Check(argv)) {
3583 argc = PyList_Size(argv);
3584 getitem = PyList_GetItem;
3586 else if (PyTuple_Check(argv)) {
3587 argc = PyTuple_Size(argv);
3588 getitem = PyTuple_GetItem;
3590 else {
3591 PyErr_SetString(PyExc_TypeError,
3592 "spawnvpe() arg 2 must be a tuple or list");
3593 goto fail_0;
3595 if (!PyMapping_Check(env)) {
3596 PyErr_SetString(PyExc_TypeError,
3597 "spawnvpe() arg 3 must be a mapping object");
3598 goto fail_0;
3601 argvlist = PyMem_NEW(char *, argc+1);
3602 if (argvlist == NULL) {
3603 PyErr_NoMemory();
3604 goto fail_0;
3606 for (i = 0; i < argc; i++) {
3607 if (!PyArg_Parse((*getitem)(argv, i),
3608 "et;spawnvpe() arg 2 must contain only strings",
3609 Py_FileSystemDefaultEncoding,
3610 &argvlist[i]))
3612 lastarg = i;
3613 goto fail_1;
3616 lastarg = argc;
3617 argvlist[argc] = NULL;
3619 i = PyMapping_Size(env);
3620 if (i < 0)
3621 goto fail_1;
3622 envlist = PyMem_NEW(char *, i + 1);
3623 if (envlist == NULL) {
3624 PyErr_NoMemory();
3625 goto fail_1;
3627 envc = 0;
3628 keys = PyMapping_Keys(env);
3629 vals = PyMapping_Values(env);
3630 if (!keys || !vals)
3631 goto fail_2;
3632 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3633 PyErr_SetString(PyExc_TypeError,
3634 "spawnvpe(): env.keys() or env.values() is not a list");
3635 goto fail_2;
3638 for (pos = 0; pos < i; pos++) {
3639 char *p, *k, *v;
3640 size_t len;
3642 key = PyList_GetItem(keys, pos);
3643 val = PyList_GetItem(vals, pos);
3644 if (!key || !val)
3645 goto fail_2;
3647 if (!PyArg_Parse(
3648 key,
3649 "s;spawnvpe() arg 3 contains a non-string key",
3650 &k) ||
3651 !PyArg_Parse(
3652 val,
3653 "s;spawnvpe() arg 3 contains a non-string value",
3654 &v))
3656 goto fail_2;
3658 len = PyString_Size(key) + PyString_Size(val) + 2;
3659 p = PyMem_NEW(char, len);
3660 if (p == NULL) {
3661 PyErr_NoMemory();
3662 goto fail_2;
3664 PyOS_snprintf(p, len, "%s=%s", k, v);
3665 envlist[envc++] = p;
3667 envlist[envc] = 0;
3669 Py_BEGIN_ALLOW_THREADS
3670 #if defined(PYCC_GCC)
3671 spawnval = spawnvpe(mode, path, argvlist, envlist);
3672 #else
3673 spawnval = _spawnvpe(mode, path, argvlist, envlist);
3674 #endif
3675 Py_END_ALLOW_THREADS
3677 if (spawnval == -1)
3678 (void) posix_error();
3679 else
3680 res = Py_BuildValue("l", (long) spawnval);
3682 fail_2:
3683 while (--envc >= 0)
3684 PyMem_DEL(envlist[envc]);
3685 PyMem_DEL(envlist);
3686 fail_1:
3687 free_string_array(argvlist, lastarg);
3688 Py_XDECREF(vals);
3689 Py_XDECREF(keys);
3690 fail_0:
3691 PyMem_Free(path);
3692 return res;
3694 #endif /* PYOS_OS2 */
3695 #endif /* HAVE_SPAWNV */
3698 #ifdef HAVE_FORK1
3699 PyDoc_STRVAR(posix_fork1__doc__,
3700 "fork1() -> pid\n\n\
3701 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3703 Return 0 to child process and PID of child to parent process.");
3705 static PyObject *
3706 posix_fork1(PyObject *self, PyObject *noargs)
3708 pid_t pid = fork1();
3709 if (pid == -1)
3710 return posix_error();
3711 if (pid == 0)
3712 PyOS_AfterFork();
3713 return PyInt_FromLong(pid);
3715 #endif
3718 #ifdef HAVE_FORK
3719 PyDoc_STRVAR(posix_fork__doc__,
3720 "fork() -> pid\n\n\
3721 Fork a child process.\n\
3722 Return 0 to child process and PID of child to parent process.");
3724 static PyObject *
3725 posix_fork(PyObject *self, PyObject *noargs)
3727 pid_t pid = fork();
3728 if (pid == -1)
3729 return posix_error();
3730 if (pid == 0)
3731 PyOS_AfterFork();
3732 return PyInt_FromLong(pid);
3734 #endif
3736 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
3737 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3738 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
3739 #define DEV_PTY_FILE "/dev/ptc"
3740 #define HAVE_DEV_PTMX
3741 #else
3742 #define DEV_PTY_FILE "/dev/ptmx"
3743 #endif
3745 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
3746 #ifdef HAVE_PTY_H
3747 #include <pty.h>
3748 #else
3749 #ifdef HAVE_LIBUTIL_H
3750 #include <libutil.h>
3751 #endif /* HAVE_LIBUTIL_H */
3752 #endif /* HAVE_PTY_H */
3753 #ifdef HAVE_STROPTS_H
3754 #include <stropts.h>
3755 #endif
3756 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
3758 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3759 PyDoc_STRVAR(posix_openpty__doc__,
3760 "openpty() -> (master_fd, slave_fd)\n\n\
3761 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
3763 static PyObject *
3764 posix_openpty(PyObject *self, PyObject *noargs)
3766 int master_fd, slave_fd;
3767 #ifndef HAVE_OPENPTY
3768 char * slave_name;
3769 #endif
3770 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
3771 PyOS_sighandler_t sig_saved;
3772 #ifdef sun
3773 extern char *ptsname(int fildes);
3774 #endif
3775 #endif
3777 #ifdef HAVE_OPENPTY
3778 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3779 return posix_error();
3780 #elif defined(HAVE__GETPTY)
3781 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3782 if (slave_name == NULL)
3783 return posix_error();
3785 slave_fd = open(slave_name, O_RDWR);
3786 if (slave_fd < 0)
3787 return posix_error();
3788 #else
3789 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3790 if (master_fd < 0)
3791 return posix_error();
3792 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3793 /* change permission of slave */
3794 if (grantpt(master_fd) < 0) {
3795 PyOS_setsig(SIGCHLD, sig_saved);
3796 return posix_error();
3798 /* unlock slave */
3799 if (unlockpt(master_fd) < 0) {
3800 PyOS_setsig(SIGCHLD, sig_saved);
3801 return posix_error();
3803 PyOS_setsig(SIGCHLD, sig_saved);
3804 slave_name = ptsname(master_fd); /* get name of slave */
3805 if (slave_name == NULL)
3806 return posix_error();
3807 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3808 if (slave_fd < 0)
3809 return posix_error();
3810 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
3811 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3812 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
3813 #ifndef __hpux
3814 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
3815 #endif /* __hpux */
3816 #endif /* HAVE_CYGWIN */
3817 #endif /* HAVE_OPENPTY */
3819 return Py_BuildValue("(ii)", master_fd, slave_fd);
3822 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3824 #ifdef HAVE_FORKPTY
3825 PyDoc_STRVAR(posix_forkpty__doc__,
3826 "forkpty() -> (pid, master_fd)\n\n\
3827 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3828 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3829 To both, return fd of newly opened pseudo-terminal.\n");
3831 static PyObject *
3832 posix_forkpty(PyObject *self, PyObject *noargs)
3834 int master_fd = -1;
3835 pid_t pid;
3837 pid = forkpty(&master_fd, NULL, NULL, NULL);
3838 if (pid == -1)
3839 return posix_error();
3840 if (pid == 0)
3841 PyOS_AfterFork();
3842 return Py_BuildValue("(li)", pid, master_fd);
3844 #endif
3846 #ifdef HAVE_GETEGID
3847 PyDoc_STRVAR(posix_getegid__doc__,
3848 "getegid() -> egid\n\n\
3849 Return the current process's effective group id.");
3851 static PyObject *
3852 posix_getegid(PyObject *self, PyObject *noargs)
3854 return PyInt_FromLong((long)getegid());
3856 #endif
3859 #ifdef HAVE_GETEUID
3860 PyDoc_STRVAR(posix_geteuid__doc__,
3861 "geteuid() -> euid\n\n\
3862 Return the current process's effective user id.");
3864 static PyObject *
3865 posix_geteuid(PyObject *self, PyObject *noargs)
3867 return PyInt_FromLong((long)geteuid());
3869 #endif
3872 #ifdef HAVE_GETGID
3873 PyDoc_STRVAR(posix_getgid__doc__,
3874 "getgid() -> gid\n\n\
3875 Return the current process's group id.");
3877 static PyObject *
3878 posix_getgid(PyObject *self, PyObject *noargs)
3880 return PyInt_FromLong((long)getgid());
3882 #endif
3885 PyDoc_STRVAR(posix_getpid__doc__,
3886 "getpid() -> pid\n\n\
3887 Return the current process id");
3889 static PyObject *
3890 posix_getpid(PyObject *self, PyObject *noargs)
3892 return PyInt_FromLong((long)getpid());
3896 #ifdef HAVE_GETGROUPS
3897 PyDoc_STRVAR(posix_getgroups__doc__,
3898 "getgroups() -> list of group IDs\n\n\
3899 Return list of supplemental group IDs for the process.");
3901 static PyObject *
3902 posix_getgroups(PyObject *self, PyObject *noargs)
3904 PyObject *result = NULL;
3906 #ifdef NGROUPS_MAX
3907 #define MAX_GROUPS NGROUPS_MAX
3908 #else
3909 /* defined to be 16 on Solaris7, so this should be a small number */
3910 #define MAX_GROUPS 64
3911 #endif
3912 gid_t grouplist[MAX_GROUPS];
3913 int n;
3915 n = getgroups(MAX_GROUPS, grouplist);
3916 if (n < 0)
3917 posix_error();
3918 else {
3919 result = PyList_New(n);
3920 if (result != NULL) {
3921 int i;
3922 for (i = 0; i < n; ++i) {
3923 PyObject *o = PyInt_FromLong((long)grouplist[i]);
3924 if (o == NULL) {
3925 Py_DECREF(result);
3926 result = NULL;
3927 break;
3929 PyList_SET_ITEM(result, i, o);
3934 return result;
3936 #endif
3938 #ifdef HAVE_GETPGID
3939 PyDoc_STRVAR(posix_getpgid__doc__,
3940 "getpgid(pid) -> pgid\n\n\
3941 Call the system call getpgid().");
3943 static PyObject *
3944 posix_getpgid(PyObject *self, PyObject *args)
3946 int pid, pgid;
3947 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3948 return NULL;
3949 pgid = getpgid(pid);
3950 if (pgid < 0)
3951 return posix_error();
3952 return PyInt_FromLong((long)pgid);
3954 #endif /* HAVE_GETPGID */
3957 #ifdef HAVE_GETPGRP
3958 PyDoc_STRVAR(posix_getpgrp__doc__,
3959 "getpgrp() -> pgrp\n\n\
3960 Return the current process group id.");
3962 static PyObject *
3963 posix_getpgrp(PyObject *self, PyObject *noargs)
3965 #ifdef GETPGRP_HAVE_ARG
3966 return PyInt_FromLong((long)getpgrp(0));
3967 #else /* GETPGRP_HAVE_ARG */
3968 return PyInt_FromLong((long)getpgrp());
3969 #endif /* GETPGRP_HAVE_ARG */
3971 #endif /* HAVE_GETPGRP */
3974 #ifdef HAVE_SETPGRP
3975 PyDoc_STRVAR(posix_setpgrp__doc__,
3976 "setpgrp()\n\n\
3977 Make this process a session leader.");
3979 static PyObject *
3980 posix_setpgrp(PyObject *self, PyObject *noargs)
3982 #ifdef SETPGRP_HAVE_ARG
3983 if (setpgrp(0, 0) < 0)
3984 #else /* SETPGRP_HAVE_ARG */
3985 if (setpgrp() < 0)
3986 #endif /* SETPGRP_HAVE_ARG */
3987 return posix_error();
3988 Py_INCREF(Py_None);
3989 return Py_None;
3992 #endif /* HAVE_SETPGRP */
3994 #ifdef HAVE_GETPPID
3995 PyDoc_STRVAR(posix_getppid__doc__,
3996 "getppid() -> ppid\n\n\
3997 Return the parent's process id.");
3999 static PyObject *
4000 posix_getppid(PyObject *self, PyObject *noargs)
4002 return PyInt_FromLong(getppid());
4004 #endif
4007 #ifdef HAVE_GETLOGIN
4008 PyDoc_STRVAR(posix_getlogin__doc__,
4009 "getlogin() -> string\n\n\
4010 Return the actual login name.");
4012 static PyObject *
4013 posix_getlogin(PyObject *self, PyObject *noargs)
4015 PyObject *result = NULL;
4016 char *name;
4017 int old_errno = errno;
4019 errno = 0;
4020 name = getlogin();
4021 if (name == NULL) {
4022 if (errno)
4023 posix_error();
4024 else
4025 PyErr_SetString(PyExc_OSError,
4026 "unable to determine login name");
4028 else
4029 result = PyString_FromString(name);
4030 errno = old_errno;
4032 return result;
4034 #endif
4036 #ifdef HAVE_GETUID
4037 PyDoc_STRVAR(posix_getuid__doc__,
4038 "getuid() -> uid\n\n\
4039 Return the current process's user id.");
4041 static PyObject *
4042 posix_getuid(PyObject *self, PyObject *noargs)
4044 return PyInt_FromLong((long)getuid());
4046 #endif
4049 #ifdef HAVE_KILL
4050 PyDoc_STRVAR(posix_kill__doc__,
4051 "kill(pid, sig)\n\n\
4052 Kill a process with a signal.");
4054 static PyObject *
4055 posix_kill(PyObject *self, PyObject *args)
4057 pid_t pid;
4058 int sig;
4059 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
4060 return NULL;
4061 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
4062 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4063 APIRET rc;
4064 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
4065 return os2_error(rc);
4067 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4068 APIRET rc;
4069 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
4070 return os2_error(rc);
4072 } else
4073 return NULL; /* Unrecognized Signal Requested */
4074 #else
4075 if (kill(pid, sig) == -1)
4076 return posix_error();
4077 #endif
4078 Py_INCREF(Py_None);
4079 return Py_None;
4081 #endif
4083 #ifdef HAVE_KILLPG
4084 PyDoc_STRVAR(posix_killpg__doc__,
4085 "killpg(pgid, sig)\n\n\
4086 Kill a process group with a signal.");
4088 static PyObject *
4089 posix_killpg(PyObject *self, PyObject *args)
4091 int pgid, sig;
4092 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
4093 return NULL;
4094 if (killpg(pgid, sig) == -1)
4095 return posix_error();
4096 Py_INCREF(Py_None);
4097 return Py_None;
4099 #endif
4101 #ifdef HAVE_PLOCK
4103 #ifdef HAVE_SYS_LOCK_H
4104 #include <sys/lock.h>
4105 #endif
4107 PyDoc_STRVAR(posix_plock__doc__,
4108 "plock(op)\n\n\
4109 Lock program segments into memory.");
4111 static PyObject *
4112 posix_plock(PyObject *self, PyObject *args)
4114 int op;
4115 if (!PyArg_ParseTuple(args, "i:plock", &op))
4116 return NULL;
4117 if (plock(op) == -1)
4118 return posix_error();
4119 Py_INCREF(Py_None);
4120 return Py_None;
4122 #endif
4125 #ifdef HAVE_POPEN
4126 PyDoc_STRVAR(posix_popen__doc__,
4127 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
4128 Open a pipe to/from a command returning a file object.");
4130 #if defined(PYOS_OS2)
4131 #if defined(PYCC_VACPP)
4132 static int
4133 async_system(const char *command)
4135 char errormsg[256], args[1024];
4136 RESULTCODES rcodes;
4137 APIRET rc;
4139 char *shell = getenv("COMSPEC");
4140 if (!shell)
4141 shell = "cmd";
4143 /* avoid overflowing the argument buffer */
4144 if (strlen(shell) + 3 + strlen(command) >= 1024)
4145 return ERROR_NOT_ENOUGH_MEMORY
4147 args[0] = '\0';
4148 strcat(args, shell);
4149 strcat(args, "/c ");
4150 strcat(args, command);
4152 /* execute asynchronously, inheriting the environment */
4153 rc = DosExecPgm(errormsg,
4154 sizeof(errormsg),
4155 EXEC_ASYNC,
4156 args,
4157 NULL,
4158 &rcodes,
4159 shell);
4160 return rc;
4163 static FILE *
4164 popen(const char *command, const char *mode, int pipesize, int *err)
4166 int oldfd, tgtfd;
4167 HFILE pipeh[2];
4168 APIRET rc;
4170 /* mode determines which of stdin or stdout is reconnected to
4171 * the pipe to the child
4173 if (strchr(mode, 'r') != NULL) {
4174 tgt_fd = 1; /* stdout */
4175 } else if (strchr(mode, 'w')) {
4176 tgt_fd = 0; /* stdin */
4177 } else {
4178 *err = ERROR_INVALID_ACCESS;
4179 return NULL;
4182 /* setup the pipe */
4183 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4184 *err = rc;
4185 return NULL;
4188 /* prevent other threads accessing stdio */
4189 DosEnterCritSec();
4191 /* reconnect stdio and execute child */
4192 oldfd = dup(tgtfd);
4193 close(tgtfd);
4194 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4195 DosClose(pipeh[tgtfd]);
4196 rc = async_system(command);
4199 /* restore stdio */
4200 dup2(oldfd, tgtfd);
4201 close(oldfd);
4203 /* allow other threads access to stdio */
4204 DosExitCritSec();
4206 /* if execution of child was successful return file stream */
4207 if (rc == NO_ERROR)
4208 return fdopen(pipeh[1 - tgtfd], mode);
4209 else {
4210 DosClose(pipeh[1 - tgtfd]);
4211 *err = rc;
4212 return NULL;
4216 static PyObject *
4217 posix_popen(PyObject *self, PyObject *args)
4219 char *name;
4220 char *mode = "r";
4221 int err, bufsize = -1;
4222 FILE *fp;
4223 PyObject *f;
4224 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4225 return NULL;
4226 Py_BEGIN_ALLOW_THREADS
4227 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4228 Py_END_ALLOW_THREADS
4229 if (fp == NULL)
4230 return os2_error(err);
4232 f = PyFile_FromFile(fp, name, mode, fclose);
4233 if (f != NULL)
4234 PyFile_SetBufSize(f, bufsize);
4235 return f;
4238 #elif defined(PYCC_GCC)
4240 /* standard posix version of popen() support */
4241 static PyObject *
4242 posix_popen(PyObject *self, PyObject *args)
4244 char *name;
4245 char *mode = "r";
4246 int bufsize = -1;
4247 FILE *fp;
4248 PyObject *f;
4249 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4250 return NULL;
4251 Py_BEGIN_ALLOW_THREADS
4252 fp = popen(name, mode);
4253 Py_END_ALLOW_THREADS
4254 if (fp == NULL)
4255 return posix_error();
4256 f = PyFile_FromFile(fp, name, mode, pclose);
4257 if (f != NULL)
4258 PyFile_SetBufSize(f, bufsize);
4259 return f;
4262 /* fork() under OS/2 has lots'o'warts
4263 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4264 * most of this code is a ripoff of the win32 code, but using the
4265 * capabilities of EMX's C library routines
4268 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4269 #define POPEN_1 1
4270 #define POPEN_2 2
4271 #define POPEN_3 3
4272 #define POPEN_4 4
4274 static PyObject *_PyPopen(char *, int, int, int);
4275 static int _PyPclose(FILE *file);
4278 * Internal dictionary mapping popen* file pointers to process handles,
4279 * for use when retrieving the process exit code. See _PyPclose() below
4280 * for more information on this dictionary's use.
4282 static PyObject *_PyPopenProcs = NULL;
4284 /* os2emx version of popen2()
4286 * The result of this function is a pipe (file) connected to the
4287 * process's stdin, and a pipe connected to the process's stdout.
4290 static PyObject *
4291 os2emx_popen2(PyObject *self, PyObject *args)
4293 PyObject *f;
4294 int tm=0;
4296 char *cmdstring;
4297 char *mode = "t";
4298 int bufsize = -1;
4299 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4300 return NULL;
4302 if (*mode == 't')
4303 tm = O_TEXT;
4304 else if (*mode != 'b') {
4305 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4306 return NULL;
4307 } else
4308 tm = O_BINARY;
4310 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4312 return f;
4316 * Variation on os2emx.popen2
4318 * The result of this function is 3 pipes - the process's stdin,
4319 * stdout and stderr
4322 static PyObject *
4323 os2emx_popen3(PyObject *self, PyObject *args)
4325 PyObject *f;
4326 int tm = 0;
4328 char *cmdstring;
4329 char *mode = "t";
4330 int bufsize = -1;
4331 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4332 return NULL;
4334 if (*mode == 't')
4335 tm = O_TEXT;
4336 else if (*mode != 'b') {
4337 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4338 return NULL;
4339 } else
4340 tm = O_BINARY;
4342 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4344 return f;
4348 * Variation on os2emx.popen2
4350 * The result of this function is 2 pipes - the processes stdin,
4351 * and stdout+stderr combined as a single pipe.
4354 static PyObject *
4355 os2emx_popen4(PyObject *self, PyObject *args)
4357 PyObject *f;
4358 int tm = 0;
4360 char *cmdstring;
4361 char *mode = "t";
4362 int bufsize = -1;
4363 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4364 return NULL;
4366 if (*mode == 't')
4367 tm = O_TEXT;
4368 else if (*mode != 'b') {
4369 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4370 return NULL;
4371 } else
4372 tm = O_BINARY;
4374 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4376 return f;
4379 /* a couple of structures for convenient handling of multiple
4380 * file handles and pipes
4382 struct file_ref
4384 int handle;
4385 int flags;
4388 struct pipe_ref
4390 int rd;
4391 int wr;
4394 /* The following code is derived from the win32 code */
4396 static PyObject *
4397 _PyPopen(char *cmdstring, int mode, int n, int bufsize)
4399 struct file_ref stdio[3];
4400 struct pipe_ref p_fd[3];
4401 FILE *p_s[3];
4402 int file_count, i, pipe_err;
4403 pid_t pipe_pid;
4404 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4405 PyObject *f, *p_f[3];
4407 /* file modes for subsequent fdopen's on pipe handles */
4408 if (mode == O_TEXT)
4410 rd_mode = "rt";
4411 wr_mode = "wt";
4413 else
4415 rd_mode = "rb";
4416 wr_mode = "wb";
4419 /* prepare shell references */
4420 if ((shell = getenv("EMXSHELL")) == NULL)
4421 if ((shell = getenv("COMSPEC")) == NULL)
4423 errno = ENOENT;
4424 return posix_error();
4427 sh_name = _getname(shell);
4428 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4429 opt = "/c";
4430 else
4431 opt = "-c";
4433 /* save current stdio fds + their flags, and set not inheritable */
4434 i = pipe_err = 0;
4435 while (pipe_err >= 0 && i < 3)
4437 pipe_err = stdio[i].handle = dup(i);
4438 stdio[i].flags = fcntl(i, F_GETFD, 0);
4439 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4440 i++;
4442 if (pipe_err < 0)
4444 /* didn't get them all saved - clean up and bail out */
4445 int saved_err = errno;
4446 while (i-- > 0)
4448 close(stdio[i].handle);
4450 errno = saved_err;
4451 return posix_error();
4454 /* create pipe ends */
4455 file_count = 2;
4456 if (n == POPEN_3)
4457 file_count = 3;
4458 i = pipe_err = 0;
4459 while ((pipe_err == 0) && (i < file_count))
4460 pipe_err = pipe((int *)&p_fd[i++]);
4461 if (pipe_err < 0)
4463 /* didn't get them all made - clean up and bail out */
4464 while (i-- > 0)
4466 close(p_fd[i].wr);
4467 close(p_fd[i].rd);
4469 errno = EPIPE;
4470 return posix_error();
4473 /* change the actual standard IO streams over temporarily,
4474 * making the retained pipe ends non-inheritable
4476 pipe_err = 0;
4478 /* - stdin */
4479 if (dup2(p_fd[0].rd, 0) == 0)
4481 close(p_fd[0].rd);
4482 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4483 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4484 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4486 close(p_fd[0].wr);
4487 pipe_err = -1;
4490 else
4492 pipe_err = -1;
4495 /* - stdout */
4496 if (pipe_err == 0)
4498 if (dup2(p_fd[1].wr, 1) == 1)
4500 close(p_fd[1].wr);
4501 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4502 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4503 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4505 close(p_fd[1].rd);
4506 pipe_err = -1;
4509 else
4511 pipe_err = -1;
4515 /* - stderr, as required */
4516 if (pipe_err == 0)
4517 switch (n)
4519 case POPEN_3:
4521 if (dup2(p_fd[2].wr, 2) == 2)
4523 close(p_fd[2].wr);
4524 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4525 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4526 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4528 close(p_fd[2].rd);
4529 pipe_err = -1;
4532 else
4534 pipe_err = -1;
4536 break;
4539 case POPEN_4:
4541 if (dup2(1, 2) != 2)
4543 pipe_err = -1;
4545 break;
4549 /* spawn the child process */
4550 if (pipe_err == 0)
4552 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4553 if (pipe_pid == -1)
4555 pipe_err = -1;
4557 else
4559 /* save the PID into the FILE structure
4560 * NOTE: this implementation doesn't actually
4561 * take advantage of this, but do it for
4562 * completeness - AIM Apr01
4564 for (i = 0; i < file_count; i++)
4565 p_s[i]->_pid = pipe_pid;
4569 /* reset standard IO to normal */
4570 for (i = 0; i < 3; i++)
4572 dup2(stdio[i].handle, i);
4573 fcntl(i, F_SETFD, stdio[i].flags);
4574 close(stdio[i].handle);
4577 /* if any remnant problems, clean up and bail out */
4578 if (pipe_err < 0)
4580 for (i = 0; i < 3; i++)
4582 close(p_fd[i].rd);
4583 close(p_fd[i].wr);
4585 errno = EPIPE;
4586 return posix_error_with_filename(cmdstring);
4589 /* build tuple of file objects to return */
4590 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4591 PyFile_SetBufSize(p_f[0], bufsize);
4592 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4593 PyFile_SetBufSize(p_f[1], bufsize);
4594 if (n == POPEN_3)
4596 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4597 PyFile_SetBufSize(p_f[0], bufsize);
4598 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4600 else
4601 f = PyTuple_Pack(2, p_f[0], p_f[1]);
4604 * Insert the files we've created into the process dictionary
4605 * all referencing the list with the process handle and the
4606 * initial number of files (see description below in _PyPclose).
4607 * Since if _PyPclose later tried to wait on a process when all
4608 * handles weren't closed, it could create a deadlock with the
4609 * child, we spend some energy here to try to ensure that we
4610 * either insert all file handles into the dictionary or none
4611 * at all. It's a little clumsy with the various popen modes
4612 * and variable number of files involved.
4614 if (!_PyPopenProcs)
4616 _PyPopenProcs = PyDict_New();
4619 if (_PyPopenProcs)
4621 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4622 int ins_rc[3];
4624 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4625 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4627 procObj = PyList_New(2);
4628 pidObj = PyInt_FromLong((long) pipe_pid);
4629 intObj = PyInt_FromLong((long) file_count);
4631 if (procObj && pidObj && intObj)
4633 PyList_SetItem(procObj, 0, pidObj);
4634 PyList_SetItem(procObj, 1, intObj);
4636 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4637 if (fileObj[0])
4639 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4640 fileObj[0],
4641 procObj);
4643 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4644 if (fileObj[1])
4646 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4647 fileObj[1],
4648 procObj);
4650 if (file_count >= 3)
4652 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4653 if (fileObj[2])
4655 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4656 fileObj[2],
4657 procObj);
4661 if (ins_rc[0] < 0 || !fileObj[0] ||
4662 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4663 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4665 /* Something failed - remove any dictionary
4666 * entries that did make it.
4668 if (!ins_rc[0] && fileObj[0])
4670 PyDict_DelItem(_PyPopenProcs,
4671 fileObj[0]);
4673 if (!ins_rc[1] && fileObj[1])
4675 PyDict_DelItem(_PyPopenProcs,
4676 fileObj[1]);
4678 if (!ins_rc[2] && fileObj[2])
4680 PyDict_DelItem(_PyPopenProcs,
4681 fileObj[2]);
4687 * Clean up our localized references for the dictionary keys
4688 * and value since PyDict_SetItem will Py_INCREF any copies
4689 * that got placed in the dictionary.
4691 Py_XDECREF(procObj);
4692 Py_XDECREF(fileObj[0]);
4693 Py_XDECREF(fileObj[1]);
4694 Py_XDECREF(fileObj[2]);
4697 /* Child is launched. */
4698 return f;
4702 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4703 * exit code for the child process and return as a result of the close.
4705 * This function uses the _PyPopenProcs dictionary in order to map the
4706 * input file pointer to information about the process that was
4707 * originally created by the popen* call that created the file pointer.
4708 * The dictionary uses the file pointer as a key (with one entry
4709 * inserted for each file returned by the original popen* call) and a
4710 * single list object as the value for all files from a single call.
4711 * The list object contains the Win32 process handle at [0], and a file
4712 * count at [1], which is initialized to the total number of file
4713 * handles using that list.
4715 * This function closes whichever handle it is passed, and decrements
4716 * the file count in the dictionary for the process handle pointed to
4717 * by this file. On the last close (when the file count reaches zero),
4718 * this function will wait for the child process and then return its
4719 * exit code as the result of the close() operation. This permits the
4720 * files to be closed in any order - it is always the close() of the
4721 * final handle that will return the exit code.
4723 * NOTE: This function is currently called with the GIL released.
4724 * hence we use the GILState API to manage our state.
4727 static int _PyPclose(FILE *file)
4729 int result;
4730 int exit_code;
4731 pid_t pipe_pid;
4732 PyObject *procObj, *pidObj, *intObj, *fileObj;
4733 int file_count;
4734 #ifdef WITH_THREAD
4735 PyGILState_STATE state;
4736 #endif
4738 /* Close the file handle first, to ensure it can't block the
4739 * child from exiting if it's the last handle.
4741 result = fclose(file);
4743 #ifdef WITH_THREAD
4744 state = PyGILState_Ensure();
4745 #endif
4746 if (_PyPopenProcs)
4748 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4749 (procObj = PyDict_GetItem(_PyPopenProcs,
4750 fileObj)) != NULL &&
4751 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4752 (intObj = PyList_GetItem(procObj,1)) != NULL)
4754 pipe_pid = (int) PyInt_AsLong(pidObj);
4755 file_count = (int) PyInt_AsLong(intObj);
4757 if (file_count > 1)
4759 /* Still other files referencing process */
4760 file_count--;
4761 PyList_SetItem(procObj,1,
4762 PyInt_FromLong((long) file_count));
4764 else
4766 /* Last file for this process */
4767 if (result != EOF &&
4768 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4770 /* extract exit status */
4771 if (WIFEXITED(exit_code))
4773 result = WEXITSTATUS(exit_code);
4775 else
4777 errno = EPIPE;
4778 result = -1;
4781 else
4783 /* Indicate failure - this will cause the file object
4784 * to raise an I/O error and translate the last
4785 * error code from errno. We do have a problem with
4786 * last errors that overlap the normal errno table,
4787 * but that's a consistent problem with the file object.
4789 result = -1;
4793 /* Remove this file pointer from dictionary */
4794 PyDict_DelItem(_PyPopenProcs, fileObj);
4796 if (PyDict_Size(_PyPopenProcs) == 0)
4798 Py_DECREF(_PyPopenProcs);
4799 _PyPopenProcs = NULL;
4802 } /* if object retrieval ok */
4804 Py_XDECREF(fileObj);
4805 } /* if _PyPopenProcs */
4807 #ifdef WITH_THREAD
4808 PyGILState_Release(state);
4809 #endif
4810 return result;
4813 #endif /* PYCC_??? */
4815 #elif defined(MS_WINDOWS)
4818 * Portable 'popen' replacement for Win32.
4820 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4821 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
4822 * Return code handling by David Bolen <db3l@fitlinxx.com>.
4825 #include <malloc.h>
4826 #include <io.h>
4827 #include <fcntl.h>
4829 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4830 #define POPEN_1 1
4831 #define POPEN_2 2
4832 #define POPEN_3 3
4833 #define POPEN_4 4
4835 static PyObject *_PyPopen(char *, int, int);
4836 static int _PyPclose(FILE *file);
4839 * Internal dictionary mapping popen* file pointers to process handles,
4840 * for use when retrieving the process exit code. See _PyPclose() below
4841 * for more information on this dictionary's use.
4843 static PyObject *_PyPopenProcs = NULL;
4846 /* popen that works from a GUI.
4848 * The result of this function is a pipe (file) connected to the
4849 * processes stdin or stdout, depending on the requested mode.
4852 static PyObject *
4853 posix_popen(PyObject *self, PyObject *args)
4855 PyObject *f;
4856 int tm = 0;
4858 char *cmdstring;
4859 char *mode = "r";
4860 int bufsize = -1;
4861 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
4862 return NULL;
4864 if (*mode == 'r')
4865 tm = _O_RDONLY;
4866 else if (*mode != 'w') {
4867 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
4868 return NULL;
4869 } else
4870 tm = _O_WRONLY;
4872 if (bufsize != -1) {
4873 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
4874 return NULL;
4877 if (*(mode+1) == 't')
4878 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4879 else if (*(mode+1) == 'b')
4880 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
4881 else
4882 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4884 return f;
4887 /* Variation on win32pipe.popen
4889 * The result of this function is a pipe (file) connected to the
4890 * process's stdin, and a pipe connected to the process's stdout.
4893 static PyObject *
4894 win32_popen2(PyObject *self, PyObject *args)
4896 PyObject *f;
4897 int tm=0;
4899 char *cmdstring;
4900 char *mode = "t";
4901 int bufsize = -1;
4902 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4903 return NULL;
4905 if (*mode == 't')
4906 tm = _O_TEXT;
4907 else if (*mode != 'b') {
4908 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
4909 return NULL;
4910 } else
4911 tm = _O_BINARY;
4913 if (bufsize != -1) {
4914 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
4915 return NULL;
4918 f = _PyPopen(cmdstring, tm, POPEN_2);
4920 return f;
4924 * Variation on <om win32pipe.popen>
4926 * The result of this function is 3 pipes - the process's stdin,
4927 * stdout and stderr
4930 static PyObject *
4931 win32_popen3(PyObject *self, PyObject *args)
4933 PyObject *f;
4934 int tm = 0;
4936 char *cmdstring;
4937 char *mode = "t";
4938 int bufsize = -1;
4939 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4940 return NULL;
4942 if (*mode == 't')
4943 tm = _O_TEXT;
4944 else if (*mode != 'b') {
4945 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
4946 return NULL;
4947 } else
4948 tm = _O_BINARY;
4950 if (bufsize != -1) {
4951 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
4952 return NULL;
4955 f = _PyPopen(cmdstring, tm, POPEN_3);
4957 return f;
4961 * Variation on win32pipe.popen
4963 * The result of this function is 2 pipes - the processes stdin,
4964 * and stdout+stderr combined as a single pipe.
4967 static PyObject *
4968 win32_popen4(PyObject *self, PyObject *args)
4970 PyObject *f;
4971 int tm = 0;
4973 char *cmdstring;
4974 char *mode = "t";
4975 int bufsize = -1;
4976 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4977 return NULL;
4979 if (*mode == 't')
4980 tm = _O_TEXT;
4981 else if (*mode != 'b') {
4982 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
4983 return NULL;
4984 } else
4985 tm = _O_BINARY;
4987 if (bufsize != -1) {
4988 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
4989 return NULL;
4992 f = _PyPopen(cmdstring, tm, POPEN_4);
4994 return f;
4997 static BOOL
4998 _PyPopenCreateProcess(char *cmdstring,
4999 HANDLE hStdin,
5000 HANDLE hStdout,
5001 HANDLE hStderr,
5002 HANDLE *hProcess)
5004 PROCESS_INFORMATION piProcInfo;
5005 STARTUPINFO siStartInfo;
5006 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5007 char *s1,*s2, *s3 = " /c ";
5008 const char *szConsoleSpawn = "w9xpopen.exe";
5009 int i;
5010 Py_ssize_t x;
5012 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5013 char *comshell;
5015 s1 = (char *)alloca(i);
5016 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5017 /* x < i, so x fits into an integer */
5018 return (int)x;
5020 /* Explicitly check if we are using COMMAND.COM. If we are
5021 * then use the w9xpopen hack.
5023 comshell = s1 + x;
5024 while (comshell >= s1 && *comshell != '\\')
5025 --comshell;
5026 ++comshell;
5028 if (GetVersion() < 0x80000000 &&
5029 _stricmp(comshell, "command.com") != 0) {
5030 /* NT/2000 and not using command.com. */
5031 x = i + strlen(s3) + strlen(cmdstring) + 1;
5032 s2 = (char *)alloca(x);
5033 ZeroMemory(s2, x);
5034 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5036 else {
5038 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5039 * the workaround listed in KB: Q150956
5041 char modulepath[_MAX_PATH];
5042 struct stat statinfo;
5043 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5044 for (x = i = 0; modulepath[i]; i++)
5045 if (modulepath[i] == SEP)
5046 x = i+1;
5047 modulepath[x] = '\0';
5048 /* Create the full-name to w9xpopen, so we can test it exists */
5049 strncat(modulepath,
5050 szConsoleSpawn,
5051 (sizeof(modulepath)/sizeof(modulepath[0]))
5052 -strlen(modulepath));
5053 if (stat(modulepath, &statinfo) != 0) {
5054 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5055 /* Eeek - file-not-found - possibly an embedding
5056 situation - see if we can locate it in sys.prefix
5058 strncpy(modulepath,
5059 Py_GetExecPrefix(),
5060 mplen);
5061 modulepath[mplen-1] = '\0';
5062 if (modulepath[strlen(modulepath)-1] != '\\')
5063 strcat(modulepath, "\\");
5064 strncat(modulepath,
5065 szConsoleSpawn,
5066 mplen-strlen(modulepath));
5067 /* No where else to look - raise an easily identifiable
5068 error, rather than leaving Windows to report
5069 "file not found" - as the user is probably blissfully
5070 unaware this shim EXE is used, and it will confuse them.
5071 (well, it confused me for a while ;-)
5073 if (stat(modulepath, &statinfo) != 0) {
5074 PyErr_Format(PyExc_RuntimeError,
5075 "Can not locate '%s' which is needed "
5076 "for popen to work with your shell "
5077 "or platform.",
5078 szConsoleSpawn);
5079 return FALSE;
5082 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5083 strlen(modulepath) +
5084 strlen(szConsoleSpawn) + 1;
5086 s2 = (char *)alloca(x);
5087 ZeroMemory(s2, x);
5088 /* To maintain correct argument passing semantics,
5089 we pass the command-line as it stands, and allow
5090 quoting to be applied. w9xpopen.exe will then
5091 use its argv vector, and re-quote the necessary
5092 args for the ultimate child process.
5094 PyOS_snprintf(
5095 s2, x,
5096 "\"%s\" %s%s%s",
5097 modulepath,
5100 cmdstring);
5101 /* Not passing CREATE_NEW_CONSOLE has been known to
5102 cause random failures on win9x. Specifically a
5103 dialog:
5104 "Your program accessed mem currently in use at xxx"
5105 and a hopeful warning about the stability of your
5106 system.
5107 Cost is Ctrl+C won't kill children, but anyone
5108 who cares can have a go!
5110 dwProcessFlags |= CREATE_NEW_CONSOLE;
5114 /* Could be an else here to try cmd.exe / command.com in the path
5115 Now we'll just error out.. */
5116 else {
5117 PyErr_SetString(PyExc_RuntimeError,
5118 "Cannot locate a COMSPEC environment variable to "
5119 "use as the shell");
5120 return FALSE;
5123 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5124 siStartInfo.cb = sizeof(STARTUPINFO);
5125 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5126 siStartInfo.hStdInput = hStdin;
5127 siStartInfo.hStdOutput = hStdout;
5128 siStartInfo.hStdError = hStderr;
5129 siStartInfo.wShowWindow = SW_HIDE;
5131 if (CreateProcess(NULL,
5133 NULL,
5134 NULL,
5135 TRUE,
5136 dwProcessFlags,
5137 NULL,
5138 NULL,
5139 &siStartInfo,
5140 &piProcInfo) ) {
5141 /* Close the handles now so anyone waiting is woken. */
5142 CloseHandle(piProcInfo.hThread);
5144 /* Return process handle */
5145 *hProcess = piProcInfo.hProcess;
5146 return TRUE;
5148 win32_error("CreateProcess", s2);
5149 return FALSE;
5152 /* The following code is based off of KB: Q190351 */
5154 static PyObject *
5155 _PyPopen(char *cmdstring, int mode, int n)
5157 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5158 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5159 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
5161 SECURITY_ATTRIBUTES saAttr;
5162 BOOL fSuccess;
5163 int fd1, fd2, fd3;
5164 FILE *f1, *f2, *f3;
5165 long file_count;
5166 PyObject *f;
5168 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5169 saAttr.bInheritHandle = TRUE;
5170 saAttr.lpSecurityDescriptor = NULL;
5172 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5173 return win32_error("CreatePipe", NULL);
5175 /* Create new output read handle and the input write handle. Set
5176 * the inheritance properties to FALSE. Otherwise, the child inherits
5177 * these handles; resulting in non-closeable handles to the pipes
5178 * being created. */
5179 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5180 GetCurrentProcess(), &hChildStdinWrDup, 0,
5181 FALSE,
5182 DUPLICATE_SAME_ACCESS);
5183 if (!fSuccess)
5184 return win32_error("DuplicateHandle", NULL);
5186 /* Close the inheritable version of ChildStdin
5187 that we're using. */
5188 CloseHandle(hChildStdinWr);
5190 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5191 return win32_error("CreatePipe", NULL);
5193 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5194 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5195 FALSE, DUPLICATE_SAME_ACCESS);
5196 if (!fSuccess)
5197 return win32_error("DuplicateHandle", NULL);
5199 /* Close the inheritable version of ChildStdout
5200 that we're using. */
5201 CloseHandle(hChildStdoutRd);
5203 if (n != POPEN_4) {
5204 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5205 return win32_error("CreatePipe", NULL);
5206 fSuccess = DuplicateHandle(GetCurrentProcess(),
5207 hChildStderrRd,
5208 GetCurrentProcess(),
5209 &hChildStderrRdDup, 0,
5210 FALSE, DUPLICATE_SAME_ACCESS);
5211 if (!fSuccess)
5212 return win32_error("DuplicateHandle", NULL);
5213 /* Close the inheritable version of ChildStdErr that we're using. */
5214 CloseHandle(hChildStderrRd);
5217 switch (n) {
5218 case POPEN_1:
5219 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5220 case _O_WRONLY | _O_TEXT:
5221 /* Case for writing to child Stdin in text mode. */
5222 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5223 f1 = _fdopen(fd1, "w");
5224 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5225 PyFile_SetBufSize(f, 0);
5226 /* We don't care about these pipes anymore, so close them. */
5227 CloseHandle(hChildStdoutRdDup);
5228 CloseHandle(hChildStderrRdDup);
5229 break;
5231 case _O_RDONLY | _O_TEXT:
5232 /* Case for reading from child Stdout in text mode. */
5233 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5234 f1 = _fdopen(fd1, "r");
5235 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5236 PyFile_SetBufSize(f, 0);
5237 /* We don't care about these pipes anymore, so close them. */
5238 CloseHandle(hChildStdinWrDup);
5239 CloseHandle(hChildStderrRdDup);
5240 break;
5242 case _O_RDONLY | _O_BINARY:
5243 /* Case for readinig from child Stdout in binary mode. */
5244 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5245 f1 = _fdopen(fd1, "rb");
5246 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5247 PyFile_SetBufSize(f, 0);
5248 /* We don't care about these pipes anymore, so close them. */
5249 CloseHandle(hChildStdinWrDup);
5250 CloseHandle(hChildStderrRdDup);
5251 break;
5253 case _O_WRONLY | _O_BINARY:
5254 /* Case for writing to child Stdin in binary mode. */
5255 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5256 f1 = _fdopen(fd1, "wb");
5257 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5258 PyFile_SetBufSize(f, 0);
5259 /* We don't care about these pipes anymore, so close them. */
5260 CloseHandle(hChildStdoutRdDup);
5261 CloseHandle(hChildStderrRdDup);
5262 break;
5264 file_count = 1;
5265 break;
5267 case POPEN_2:
5268 case POPEN_4:
5270 char *m1, *m2;
5271 PyObject *p1, *p2;
5273 if (mode & _O_TEXT) {
5274 m1 = "r";
5275 m2 = "w";
5276 } else {
5277 m1 = "rb";
5278 m2 = "wb";
5281 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5282 f1 = _fdopen(fd1, m2);
5283 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5284 f2 = _fdopen(fd2, m1);
5285 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5286 PyFile_SetBufSize(p1, 0);
5287 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5288 PyFile_SetBufSize(p2, 0);
5290 if (n != 4)
5291 CloseHandle(hChildStderrRdDup);
5293 f = PyTuple_Pack(2,p1,p2);
5294 Py_XDECREF(p1);
5295 Py_XDECREF(p2);
5296 file_count = 2;
5297 break;
5300 case POPEN_3:
5302 char *m1, *m2;
5303 PyObject *p1, *p2, *p3;
5305 if (mode & _O_TEXT) {
5306 m1 = "r";
5307 m2 = "w";
5308 } else {
5309 m1 = "rb";
5310 m2 = "wb";
5313 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5314 f1 = _fdopen(fd1, m2);
5315 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5316 f2 = _fdopen(fd2, m1);
5317 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5318 f3 = _fdopen(fd3, m1);
5319 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5320 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5321 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5322 PyFile_SetBufSize(p1, 0);
5323 PyFile_SetBufSize(p2, 0);
5324 PyFile_SetBufSize(p3, 0);
5325 f = PyTuple_Pack(3,p1,p2,p3);
5326 Py_XDECREF(p1);
5327 Py_XDECREF(p2);
5328 Py_XDECREF(p3);
5329 file_count = 3;
5330 break;
5334 if (n == POPEN_4) {
5335 if (!_PyPopenCreateProcess(cmdstring,
5336 hChildStdinRd,
5337 hChildStdoutWr,
5338 hChildStdoutWr,
5339 &hProcess))
5340 return NULL;
5342 else {
5343 if (!_PyPopenCreateProcess(cmdstring,
5344 hChildStdinRd,
5345 hChildStdoutWr,
5346 hChildStderrWr,
5347 &hProcess))
5348 return NULL;
5352 * Insert the files we've created into the process dictionary
5353 * all referencing the list with the process handle and the
5354 * initial number of files (see description below in _PyPclose).
5355 * Since if _PyPclose later tried to wait on a process when all
5356 * handles weren't closed, it could create a deadlock with the
5357 * child, we spend some energy here to try to ensure that we
5358 * either insert all file handles into the dictionary or none
5359 * at all. It's a little clumsy with the various popen modes
5360 * and variable number of files involved.
5362 if (!_PyPopenProcs) {
5363 _PyPopenProcs = PyDict_New();
5366 if (_PyPopenProcs) {
5367 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5368 int ins_rc[3];
5370 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5371 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5373 procObj = PyList_New(2);
5374 hProcessObj = PyLong_FromVoidPtr(hProcess);
5375 intObj = PyInt_FromLong(file_count);
5377 if (procObj && hProcessObj && intObj) {
5378 PyList_SetItem(procObj,0,hProcessObj);
5379 PyList_SetItem(procObj,1,intObj);
5381 fileObj[0] = PyLong_FromVoidPtr(f1);
5382 if (fileObj[0]) {
5383 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5384 fileObj[0],
5385 procObj);
5387 if (file_count >= 2) {
5388 fileObj[1] = PyLong_FromVoidPtr(f2);
5389 if (fileObj[1]) {
5390 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5391 fileObj[1],
5392 procObj);
5395 if (file_count >= 3) {
5396 fileObj[2] = PyLong_FromVoidPtr(f3);
5397 if (fileObj[2]) {
5398 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5399 fileObj[2],
5400 procObj);
5404 if (ins_rc[0] < 0 || !fileObj[0] ||
5405 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5406 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5407 /* Something failed - remove any dictionary
5408 * entries that did make it.
5410 if (!ins_rc[0] && fileObj[0]) {
5411 PyDict_DelItem(_PyPopenProcs,
5412 fileObj[0]);
5414 if (!ins_rc[1] && fileObj[1]) {
5415 PyDict_DelItem(_PyPopenProcs,
5416 fileObj[1]);
5418 if (!ins_rc[2] && fileObj[2]) {
5419 PyDict_DelItem(_PyPopenProcs,
5420 fileObj[2]);
5426 * Clean up our localized references for the dictionary keys
5427 * and value since PyDict_SetItem will Py_INCREF any copies
5428 * that got placed in the dictionary.
5430 Py_XDECREF(procObj);
5431 Py_XDECREF(fileObj[0]);
5432 Py_XDECREF(fileObj[1]);
5433 Py_XDECREF(fileObj[2]);
5436 /* Child is launched. Close the parents copy of those pipe
5437 * handles that only the child should have open. You need to
5438 * make sure that no handles to the write end of the output pipe
5439 * are maintained in this process or else the pipe will not close
5440 * when the child process exits and the ReadFile will hang. */
5442 if (!CloseHandle(hChildStdinRd))
5443 return win32_error("CloseHandle", NULL);
5445 if (!CloseHandle(hChildStdoutWr))
5446 return win32_error("CloseHandle", NULL);
5448 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5449 return win32_error("CloseHandle", NULL);
5451 return f;
5455 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5456 * exit code for the child process and return as a result of the close.
5458 * This function uses the _PyPopenProcs dictionary in order to map the
5459 * input file pointer to information about the process that was
5460 * originally created by the popen* call that created the file pointer.
5461 * The dictionary uses the file pointer as a key (with one entry
5462 * inserted for each file returned by the original popen* call) and a
5463 * single list object as the value for all files from a single call.
5464 * The list object contains the Win32 process handle at [0], and a file
5465 * count at [1], which is initialized to the total number of file
5466 * handles using that list.
5468 * This function closes whichever handle it is passed, and decrements
5469 * the file count in the dictionary for the process handle pointed to
5470 * by this file. On the last close (when the file count reaches zero),
5471 * this function will wait for the child process and then return its
5472 * exit code as the result of the close() operation. This permits the
5473 * files to be closed in any order - it is always the close() of the
5474 * final handle that will return the exit code.
5476 * NOTE: This function is currently called with the GIL released.
5477 * hence we use the GILState API to manage our state.
5480 static int _PyPclose(FILE *file)
5482 int result;
5483 DWORD exit_code;
5484 HANDLE hProcess;
5485 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5486 long file_count;
5487 #ifdef WITH_THREAD
5488 PyGILState_STATE state;
5489 #endif
5491 /* Close the file handle first, to ensure it can't block the
5492 * child from exiting if it's the last handle.
5494 result = fclose(file);
5495 #ifdef WITH_THREAD
5496 state = PyGILState_Ensure();
5497 #endif
5498 if (_PyPopenProcs) {
5499 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5500 (procObj = PyDict_GetItem(_PyPopenProcs,
5501 fileObj)) != NULL &&
5502 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5503 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5505 hProcess = PyLong_AsVoidPtr(hProcessObj);
5506 file_count = PyInt_AsLong(intObj);
5508 if (file_count > 1) {
5509 /* Still other files referencing process */
5510 file_count--;
5511 PyList_SetItem(procObj,1,
5512 PyInt_FromLong(file_count));
5513 } else {
5514 /* Last file for this process */
5515 if (result != EOF &&
5516 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5517 GetExitCodeProcess(hProcess, &exit_code)) {
5518 /* Possible truncation here in 16-bit environments, but
5519 * real exit codes are just the lower byte in any event.
5521 result = exit_code;
5522 } else {
5523 /* Indicate failure - this will cause the file object
5524 * to raise an I/O error and translate the last Win32
5525 * error code from errno. We do have a problem with
5526 * last errors that overlap the normal errno table,
5527 * but that's a consistent problem with the file object.
5529 if (result != EOF) {
5530 /* If the error wasn't from the fclose(), then
5531 * set errno for the file object error handling.
5533 errno = GetLastError();
5535 result = -1;
5538 /* Free up the native handle at this point */
5539 CloseHandle(hProcess);
5542 /* Remove this file pointer from dictionary */
5543 PyDict_DelItem(_PyPopenProcs, fileObj);
5545 if (PyDict_Size(_PyPopenProcs) == 0) {
5546 Py_DECREF(_PyPopenProcs);
5547 _PyPopenProcs = NULL;
5550 } /* if object retrieval ok */
5552 Py_XDECREF(fileObj);
5553 } /* if _PyPopenProcs */
5555 #ifdef WITH_THREAD
5556 PyGILState_Release(state);
5557 #endif
5558 return result;
5561 #else /* which OS? */
5562 static PyObject *
5563 posix_popen(PyObject *self, PyObject *args)
5565 char *name;
5566 char *mode = "r";
5567 int bufsize = -1;
5568 FILE *fp;
5569 PyObject *f;
5570 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5571 return NULL;
5572 /* Strip mode of binary or text modifiers */
5573 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5574 mode = "r";
5575 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5576 mode = "w";
5577 Py_BEGIN_ALLOW_THREADS
5578 fp = popen(name, mode);
5579 Py_END_ALLOW_THREADS
5580 if (fp == NULL)
5581 return posix_error();
5582 f = PyFile_FromFile(fp, name, mode, pclose);
5583 if (f != NULL)
5584 PyFile_SetBufSize(f, bufsize);
5585 return f;
5588 #endif /* PYOS_??? */
5589 #endif /* HAVE_POPEN */
5592 #ifdef HAVE_SETUID
5593 PyDoc_STRVAR(posix_setuid__doc__,
5594 "setuid(uid)\n\n\
5595 Set the current process's user id.");
5597 static PyObject *
5598 posix_setuid(PyObject *self, PyObject *args)
5600 long uid_arg;
5601 uid_t uid;
5602 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5603 return NULL;
5604 uid = uid_arg;
5605 if (uid != uid_arg) {
5606 PyErr_SetString(PyExc_OverflowError, "user id too big");
5607 return NULL;
5609 if (setuid(uid) < 0)
5610 return posix_error();
5611 Py_INCREF(Py_None);
5612 return Py_None;
5614 #endif /* HAVE_SETUID */
5617 #ifdef HAVE_SETEUID
5618 PyDoc_STRVAR(posix_seteuid__doc__,
5619 "seteuid(uid)\n\n\
5620 Set the current process's effective user id.");
5622 static PyObject *
5623 posix_seteuid (PyObject *self, PyObject *args)
5625 long euid_arg;
5626 uid_t euid;
5627 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5628 return NULL;
5629 euid = euid_arg;
5630 if (euid != euid_arg) {
5631 PyErr_SetString(PyExc_OverflowError, "user id too big");
5632 return NULL;
5634 if (seteuid(euid) < 0) {
5635 return posix_error();
5636 } else {
5637 Py_INCREF(Py_None);
5638 return Py_None;
5641 #endif /* HAVE_SETEUID */
5643 #ifdef HAVE_SETEGID
5644 PyDoc_STRVAR(posix_setegid__doc__,
5645 "setegid(gid)\n\n\
5646 Set the current process's effective group id.");
5648 static PyObject *
5649 posix_setegid (PyObject *self, PyObject *args)
5651 long egid_arg;
5652 gid_t egid;
5653 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5654 return NULL;
5655 egid = egid_arg;
5656 if (egid != egid_arg) {
5657 PyErr_SetString(PyExc_OverflowError, "group id too big");
5658 return NULL;
5660 if (setegid(egid) < 0) {
5661 return posix_error();
5662 } else {
5663 Py_INCREF(Py_None);
5664 return Py_None;
5667 #endif /* HAVE_SETEGID */
5669 #ifdef HAVE_SETREUID
5670 PyDoc_STRVAR(posix_setreuid__doc__,
5671 "setreuid(ruid, euid)\n\n\
5672 Set the current process's real and effective user ids.");
5674 static PyObject *
5675 posix_setreuid (PyObject *self, PyObject *args)
5677 long ruid_arg, euid_arg;
5678 uid_t ruid, euid;
5679 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5680 return NULL;
5681 ruid = ruid_arg;
5682 euid = euid_arg;
5683 if (euid != euid_arg || ruid != ruid_arg) {
5684 PyErr_SetString(PyExc_OverflowError, "user id too big");
5685 return NULL;
5687 if (setreuid(ruid, euid) < 0) {
5688 return posix_error();
5689 } else {
5690 Py_INCREF(Py_None);
5691 return Py_None;
5694 #endif /* HAVE_SETREUID */
5696 #ifdef HAVE_SETREGID
5697 PyDoc_STRVAR(posix_setregid__doc__,
5698 "setregid(rgid, egid)\n\n\
5699 Set the current process's real and effective group ids.");
5701 static PyObject *
5702 posix_setregid (PyObject *self, PyObject *args)
5704 long rgid_arg, egid_arg;
5705 gid_t rgid, egid;
5706 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5707 return NULL;
5708 rgid = rgid_arg;
5709 egid = egid_arg;
5710 if (egid != egid_arg || rgid != rgid_arg) {
5711 PyErr_SetString(PyExc_OverflowError, "group id too big");
5712 return NULL;
5714 if (setregid(rgid, egid) < 0) {
5715 return posix_error();
5716 } else {
5717 Py_INCREF(Py_None);
5718 return Py_None;
5721 #endif /* HAVE_SETREGID */
5723 #ifdef HAVE_SETGID
5724 PyDoc_STRVAR(posix_setgid__doc__,
5725 "setgid(gid)\n\n\
5726 Set the current process's group id.");
5728 static PyObject *
5729 posix_setgid(PyObject *self, PyObject *args)
5731 long gid_arg;
5732 gid_t gid;
5733 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
5734 return NULL;
5735 gid = gid_arg;
5736 if (gid != gid_arg) {
5737 PyErr_SetString(PyExc_OverflowError, "group id too big");
5738 return NULL;
5740 if (setgid(gid) < 0)
5741 return posix_error();
5742 Py_INCREF(Py_None);
5743 return Py_None;
5745 #endif /* HAVE_SETGID */
5747 #ifdef HAVE_SETGROUPS
5748 PyDoc_STRVAR(posix_setgroups__doc__,
5749 "setgroups(list)\n\n\
5750 Set the groups of the current process to list.");
5752 static PyObject *
5753 posix_setgroups(PyObject *self, PyObject *groups)
5755 int i, len;
5756 gid_t grouplist[MAX_GROUPS];
5758 if (!PySequence_Check(groups)) {
5759 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5760 return NULL;
5762 len = PySequence_Size(groups);
5763 if (len > MAX_GROUPS) {
5764 PyErr_SetString(PyExc_ValueError, "too many groups");
5765 return NULL;
5767 for(i = 0; i < len; i++) {
5768 PyObject *elem;
5769 elem = PySequence_GetItem(groups, i);
5770 if (!elem)
5771 return NULL;
5772 if (!PyInt_Check(elem)) {
5773 if (!PyLong_Check(elem)) {
5774 PyErr_SetString(PyExc_TypeError,
5775 "groups must be integers");
5776 Py_DECREF(elem);
5777 return NULL;
5778 } else {
5779 unsigned long x = PyLong_AsUnsignedLong(elem);
5780 if (PyErr_Occurred()) {
5781 PyErr_SetString(PyExc_TypeError,
5782 "group id too big");
5783 Py_DECREF(elem);
5784 return NULL;
5786 grouplist[i] = x;
5787 /* read back to see if it fits in gid_t */
5788 if (grouplist[i] != x) {
5789 PyErr_SetString(PyExc_TypeError,
5790 "group id too big");
5791 Py_DECREF(elem);
5792 return NULL;
5795 } else {
5796 long x = PyInt_AsLong(elem);
5797 grouplist[i] = x;
5798 if (grouplist[i] != x) {
5799 PyErr_SetString(PyExc_TypeError,
5800 "group id too big");
5801 Py_DECREF(elem);
5802 return NULL;
5805 Py_DECREF(elem);
5808 if (setgroups(len, grouplist) < 0)
5809 return posix_error();
5810 Py_INCREF(Py_None);
5811 return Py_None;
5813 #endif /* HAVE_SETGROUPS */
5815 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5816 static PyObject *
5817 wait_helper(pid_t pid, int status, struct rusage *ru)
5819 PyObject *result;
5820 static PyObject *struct_rusage;
5822 if (pid == -1)
5823 return posix_error();
5825 if (struct_rusage == NULL) {
5826 PyObject *m = PyImport_ImportModuleNoBlock("resource");
5827 if (m == NULL)
5828 return NULL;
5829 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5830 Py_DECREF(m);
5831 if (struct_rusage == NULL)
5832 return NULL;
5835 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5836 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5837 if (!result)
5838 return NULL;
5840 #ifndef doubletime
5841 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5842 #endif
5844 PyStructSequence_SET_ITEM(result, 0,
5845 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5846 PyStructSequence_SET_ITEM(result, 1,
5847 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5848 #define SET_INT(result, index, value)\
5849 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5850 SET_INT(result, 2, ru->ru_maxrss);
5851 SET_INT(result, 3, ru->ru_ixrss);
5852 SET_INT(result, 4, ru->ru_idrss);
5853 SET_INT(result, 5, ru->ru_isrss);
5854 SET_INT(result, 6, ru->ru_minflt);
5855 SET_INT(result, 7, ru->ru_majflt);
5856 SET_INT(result, 8, ru->ru_nswap);
5857 SET_INT(result, 9, ru->ru_inblock);
5858 SET_INT(result, 10, ru->ru_oublock);
5859 SET_INT(result, 11, ru->ru_msgsnd);
5860 SET_INT(result, 12, ru->ru_msgrcv);
5861 SET_INT(result, 13, ru->ru_nsignals);
5862 SET_INT(result, 14, ru->ru_nvcsw);
5863 SET_INT(result, 15, ru->ru_nivcsw);
5864 #undef SET_INT
5866 if (PyErr_Occurred()) {
5867 Py_DECREF(result);
5868 return NULL;
5871 return Py_BuildValue("iiN", pid, status, result);
5873 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5875 #ifdef HAVE_WAIT3
5876 PyDoc_STRVAR(posix_wait3__doc__,
5877 "wait3(options) -> (pid, status, rusage)\n\n\
5878 Wait for completion of a child process.");
5880 static PyObject *
5881 posix_wait3(PyObject *self, PyObject *args)
5883 pid_t pid;
5884 int options;
5885 struct rusage ru;
5886 WAIT_TYPE status;
5887 WAIT_STATUS_INT(status) = 0;
5889 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5890 return NULL;
5892 Py_BEGIN_ALLOW_THREADS
5893 pid = wait3(&status, options, &ru);
5894 Py_END_ALLOW_THREADS
5896 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5898 #endif /* HAVE_WAIT3 */
5900 #ifdef HAVE_WAIT4
5901 PyDoc_STRVAR(posix_wait4__doc__,
5902 "wait4(pid, options) -> (pid, status, rusage)\n\n\
5903 Wait for completion of a given child process.");
5905 static PyObject *
5906 posix_wait4(PyObject *self, PyObject *args)
5908 pid_t pid;
5909 int options;
5910 struct rusage ru;
5911 WAIT_TYPE status;
5912 WAIT_STATUS_INT(status) = 0;
5914 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5915 return NULL;
5917 Py_BEGIN_ALLOW_THREADS
5918 pid = wait4(pid, &status, options, &ru);
5919 Py_END_ALLOW_THREADS
5921 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5923 #endif /* HAVE_WAIT4 */
5925 #ifdef HAVE_WAITPID
5926 PyDoc_STRVAR(posix_waitpid__doc__,
5927 "waitpid(pid, options) -> (pid, status)\n\n\
5928 Wait for completion of a given child process.");
5930 static PyObject *
5931 posix_waitpid(PyObject *self, PyObject *args)
5933 pid_t pid;
5934 int options;
5935 WAIT_TYPE status;
5936 WAIT_STATUS_INT(status) = 0;
5938 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5939 return NULL;
5940 Py_BEGIN_ALLOW_THREADS
5941 pid = waitpid(pid, &status, options);
5942 Py_END_ALLOW_THREADS
5943 if (pid == -1)
5944 return posix_error();
5946 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
5949 #elif defined(HAVE_CWAIT)
5951 /* MS C has a variant of waitpid() that's usable for most purposes. */
5952 PyDoc_STRVAR(posix_waitpid__doc__,
5953 "waitpid(pid, options) -> (pid, status << 8)\n\n"
5954 "Wait for completion of a given process. options is ignored on Windows.");
5956 static PyObject *
5957 posix_waitpid(PyObject *self, PyObject *args)
5959 Py_intptr_t pid;
5960 int status, options;
5962 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5963 return NULL;
5964 Py_BEGIN_ALLOW_THREADS
5965 pid = _cwait(&status, pid, options);
5966 Py_END_ALLOW_THREADS
5967 if (pid == -1)
5968 return posix_error();
5970 /* shift the status left a byte so this is more like the POSIX waitpid */
5971 return Py_BuildValue("ii", pid, status << 8);
5973 #endif /* HAVE_WAITPID || HAVE_CWAIT */
5975 #ifdef HAVE_WAIT
5976 PyDoc_STRVAR(posix_wait__doc__,
5977 "wait() -> (pid, status)\n\n\
5978 Wait for completion of a child process.");
5980 static PyObject *
5981 posix_wait(PyObject *self, PyObject *noargs)
5983 pid_t pid;
5984 WAIT_TYPE status;
5985 WAIT_STATUS_INT(status) = 0;
5987 Py_BEGIN_ALLOW_THREADS
5988 pid = wait(&status);
5989 Py_END_ALLOW_THREADS
5990 if (pid == -1)
5991 return posix_error();
5993 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
5995 #endif
5998 PyDoc_STRVAR(posix_lstat__doc__,
5999 "lstat(path) -> stat result\n\n\
6000 Like stat(path), but do not follow symbolic links.");
6002 static PyObject *
6003 posix_lstat(PyObject *self, PyObject *args)
6005 #ifdef HAVE_LSTAT
6006 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
6007 #else /* !HAVE_LSTAT */
6008 #ifdef MS_WINDOWS
6009 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
6010 #else
6011 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
6012 #endif
6013 #endif /* !HAVE_LSTAT */
6017 #ifdef HAVE_READLINK
6018 PyDoc_STRVAR(posix_readlink__doc__,
6019 "readlink(path) -> path\n\n\
6020 Return a string representing the path to which the symbolic link points.");
6022 static PyObject *
6023 posix_readlink(PyObject *self, PyObject *args)
6025 PyObject* v;
6026 char buf[MAXPATHLEN];
6027 char *path;
6028 int n;
6029 #ifdef Py_USING_UNICODE
6030 int arg_is_unicode = 0;
6031 #endif
6033 if (!PyArg_ParseTuple(args, "et:readlink",
6034 Py_FileSystemDefaultEncoding, &path))
6035 return NULL;
6036 #ifdef Py_USING_UNICODE
6037 v = PySequence_GetItem(args, 0);
6038 if (v == NULL) {
6039 PyMem_Free(path);
6040 return NULL;
6043 if (PyUnicode_Check(v)) {
6044 arg_is_unicode = 1;
6046 Py_DECREF(v);
6047 #endif
6049 Py_BEGIN_ALLOW_THREADS
6050 n = readlink(path, buf, (int) sizeof buf);
6051 Py_END_ALLOW_THREADS
6052 if (n < 0)
6053 return posix_error_with_allocated_filename(path);
6055 PyMem_Free(path);
6056 v = PyString_FromStringAndSize(buf, n);
6057 #ifdef Py_USING_UNICODE
6058 if (arg_is_unicode) {
6059 PyObject *w;
6061 w = PyUnicode_FromEncodedObject(v,
6062 Py_FileSystemDefaultEncoding,
6063 "strict");
6064 if (w != NULL) {
6065 Py_DECREF(v);
6066 v = w;
6068 else {
6069 /* fall back to the original byte string, as
6070 discussed in patch #683592 */
6071 PyErr_Clear();
6074 #endif
6075 return v;
6077 #endif /* HAVE_READLINK */
6080 #ifdef HAVE_SYMLINK
6081 PyDoc_STRVAR(posix_symlink__doc__,
6082 "symlink(src, dst)\n\n\
6083 Create a symbolic link pointing to src named dst.");
6085 static PyObject *
6086 posix_symlink(PyObject *self, PyObject *args)
6088 return posix_2str(args, "etet:symlink", symlink);
6090 #endif /* HAVE_SYMLINK */
6093 #ifdef HAVE_TIMES
6094 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
6095 static long
6096 system_uptime(void)
6098 ULONG value = 0;
6100 Py_BEGIN_ALLOW_THREADS
6101 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6102 Py_END_ALLOW_THREADS
6104 return value;
6107 static PyObject *
6108 posix_times(PyObject *self, PyObject *noargs)
6110 /* Currently Only Uptime is Provided -- Others Later */
6111 return Py_BuildValue("ddddd",
6112 (double)0 /* t.tms_utime / HZ */,
6113 (double)0 /* t.tms_stime / HZ */,
6114 (double)0 /* t.tms_cutime / HZ */,
6115 (double)0 /* t.tms_cstime / HZ */,
6116 (double)system_uptime() / 1000);
6118 #else /* not OS2 */
6119 #define NEED_TICKS_PER_SECOND
6120 static long ticks_per_second = -1;
6121 static PyObject *
6122 posix_times(PyObject *self, PyObject *noargs)
6124 struct tms t;
6125 clock_t c;
6126 errno = 0;
6127 c = times(&t);
6128 if (c == (clock_t) -1)
6129 return posix_error();
6130 return Py_BuildValue("ddddd",
6131 (double)t.tms_utime / ticks_per_second,
6132 (double)t.tms_stime / ticks_per_second,
6133 (double)t.tms_cutime / ticks_per_second,
6134 (double)t.tms_cstime / ticks_per_second,
6135 (double)c / ticks_per_second);
6137 #endif /* not OS2 */
6138 #endif /* HAVE_TIMES */
6141 #ifdef MS_WINDOWS
6142 #define HAVE_TIMES /* so the method table will pick it up */
6143 static PyObject *
6144 posix_times(PyObject *self, PyObject *noargs)
6146 FILETIME create, exit, kernel, user;
6147 HANDLE hProc;
6148 hProc = GetCurrentProcess();
6149 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6150 /* The fields of a FILETIME structure are the hi and lo part
6151 of a 64-bit value expressed in 100 nanosecond units.
6152 1e7 is one second in such units; 1e-7 the inverse.
6153 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6155 return Py_BuildValue(
6156 "ddddd",
6157 (double)(user.dwHighDateTime*429.4967296 +
6158 user.dwLowDateTime*1e-7),
6159 (double)(kernel.dwHighDateTime*429.4967296 +
6160 kernel.dwLowDateTime*1e-7),
6161 (double)0,
6162 (double)0,
6163 (double)0);
6165 #endif /* MS_WINDOWS */
6167 #ifdef HAVE_TIMES
6168 PyDoc_STRVAR(posix_times__doc__,
6169 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
6170 Return a tuple of floating point numbers indicating process times.");
6171 #endif
6174 #ifdef HAVE_GETSID
6175 PyDoc_STRVAR(posix_getsid__doc__,
6176 "getsid(pid) -> sid\n\n\
6177 Call the system call getsid().");
6179 static PyObject *
6180 posix_getsid(PyObject *self, PyObject *args)
6182 pid_t pid;
6183 int sid;
6184 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
6185 return NULL;
6186 sid = getsid(pid);
6187 if (sid < 0)
6188 return posix_error();
6189 return PyInt_FromLong((long)sid);
6191 #endif /* HAVE_GETSID */
6194 #ifdef HAVE_SETSID
6195 PyDoc_STRVAR(posix_setsid__doc__,
6196 "setsid()\n\n\
6197 Call the system call setsid().");
6199 static PyObject *
6200 posix_setsid(PyObject *self, PyObject *noargs)
6202 if (setsid() < 0)
6203 return posix_error();
6204 Py_INCREF(Py_None);
6205 return Py_None;
6207 #endif /* HAVE_SETSID */
6209 #ifdef HAVE_SETPGID
6210 PyDoc_STRVAR(posix_setpgid__doc__,
6211 "setpgid(pid, pgrp)\n\n\
6212 Call the system call setpgid().");
6214 static PyObject *
6215 posix_setpgid(PyObject *self, PyObject *args)
6217 pid_t pid;
6218 int pgrp;
6219 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
6220 return NULL;
6221 if (setpgid(pid, pgrp) < 0)
6222 return posix_error();
6223 Py_INCREF(Py_None);
6224 return Py_None;
6226 #endif /* HAVE_SETPGID */
6229 #ifdef HAVE_TCGETPGRP
6230 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
6231 "tcgetpgrp(fd) -> pgid\n\n\
6232 Return the process group associated with the terminal given by a fd.");
6234 static PyObject *
6235 posix_tcgetpgrp(PyObject *self, PyObject *args)
6237 int fd;
6238 pid_t pgid;
6239 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6240 return NULL;
6241 pgid = tcgetpgrp(fd);
6242 if (pgid < 0)
6243 return posix_error();
6244 return PyInt_FromLong((long)pgid);
6246 #endif /* HAVE_TCGETPGRP */
6249 #ifdef HAVE_TCSETPGRP
6250 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
6251 "tcsetpgrp(fd, pgid)\n\n\
6252 Set the process group associated with the terminal given by a fd.");
6254 static PyObject *
6255 posix_tcsetpgrp(PyObject *self, PyObject *args)
6257 int fd, pgid;
6258 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
6259 return NULL;
6260 if (tcsetpgrp(fd, pgid) < 0)
6261 return posix_error();
6262 Py_INCREF(Py_None);
6263 return Py_None;
6265 #endif /* HAVE_TCSETPGRP */
6267 /* Functions acting on file descriptors */
6269 PyDoc_STRVAR(posix_open__doc__,
6270 "open(filename, flag [, mode=0777]) -> fd\n\n\
6271 Open a file (for low level IO).");
6273 static PyObject *
6274 posix_open(PyObject *self, PyObject *args)
6276 char *file = NULL;
6277 int flag;
6278 int mode = 0777;
6279 int fd;
6281 #ifdef MS_WINDOWS
6282 if (unicode_file_names()) {
6283 PyUnicodeObject *po;
6284 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6285 Py_BEGIN_ALLOW_THREADS
6286 /* PyUnicode_AS_UNICODE OK without thread
6287 lock as it is a simple dereference. */
6288 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6289 Py_END_ALLOW_THREADS
6290 if (fd < 0)
6291 return posix_error();
6292 return PyInt_FromLong((long)fd);
6294 /* Drop the argument parsing error as narrow strings
6295 are also valid. */
6296 PyErr_Clear();
6298 #endif
6300 if (!PyArg_ParseTuple(args, "eti|i",
6301 Py_FileSystemDefaultEncoding, &file,
6302 &flag, &mode))
6303 return NULL;
6305 Py_BEGIN_ALLOW_THREADS
6306 fd = open(file, flag, mode);
6307 Py_END_ALLOW_THREADS
6308 if (fd < 0)
6309 return posix_error_with_allocated_filename(file);
6310 PyMem_Free(file);
6311 return PyInt_FromLong((long)fd);
6315 PyDoc_STRVAR(posix_close__doc__,
6316 "close(fd)\n\n\
6317 Close a file descriptor (for low level IO).");
6319 static PyObject *
6320 posix_close(PyObject *self, PyObject *args)
6322 int fd, res;
6323 if (!PyArg_ParseTuple(args, "i:close", &fd))
6324 return NULL;
6325 if (!_PyVerify_fd(fd))
6326 return posix_error();
6327 Py_BEGIN_ALLOW_THREADS
6328 res = close(fd);
6329 Py_END_ALLOW_THREADS
6330 if (res < 0)
6331 return posix_error();
6332 Py_INCREF(Py_None);
6333 return Py_None;
6337 PyDoc_STRVAR(posix_closerange__doc__,
6338 "closerange(fd_low, fd_high)\n\n\
6339 Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6341 static PyObject *
6342 posix_closerange(PyObject *self, PyObject *args)
6344 int fd_from, fd_to, i;
6345 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6346 return NULL;
6347 Py_BEGIN_ALLOW_THREADS
6348 for (i = fd_from; i < fd_to; i++)
6349 if (_PyVerify_fd(i))
6350 close(i);
6351 Py_END_ALLOW_THREADS
6352 Py_RETURN_NONE;
6356 PyDoc_STRVAR(posix_dup__doc__,
6357 "dup(fd) -> fd2\n\n\
6358 Return a duplicate of a file descriptor.");
6360 static PyObject *
6361 posix_dup(PyObject *self, PyObject *args)
6363 int fd;
6364 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6365 return NULL;
6366 if (!_PyVerify_fd(fd))
6367 return posix_error();
6368 Py_BEGIN_ALLOW_THREADS
6369 fd = dup(fd);
6370 Py_END_ALLOW_THREADS
6371 if (fd < 0)
6372 return posix_error();
6373 return PyInt_FromLong((long)fd);
6377 PyDoc_STRVAR(posix_dup2__doc__,
6378 "dup2(old_fd, new_fd)\n\n\
6379 Duplicate file descriptor.");
6381 static PyObject *
6382 posix_dup2(PyObject *self, PyObject *args)
6384 int fd, fd2, res;
6385 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6386 return NULL;
6387 if (!_PyVerify_fd_dup2(fd, fd2))
6388 return posix_error();
6389 Py_BEGIN_ALLOW_THREADS
6390 res = dup2(fd, fd2);
6391 Py_END_ALLOW_THREADS
6392 if (res < 0)
6393 return posix_error();
6394 Py_INCREF(Py_None);
6395 return Py_None;
6399 PyDoc_STRVAR(posix_lseek__doc__,
6400 "lseek(fd, pos, how) -> newpos\n\n\
6401 Set the current position of a file descriptor.");
6403 static PyObject *
6404 posix_lseek(PyObject *self, PyObject *args)
6406 int fd, how;
6407 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6408 PY_LONG_LONG pos, res;
6409 #else
6410 off_t pos, res;
6411 #endif
6412 PyObject *posobj;
6413 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6414 return NULL;
6415 #ifdef SEEK_SET
6416 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6417 switch (how) {
6418 case 0: how = SEEK_SET; break;
6419 case 1: how = SEEK_CUR; break;
6420 case 2: how = SEEK_END; break;
6422 #endif /* SEEK_END */
6424 #if !defined(HAVE_LARGEFILE_SUPPORT)
6425 pos = PyInt_AsLong(posobj);
6426 #else
6427 pos = PyLong_Check(posobj) ?
6428 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6429 #endif
6430 if (PyErr_Occurred())
6431 return NULL;
6433 if (!_PyVerify_fd(fd))
6434 return posix_error();
6435 Py_BEGIN_ALLOW_THREADS
6436 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6437 res = _lseeki64(fd, pos, how);
6438 #else
6439 res = lseek(fd, pos, how);
6440 #endif
6441 Py_END_ALLOW_THREADS
6442 if (res < 0)
6443 return posix_error();
6445 #if !defined(HAVE_LARGEFILE_SUPPORT)
6446 return PyInt_FromLong(res);
6447 #else
6448 return PyLong_FromLongLong(res);
6449 #endif
6453 PyDoc_STRVAR(posix_read__doc__,
6454 "read(fd, buffersize) -> string\n\n\
6455 Read a file descriptor.");
6457 static PyObject *
6458 posix_read(PyObject *self, PyObject *args)
6460 int fd, size, n;
6461 PyObject *buffer;
6462 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6463 return NULL;
6464 if (size < 0) {
6465 errno = EINVAL;
6466 return posix_error();
6468 buffer = PyString_FromStringAndSize((char *)NULL, size);
6469 if (buffer == NULL)
6470 return NULL;
6471 if (!_PyVerify_fd(fd))
6472 return posix_error();
6473 Py_BEGIN_ALLOW_THREADS
6474 n = read(fd, PyString_AsString(buffer), size);
6475 Py_END_ALLOW_THREADS
6476 if (n < 0) {
6477 Py_DECREF(buffer);
6478 return posix_error();
6480 if (n != size)
6481 _PyString_Resize(&buffer, n);
6482 return buffer;
6486 PyDoc_STRVAR(posix_write__doc__,
6487 "write(fd, string) -> byteswritten\n\n\
6488 Write a string to a file descriptor.");
6490 static PyObject *
6491 posix_write(PyObject *self, PyObject *args)
6493 Py_buffer pbuf;
6494 int fd;
6495 Py_ssize_t size;
6497 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6498 return NULL;
6499 if (!_PyVerify_fd(fd))
6500 return posix_error();
6501 Py_BEGIN_ALLOW_THREADS
6502 size = write(fd, pbuf.buf, (size_t)pbuf.len);
6503 Py_END_ALLOW_THREADS
6504 PyBuffer_Release(&pbuf);
6505 if (size < 0)
6506 return posix_error();
6507 return PyInt_FromSsize_t(size);
6511 PyDoc_STRVAR(posix_fstat__doc__,
6512 "fstat(fd) -> stat result\n\n\
6513 Like stat(), but for an open file descriptor.");
6515 static PyObject *
6516 posix_fstat(PyObject *self, PyObject *args)
6518 int fd;
6519 STRUCT_STAT st;
6520 int res;
6521 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6522 return NULL;
6523 #ifdef __VMS
6524 /* on OpenVMS we must ensure that all bytes are written to the file */
6525 fsync(fd);
6526 #endif
6527 if (!_PyVerify_fd(fd))
6528 return posix_error();
6529 Py_BEGIN_ALLOW_THREADS
6530 res = FSTAT(fd, &st);
6531 Py_END_ALLOW_THREADS
6532 if (res != 0) {
6533 #ifdef MS_WINDOWS
6534 return win32_error("fstat", NULL);
6535 #else
6536 return posix_error();
6537 #endif
6540 return _pystat_fromstructstat(&st);
6544 PyDoc_STRVAR(posix_fdopen__doc__,
6545 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
6546 Return an open file object connected to a file descriptor.");
6548 static PyObject *
6549 posix_fdopen(PyObject *self, PyObject *args)
6551 int fd;
6552 char *orgmode = "r";
6553 int bufsize = -1;
6554 FILE *fp;
6555 PyObject *f;
6556 char *mode;
6557 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6558 return NULL;
6560 /* Sanitize mode. See fileobject.c */
6561 mode = PyMem_MALLOC(strlen(orgmode)+3);
6562 if (!mode) {
6563 PyErr_NoMemory();
6564 return NULL;
6566 strcpy(mode, orgmode);
6567 if (_PyFile_SanitizeMode(mode)) {
6568 PyMem_FREE(mode);
6569 return NULL;
6571 if (!_PyVerify_fd(fd))
6572 return posix_error();
6573 Py_BEGIN_ALLOW_THREADS
6574 #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6575 if (mode[0] == 'a') {
6576 /* try to make sure the O_APPEND flag is set */
6577 int flags;
6578 flags = fcntl(fd, F_GETFL);
6579 if (flags != -1)
6580 fcntl(fd, F_SETFL, flags | O_APPEND);
6581 fp = fdopen(fd, mode);
6582 if (fp == NULL && flags != -1)
6583 /* restore old mode if fdopen failed */
6584 fcntl(fd, F_SETFL, flags);
6585 } else {
6586 fp = fdopen(fd, mode);
6588 #else
6589 fp = fdopen(fd, mode);
6590 #endif
6591 Py_END_ALLOW_THREADS
6592 PyMem_FREE(mode);
6593 if (fp == NULL)
6594 return posix_error();
6595 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
6596 if (f != NULL)
6597 PyFile_SetBufSize(f, bufsize);
6598 return f;
6601 PyDoc_STRVAR(posix_isatty__doc__,
6602 "isatty(fd) -> bool\n\n\
6603 Return True if the file descriptor 'fd' is an open file descriptor\n\
6604 connected to the slave end of a terminal.");
6606 static PyObject *
6607 posix_isatty(PyObject *self, PyObject *args)
6609 int fd;
6610 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6611 return NULL;
6612 if (!_PyVerify_fd(fd))
6613 return PyBool_FromLong(0);
6614 return PyBool_FromLong(isatty(fd));
6617 #ifdef HAVE_PIPE
6618 PyDoc_STRVAR(posix_pipe__doc__,
6619 "pipe() -> (read_end, write_end)\n\n\
6620 Create a pipe.");
6622 static PyObject *
6623 posix_pipe(PyObject *self, PyObject *noargs)
6625 #if defined(PYOS_OS2)
6626 HFILE read, write;
6627 APIRET rc;
6629 Py_BEGIN_ALLOW_THREADS
6630 rc = DosCreatePipe( &read, &write, 4096);
6631 Py_END_ALLOW_THREADS
6632 if (rc != NO_ERROR)
6633 return os2_error(rc);
6635 return Py_BuildValue("(ii)", read, write);
6636 #else
6637 #if !defined(MS_WINDOWS)
6638 int fds[2];
6639 int res;
6640 Py_BEGIN_ALLOW_THREADS
6641 res = pipe(fds);
6642 Py_END_ALLOW_THREADS
6643 if (res != 0)
6644 return posix_error();
6645 return Py_BuildValue("(ii)", fds[0], fds[1]);
6646 #else /* MS_WINDOWS */
6647 HANDLE read, write;
6648 int read_fd, write_fd;
6649 BOOL ok;
6650 Py_BEGIN_ALLOW_THREADS
6651 ok = CreatePipe(&read, &write, NULL, 0);
6652 Py_END_ALLOW_THREADS
6653 if (!ok)
6654 return win32_error("CreatePipe", NULL);
6655 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6656 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6657 return Py_BuildValue("(ii)", read_fd, write_fd);
6658 #endif /* MS_WINDOWS */
6659 #endif
6661 #endif /* HAVE_PIPE */
6664 #ifdef HAVE_MKFIFO
6665 PyDoc_STRVAR(posix_mkfifo__doc__,
6666 "mkfifo(filename [, mode=0666])\n\n\
6667 Create a FIFO (a POSIX named pipe).");
6669 static PyObject *
6670 posix_mkfifo(PyObject *self, PyObject *args)
6672 char *filename;
6673 int mode = 0666;
6674 int res;
6675 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6676 return NULL;
6677 Py_BEGIN_ALLOW_THREADS
6678 res = mkfifo(filename, mode);
6679 Py_END_ALLOW_THREADS
6680 if (res < 0)
6681 return posix_error();
6682 Py_INCREF(Py_None);
6683 return Py_None;
6685 #endif
6688 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
6689 PyDoc_STRVAR(posix_mknod__doc__,
6690 "mknod(filename [, mode=0600, device])\n\n\
6691 Create a filesystem node (file, device special file or named pipe)\n\
6692 named filename. mode specifies both the permissions to use and the\n\
6693 type of node to be created, being combined (bitwise OR) with one of\n\
6694 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
6695 device defines the newly created device special file (probably using\n\
6696 os.makedev()), otherwise it is ignored.");
6699 static PyObject *
6700 posix_mknod(PyObject *self, PyObject *args)
6702 char *filename;
6703 int mode = 0600;
6704 int device = 0;
6705 int res;
6706 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6707 return NULL;
6708 Py_BEGIN_ALLOW_THREADS
6709 res = mknod(filename, mode, device);
6710 Py_END_ALLOW_THREADS
6711 if (res < 0)
6712 return posix_error();
6713 Py_INCREF(Py_None);
6714 return Py_None;
6716 #endif
6718 #ifdef HAVE_DEVICE_MACROS
6719 PyDoc_STRVAR(posix_major__doc__,
6720 "major(device) -> major number\n\
6721 Extracts a device major number from a raw device number.");
6723 static PyObject *
6724 posix_major(PyObject *self, PyObject *args)
6726 int device;
6727 if (!PyArg_ParseTuple(args, "i:major", &device))
6728 return NULL;
6729 return PyInt_FromLong((long)major(device));
6732 PyDoc_STRVAR(posix_minor__doc__,
6733 "minor(device) -> minor number\n\
6734 Extracts a device minor number from a raw device number.");
6736 static PyObject *
6737 posix_minor(PyObject *self, PyObject *args)
6739 int device;
6740 if (!PyArg_ParseTuple(args, "i:minor", &device))
6741 return NULL;
6742 return PyInt_FromLong((long)minor(device));
6745 PyDoc_STRVAR(posix_makedev__doc__,
6746 "makedev(major, minor) -> device number\n\
6747 Composes a raw device number from the major and minor device numbers.");
6749 static PyObject *
6750 posix_makedev(PyObject *self, PyObject *args)
6752 int major, minor;
6753 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6754 return NULL;
6755 return PyInt_FromLong((long)makedev(major, minor));
6757 #endif /* device macros */
6760 #ifdef HAVE_FTRUNCATE
6761 PyDoc_STRVAR(posix_ftruncate__doc__,
6762 "ftruncate(fd, length)\n\n\
6763 Truncate a file to a specified length.");
6765 static PyObject *
6766 posix_ftruncate(PyObject *self, PyObject *args)
6768 int fd;
6769 off_t length;
6770 int res;
6771 PyObject *lenobj;
6773 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6774 return NULL;
6776 #if !defined(HAVE_LARGEFILE_SUPPORT)
6777 length = PyInt_AsLong(lenobj);
6778 #else
6779 length = PyLong_Check(lenobj) ?
6780 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6781 #endif
6782 if (PyErr_Occurred())
6783 return NULL;
6785 Py_BEGIN_ALLOW_THREADS
6786 res = ftruncate(fd, length);
6787 Py_END_ALLOW_THREADS
6788 if (res < 0)
6789 return posix_error();
6790 Py_INCREF(Py_None);
6791 return Py_None;
6793 #endif
6795 #ifdef HAVE_PUTENV
6796 PyDoc_STRVAR(posix_putenv__doc__,
6797 "putenv(key, value)\n\n\
6798 Change or add an environment variable.");
6800 /* Save putenv() parameters as values here, so we can collect them when they
6801 * get re-set with another call for the same key. */
6802 static PyObject *posix_putenv_garbage;
6804 static PyObject *
6805 posix_putenv(PyObject *self, PyObject *args)
6807 char *s1, *s2;
6808 char *newenv;
6809 PyObject *newstr;
6810 size_t len;
6812 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6813 return NULL;
6815 #if defined(PYOS_OS2)
6816 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6817 APIRET rc;
6819 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6820 if (rc != NO_ERROR)
6821 return os2_error(rc);
6823 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6824 APIRET rc;
6826 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6827 if (rc != NO_ERROR)
6828 return os2_error(rc);
6829 } else {
6830 #endif
6832 /* XXX This can leak memory -- not easy to fix :-( */
6833 len = strlen(s1) + strlen(s2) + 2;
6834 /* len includes space for a trailing \0; the size arg to
6835 PyString_FromStringAndSize does not count that */
6836 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
6837 if (newstr == NULL)
6838 return PyErr_NoMemory();
6839 newenv = PyString_AS_STRING(newstr);
6840 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6841 if (putenv(newenv)) {
6842 Py_DECREF(newstr);
6843 posix_error();
6844 return NULL;
6846 /* Install the first arg and newstr in posix_putenv_garbage;
6847 * this will cause previous value to be collected. This has to
6848 * happen after the real putenv() call because the old value
6849 * was still accessible until then. */
6850 if (PyDict_SetItem(posix_putenv_garbage,
6851 PyTuple_GET_ITEM(args, 0), newstr)) {
6852 /* really not much we can do; just leak */
6853 PyErr_Clear();
6855 else {
6856 Py_DECREF(newstr);
6859 #if defined(PYOS_OS2)
6861 #endif
6862 Py_INCREF(Py_None);
6863 return Py_None;
6865 #endif /* putenv */
6867 #ifdef HAVE_UNSETENV
6868 PyDoc_STRVAR(posix_unsetenv__doc__,
6869 "unsetenv(key)\n\n\
6870 Delete an environment variable.");
6872 static PyObject *
6873 posix_unsetenv(PyObject *self, PyObject *args)
6875 char *s1;
6877 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6878 return NULL;
6880 unsetenv(s1);
6882 /* Remove the key from posix_putenv_garbage;
6883 * this will cause it to be collected. This has to
6884 * happen after the real unsetenv() call because the
6885 * old value was still accessible until then.
6887 if (PyDict_DelItem(posix_putenv_garbage,
6888 PyTuple_GET_ITEM(args, 0))) {
6889 /* really not much we can do; just leak */
6890 PyErr_Clear();
6893 Py_INCREF(Py_None);
6894 return Py_None;
6896 #endif /* unsetenv */
6898 PyDoc_STRVAR(posix_strerror__doc__,
6899 "strerror(code) -> string\n\n\
6900 Translate an error code to a message string.");
6902 static PyObject *
6903 posix_strerror(PyObject *self, PyObject *args)
6905 int code;
6906 char *message;
6907 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6908 return NULL;
6909 message = strerror(code);
6910 if (message == NULL) {
6911 PyErr_SetString(PyExc_ValueError,
6912 "strerror() argument out of range");
6913 return NULL;
6915 return PyString_FromString(message);
6919 #ifdef HAVE_SYS_WAIT_H
6921 #ifdef WCOREDUMP
6922 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
6923 "WCOREDUMP(status) -> bool\n\n\
6924 Return True if the process returning 'status' was dumped to a core file.");
6926 static PyObject *
6927 posix_WCOREDUMP(PyObject *self, PyObject *args)
6929 WAIT_TYPE status;
6930 WAIT_STATUS_INT(status) = 0;
6932 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6933 return NULL;
6935 return PyBool_FromLong(WCOREDUMP(status));
6937 #endif /* WCOREDUMP */
6939 #ifdef WIFCONTINUED
6940 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
6941 "WIFCONTINUED(status) -> bool\n\n\
6942 Return True if the process returning 'status' was continued from a\n\
6943 job control stop.");
6945 static PyObject *
6946 posix_WIFCONTINUED(PyObject *self, PyObject *args)
6948 WAIT_TYPE status;
6949 WAIT_STATUS_INT(status) = 0;
6951 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6952 return NULL;
6954 return PyBool_FromLong(WIFCONTINUED(status));
6956 #endif /* WIFCONTINUED */
6958 #ifdef WIFSTOPPED
6959 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
6960 "WIFSTOPPED(status) -> bool\n\n\
6961 Return True if the process returning 'status' was stopped.");
6963 static PyObject *
6964 posix_WIFSTOPPED(PyObject *self, PyObject *args)
6966 WAIT_TYPE status;
6967 WAIT_STATUS_INT(status) = 0;
6969 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6970 return NULL;
6972 return PyBool_FromLong(WIFSTOPPED(status));
6974 #endif /* WIFSTOPPED */
6976 #ifdef WIFSIGNALED
6977 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
6978 "WIFSIGNALED(status) -> bool\n\n\
6979 Return True if the process returning 'status' was terminated by a signal.");
6981 static PyObject *
6982 posix_WIFSIGNALED(PyObject *self, PyObject *args)
6984 WAIT_TYPE status;
6985 WAIT_STATUS_INT(status) = 0;
6987 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6988 return NULL;
6990 return PyBool_FromLong(WIFSIGNALED(status));
6992 #endif /* WIFSIGNALED */
6994 #ifdef WIFEXITED
6995 PyDoc_STRVAR(posix_WIFEXITED__doc__,
6996 "WIFEXITED(status) -> bool\n\n\
6997 Return true if the process returning 'status' exited using the exit()\n\
6998 system call.");
7000 static PyObject *
7001 posix_WIFEXITED(PyObject *self, PyObject *args)
7003 WAIT_TYPE status;
7004 WAIT_STATUS_INT(status) = 0;
7006 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7007 return NULL;
7009 return PyBool_FromLong(WIFEXITED(status));
7011 #endif /* WIFEXITED */
7013 #ifdef WEXITSTATUS
7014 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
7015 "WEXITSTATUS(status) -> integer\n\n\
7016 Return the process return code from 'status'.");
7018 static PyObject *
7019 posix_WEXITSTATUS(PyObject *self, PyObject *args)
7021 WAIT_TYPE status;
7022 WAIT_STATUS_INT(status) = 0;
7024 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7025 return NULL;
7027 return Py_BuildValue("i", WEXITSTATUS(status));
7029 #endif /* WEXITSTATUS */
7031 #ifdef WTERMSIG
7032 PyDoc_STRVAR(posix_WTERMSIG__doc__,
7033 "WTERMSIG(status) -> integer\n\n\
7034 Return the signal that terminated the process that provided the 'status'\n\
7035 value.");
7037 static PyObject *
7038 posix_WTERMSIG(PyObject *self, PyObject *args)
7040 WAIT_TYPE status;
7041 WAIT_STATUS_INT(status) = 0;
7043 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7044 return NULL;
7046 return Py_BuildValue("i", WTERMSIG(status));
7048 #endif /* WTERMSIG */
7050 #ifdef WSTOPSIG
7051 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
7052 "WSTOPSIG(status) -> integer\n\n\
7053 Return the signal that stopped the process that provided\n\
7054 the 'status' value.");
7056 static PyObject *
7057 posix_WSTOPSIG(PyObject *self, PyObject *args)
7059 WAIT_TYPE status;
7060 WAIT_STATUS_INT(status) = 0;
7062 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7063 return NULL;
7065 return Py_BuildValue("i", WSTOPSIG(status));
7067 #endif /* WSTOPSIG */
7069 #endif /* HAVE_SYS_WAIT_H */
7072 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
7073 #ifdef _SCO_DS
7074 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7075 needed definitions in sys/statvfs.h */
7076 #define _SVID3
7077 #endif
7078 #include <sys/statvfs.h>
7080 static PyObject*
7081 _pystatvfs_fromstructstatvfs(struct statvfs st) {
7082 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7083 if (v == NULL)
7084 return NULL;
7086 #if !defined(HAVE_LARGEFILE_SUPPORT)
7087 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7088 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7089 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7090 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7091 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7092 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7093 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7094 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7095 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7096 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7097 #else
7098 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7099 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7100 PyStructSequence_SET_ITEM(v, 2,
7101 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7102 PyStructSequence_SET_ITEM(v, 3,
7103 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7104 PyStructSequence_SET_ITEM(v, 4,
7105 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7106 PyStructSequence_SET_ITEM(v, 5,
7107 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7108 PyStructSequence_SET_ITEM(v, 6,
7109 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7110 PyStructSequence_SET_ITEM(v, 7,
7111 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7112 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7113 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7114 #endif
7116 return v;
7119 PyDoc_STRVAR(posix_fstatvfs__doc__,
7120 "fstatvfs(fd) -> statvfs result\n\n\
7121 Perform an fstatvfs system call on the given fd.");
7123 static PyObject *
7124 posix_fstatvfs(PyObject *self, PyObject *args)
7126 int fd, res;
7127 struct statvfs st;
7129 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7130 return NULL;
7131 Py_BEGIN_ALLOW_THREADS
7132 res = fstatvfs(fd, &st);
7133 Py_END_ALLOW_THREADS
7134 if (res != 0)
7135 return posix_error();
7137 return _pystatvfs_fromstructstatvfs(st);
7139 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
7142 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
7143 #include <sys/statvfs.h>
7145 PyDoc_STRVAR(posix_statvfs__doc__,
7146 "statvfs(path) -> statvfs result\n\n\
7147 Perform a statvfs system call on the given path.");
7149 static PyObject *
7150 posix_statvfs(PyObject *self, PyObject *args)
7152 char *path;
7153 int res;
7154 struct statvfs st;
7155 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7156 return NULL;
7157 Py_BEGIN_ALLOW_THREADS
7158 res = statvfs(path, &st);
7159 Py_END_ALLOW_THREADS
7160 if (res != 0)
7161 return posix_error_with_filename(path);
7163 return _pystatvfs_fromstructstatvfs(st);
7165 #endif /* HAVE_STATVFS */
7168 #ifdef HAVE_TEMPNAM
7169 PyDoc_STRVAR(posix_tempnam__doc__,
7170 "tempnam([dir[, prefix]]) -> string\n\n\
7171 Return a unique name for a temporary file.\n\
7172 The directory and a prefix may be specified as strings; they may be omitted\n\
7173 or None if not needed.");
7175 static PyObject *
7176 posix_tempnam(PyObject *self, PyObject *args)
7178 PyObject *result = NULL;
7179 char *dir = NULL;
7180 char *pfx = NULL;
7181 char *name;
7183 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7184 return NULL;
7186 if (PyErr_Warn(PyExc_RuntimeWarning,
7187 "tempnam is a potential security risk to your program") < 0)
7188 return NULL;
7190 #ifdef MS_WINDOWS
7191 name = _tempnam(dir, pfx);
7192 #else
7193 name = tempnam(dir, pfx);
7194 #endif
7195 if (name == NULL)
7196 return PyErr_NoMemory();
7197 result = PyString_FromString(name);
7198 free(name);
7199 return result;
7201 #endif
7204 #ifdef HAVE_TMPFILE
7205 PyDoc_STRVAR(posix_tmpfile__doc__,
7206 "tmpfile() -> file object\n\n\
7207 Create a temporary file with no directory entries.");
7209 static PyObject *
7210 posix_tmpfile(PyObject *self, PyObject *noargs)
7212 FILE *fp;
7214 fp = tmpfile();
7215 if (fp == NULL)
7216 return posix_error();
7217 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
7219 #endif
7222 #ifdef HAVE_TMPNAM
7223 PyDoc_STRVAR(posix_tmpnam__doc__,
7224 "tmpnam() -> string\n\n\
7225 Return a unique name for a temporary file.");
7227 static PyObject *
7228 posix_tmpnam(PyObject *self, PyObject *noargs)
7230 char buffer[L_tmpnam];
7231 char *name;
7233 if (PyErr_Warn(PyExc_RuntimeWarning,
7234 "tmpnam is a potential security risk to your program") < 0)
7235 return NULL;
7237 #ifdef USE_TMPNAM_R
7238 name = tmpnam_r(buffer);
7239 #else
7240 name = tmpnam(buffer);
7241 #endif
7242 if (name == NULL) {
7243 PyObject *err = Py_BuildValue("is", 0,
7244 #ifdef USE_TMPNAM_R
7245 "unexpected NULL from tmpnam_r"
7246 #else
7247 "unexpected NULL from tmpnam"
7248 #endif
7250 PyErr_SetObject(PyExc_OSError, err);
7251 Py_XDECREF(err);
7252 return NULL;
7254 return PyString_FromString(buffer);
7256 #endif
7259 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7260 * It maps strings representing configuration variable names to
7261 * integer values, allowing those functions to be called with the
7262 * magic names instead of polluting the module's namespace with tons of
7263 * rarely-used constants. There are three separate tables that use
7264 * these definitions.
7266 * This code is always included, even if none of the interfaces that
7267 * need it are included. The #if hackery needed to avoid it would be
7268 * sufficiently pervasive that it's not worth the loss of readability.
7270 struct constdef {
7271 char *name;
7272 long value;
7275 static int
7276 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7277 size_t tablesize)
7279 if (PyInt_Check(arg)) {
7280 *valuep = PyInt_AS_LONG(arg);
7281 return 1;
7283 if (PyString_Check(arg)) {
7284 /* look up the value in the table using a binary search */
7285 size_t lo = 0;
7286 size_t mid;
7287 size_t hi = tablesize;
7288 int cmp;
7289 char *confname = PyString_AS_STRING(arg);
7290 while (lo < hi) {
7291 mid = (lo + hi) / 2;
7292 cmp = strcmp(confname, table[mid].name);
7293 if (cmp < 0)
7294 hi = mid;
7295 else if (cmp > 0)
7296 lo = mid + 1;
7297 else {
7298 *valuep = table[mid].value;
7299 return 1;
7302 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7304 else
7305 PyErr_SetString(PyExc_TypeError,
7306 "configuration names must be strings or integers");
7307 return 0;
7311 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7312 static struct constdef posix_constants_pathconf[] = {
7313 #ifdef _PC_ABI_AIO_XFER_MAX
7314 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7315 #endif
7316 #ifdef _PC_ABI_ASYNC_IO
7317 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7318 #endif
7319 #ifdef _PC_ASYNC_IO
7320 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7321 #endif
7322 #ifdef _PC_CHOWN_RESTRICTED
7323 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7324 #endif
7325 #ifdef _PC_FILESIZEBITS
7326 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7327 #endif
7328 #ifdef _PC_LAST
7329 {"PC_LAST", _PC_LAST},
7330 #endif
7331 #ifdef _PC_LINK_MAX
7332 {"PC_LINK_MAX", _PC_LINK_MAX},
7333 #endif
7334 #ifdef _PC_MAX_CANON
7335 {"PC_MAX_CANON", _PC_MAX_CANON},
7336 #endif
7337 #ifdef _PC_MAX_INPUT
7338 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7339 #endif
7340 #ifdef _PC_NAME_MAX
7341 {"PC_NAME_MAX", _PC_NAME_MAX},
7342 #endif
7343 #ifdef _PC_NO_TRUNC
7344 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7345 #endif
7346 #ifdef _PC_PATH_MAX
7347 {"PC_PATH_MAX", _PC_PATH_MAX},
7348 #endif
7349 #ifdef _PC_PIPE_BUF
7350 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7351 #endif
7352 #ifdef _PC_PRIO_IO
7353 {"PC_PRIO_IO", _PC_PRIO_IO},
7354 #endif
7355 #ifdef _PC_SOCK_MAXBUF
7356 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7357 #endif
7358 #ifdef _PC_SYNC_IO
7359 {"PC_SYNC_IO", _PC_SYNC_IO},
7360 #endif
7361 #ifdef _PC_VDISABLE
7362 {"PC_VDISABLE", _PC_VDISABLE},
7363 #endif
7366 static int
7367 conv_path_confname(PyObject *arg, int *valuep)
7369 return conv_confname(arg, valuep, posix_constants_pathconf,
7370 sizeof(posix_constants_pathconf)
7371 / sizeof(struct constdef));
7373 #endif
7375 #ifdef HAVE_FPATHCONF
7376 PyDoc_STRVAR(posix_fpathconf__doc__,
7377 "fpathconf(fd, name) -> integer\n\n\
7378 Return the configuration limit name for the file descriptor fd.\n\
7379 If there is no limit, return -1.");
7381 static PyObject *
7382 posix_fpathconf(PyObject *self, PyObject *args)
7384 PyObject *result = NULL;
7385 int name, fd;
7387 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7388 conv_path_confname, &name)) {
7389 long limit;
7391 errno = 0;
7392 limit = fpathconf(fd, name);
7393 if (limit == -1 && errno != 0)
7394 posix_error();
7395 else
7396 result = PyInt_FromLong(limit);
7398 return result;
7400 #endif
7403 #ifdef HAVE_PATHCONF
7404 PyDoc_STRVAR(posix_pathconf__doc__,
7405 "pathconf(path, name) -> integer\n\n\
7406 Return the configuration limit name for the file or directory path.\n\
7407 If there is no limit, return -1.");
7409 static PyObject *
7410 posix_pathconf(PyObject *self, PyObject *args)
7412 PyObject *result = NULL;
7413 int name;
7414 char *path;
7416 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7417 conv_path_confname, &name)) {
7418 long limit;
7420 errno = 0;
7421 limit = pathconf(path, name);
7422 if (limit == -1 && errno != 0) {
7423 if (errno == EINVAL)
7424 /* could be a path or name problem */
7425 posix_error();
7426 else
7427 posix_error_with_filename(path);
7429 else
7430 result = PyInt_FromLong(limit);
7432 return result;
7434 #endif
7436 #ifdef HAVE_CONFSTR
7437 static struct constdef posix_constants_confstr[] = {
7438 #ifdef _CS_ARCHITECTURE
7439 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7440 #endif
7441 #ifdef _CS_HOSTNAME
7442 {"CS_HOSTNAME", _CS_HOSTNAME},
7443 #endif
7444 #ifdef _CS_HW_PROVIDER
7445 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7446 #endif
7447 #ifdef _CS_HW_SERIAL
7448 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7449 #endif
7450 #ifdef _CS_INITTAB_NAME
7451 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7452 #endif
7453 #ifdef _CS_LFS64_CFLAGS
7454 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7455 #endif
7456 #ifdef _CS_LFS64_LDFLAGS
7457 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7458 #endif
7459 #ifdef _CS_LFS64_LIBS
7460 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7461 #endif
7462 #ifdef _CS_LFS64_LINTFLAGS
7463 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7464 #endif
7465 #ifdef _CS_LFS_CFLAGS
7466 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7467 #endif
7468 #ifdef _CS_LFS_LDFLAGS
7469 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7470 #endif
7471 #ifdef _CS_LFS_LIBS
7472 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7473 #endif
7474 #ifdef _CS_LFS_LINTFLAGS
7475 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7476 #endif
7477 #ifdef _CS_MACHINE
7478 {"CS_MACHINE", _CS_MACHINE},
7479 #endif
7480 #ifdef _CS_PATH
7481 {"CS_PATH", _CS_PATH},
7482 #endif
7483 #ifdef _CS_RELEASE
7484 {"CS_RELEASE", _CS_RELEASE},
7485 #endif
7486 #ifdef _CS_SRPC_DOMAIN
7487 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7488 #endif
7489 #ifdef _CS_SYSNAME
7490 {"CS_SYSNAME", _CS_SYSNAME},
7491 #endif
7492 #ifdef _CS_VERSION
7493 {"CS_VERSION", _CS_VERSION},
7494 #endif
7495 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7496 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7497 #endif
7498 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7499 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7500 #endif
7501 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
7502 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7503 #endif
7504 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7505 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7506 #endif
7507 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7508 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7509 #endif
7510 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7511 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7512 #endif
7513 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7514 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7515 #endif
7516 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7517 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7518 #endif
7519 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7520 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7521 #endif
7522 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7523 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7524 #endif
7525 #ifdef _CS_XBS5_LP64_OFF64_LIBS
7526 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7527 #endif
7528 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7529 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7530 #endif
7531 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7532 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7533 #endif
7534 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7535 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7536 #endif
7537 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7538 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7539 #endif
7540 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7541 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7542 #endif
7543 #ifdef _MIPS_CS_AVAIL_PROCESSORS
7544 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7545 #endif
7546 #ifdef _MIPS_CS_BASE
7547 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7548 #endif
7549 #ifdef _MIPS_CS_HOSTID
7550 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7551 #endif
7552 #ifdef _MIPS_CS_HW_NAME
7553 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7554 #endif
7555 #ifdef _MIPS_CS_NUM_PROCESSORS
7556 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7557 #endif
7558 #ifdef _MIPS_CS_OSREL_MAJ
7559 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7560 #endif
7561 #ifdef _MIPS_CS_OSREL_MIN
7562 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7563 #endif
7564 #ifdef _MIPS_CS_OSREL_PATCH
7565 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7566 #endif
7567 #ifdef _MIPS_CS_OS_NAME
7568 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7569 #endif
7570 #ifdef _MIPS_CS_OS_PROVIDER
7571 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7572 #endif
7573 #ifdef _MIPS_CS_PROCESSORS
7574 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7575 #endif
7576 #ifdef _MIPS_CS_SERIAL
7577 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7578 #endif
7579 #ifdef _MIPS_CS_VENDOR
7580 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7581 #endif
7584 static int
7585 conv_confstr_confname(PyObject *arg, int *valuep)
7587 return conv_confname(arg, valuep, posix_constants_confstr,
7588 sizeof(posix_constants_confstr)
7589 / sizeof(struct constdef));
7592 PyDoc_STRVAR(posix_confstr__doc__,
7593 "confstr(name) -> string\n\n\
7594 Return a string-valued system configuration variable.");
7596 static PyObject *
7597 posix_confstr(PyObject *self, PyObject *args)
7599 PyObject *result = NULL;
7600 int name;
7601 char buffer[256];
7603 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
7604 int len;
7606 errno = 0;
7607 len = confstr(name, buffer, sizeof(buffer));
7608 if (len == 0) {
7609 if (errno) {
7610 posix_error();
7612 else {
7613 result = Py_None;
7614 Py_INCREF(Py_None);
7617 else {
7618 if ((unsigned int)len >= sizeof(buffer)) {
7619 result = PyString_FromStringAndSize(NULL, len-1);
7620 if (result != NULL)
7621 confstr(name, PyString_AS_STRING(result), len);
7623 else
7624 result = PyString_FromStringAndSize(buffer, len-1);
7627 return result;
7629 #endif
7632 #ifdef HAVE_SYSCONF
7633 static struct constdef posix_constants_sysconf[] = {
7634 #ifdef _SC_2_CHAR_TERM
7635 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7636 #endif
7637 #ifdef _SC_2_C_BIND
7638 {"SC_2_C_BIND", _SC_2_C_BIND},
7639 #endif
7640 #ifdef _SC_2_C_DEV
7641 {"SC_2_C_DEV", _SC_2_C_DEV},
7642 #endif
7643 #ifdef _SC_2_C_VERSION
7644 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7645 #endif
7646 #ifdef _SC_2_FORT_DEV
7647 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7648 #endif
7649 #ifdef _SC_2_FORT_RUN
7650 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7651 #endif
7652 #ifdef _SC_2_LOCALEDEF
7653 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7654 #endif
7655 #ifdef _SC_2_SW_DEV
7656 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7657 #endif
7658 #ifdef _SC_2_UPE
7659 {"SC_2_UPE", _SC_2_UPE},
7660 #endif
7661 #ifdef _SC_2_VERSION
7662 {"SC_2_VERSION", _SC_2_VERSION},
7663 #endif
7664 #ifdef _SC_ABI_ASYNCHRONOUS_IO
7665 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7666 #endif
7667 #ifdef _SC_ACL
7668 {"SC_ACL", _SC_ACL},
7669 #endif
7670 #ifdef _SC_AIO_LISTIO_MAX
7671 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7672 #endif
7673 #ifdef _SC_AIO_MAX
7674 {"SC_AIO_MAX", _SC_AIO_MAX},
7675 #endif
7676 #ifdef _SC_AIO_PRIO_DELTA_MAX
7677 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7678 #endif
7679 #ifdef _SC_ARG_MAX
7680 {"SC_ARG_MAX", _SC_ARG_MAX},
7681 #endif
7682 #ifdef _SC_ASYNCHRONOUS_IO
7683 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7684 #endif
7685 #ifdef _SC_ATEXIT_MAX
7686 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7687 #endif
7688 #ifdef _SC_AUDIT
7689 {"SC_AUDIT", _SC_AUDIT},
7690 #endif
7691 #ifdef _SC_AVPHYS_PAGES
7692 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7693 #endif
7694 #ifdef _SC_BC_BASE_MAX
7695 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7696 #endif
7697 #ifdef _SC_BC_DIM_MAX
7698 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7699 #endif
7700 #ifdef _SC_BC_SCALE_MAX
7701 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7702 #endif
7703 #ifdef _SC_BC_STRING_MAX
7704 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7705 #endif
7706 #ifdef _SC_CAP
7707 {"SC_CAP", _SC_CAP},
7708 #endif
7709 #ifdef _SC_CHARCLASS_NAME_MAX
7710 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7711 #endif
7712 #ifdef _SC_CHAR_BIT
7713 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7714 #endif
7715 #ifdef _SC_CHAR_MAX
7716 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7717 #endif
7718 #ifdef _SC_CHAR_MIN
7719 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7720 #endif
7721 #ifdef _SC_CHILD_MAX
7722 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7723 #endif
7724 #ifdef _SC_CLK_TCK
7725 {"SC_CLK_TCK", _SC_CLK_TCK},
7726 #endif
7727 #ifdef _SC_COHER_BLKSZ
7728 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7729 #endif
7730 #ifdef _SC_COLL_WEIGHTS_MAX
7731 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7732 #endif
7733 #ifdef _SC_DCACHE_ASSOC
7734 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7735 #endif
7736 #ifdef _SC_DCACHE_BLKSZ
7737 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7738 #endif
7739 #ifdef _SC_DCACHE_LINESZ
7740 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7741 #endif
7742 #ifdef _SC_DCACHE_SZ
7743 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7744 #endif
7745 #ifdef _SC_DCACHE_TBLKSZ
7746 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7747 #endif
7748 #ifdef _SC_DELAYTIMER_MAX
7749 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7750 #endif
7751 #ifdef _SC_EQUIV_CLASS_MAX
7752 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7753 #endif
7754 #ifdef _SC_EXPR_NEST_MAX
7755 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7756 #endif
7757 #ifdef _SC_FSYNC
7758 {"SC_FSYNC", _SC_FSYNC},
7759 #endif
7760 #ifdef _SC_GETGR_R_SIZE_MAX
7761 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7762 #endif
7763 #ifdef _SC_GETPW_R_SIZE_MAX
7764 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7765 #endif
7766 #ifdef _SC_ICACHE_ASSOC
7767 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7768 #endif
7769 #ifdef _SC_ICACHE_BLKSZ
7770 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7771 #endif
7772 #ifdef _SC_ICACHE_LINESZ
7773 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7774 #endif
7775 #ifdef _SC_ICACHE_SZ
7776 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7777 #endif
7778 #ifdef _SC_INF
7779 {"SC_INF", _SC_INF},
7780 #endif
7781 #ifdef _SC_INT_MAX
7782 {"SC_INT_MAX", _SC_INT_MAX},
7783 #endif
7784 #ifdef _SC_INT_MIN
7785 {"SC_INT_MIN", _SC_INT_MIN},
7786 #endif
7787 #ifdef _SC_IOV_MAX
7788 {"SC_IOV_MAX", _SC_IOV_MAX},
7789 #endif
7790 #ifdef _SC_IP_SECOPTS
7791 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7792 #endif
7793 #ifdef _SC_JOB_CONTROL
7794 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7795 #endif
7796 #ifdef _SC_KERN_POINTERS
7797 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7798 #endif
7799 #ifdef _SC_KERN_SIM
7800 {"SC_KERN_SIM", _SC_KERN_SIM},
7801 #endif
7802 #ifdef _SC_LINE_MAX
7803 {"SC_LINE_MAX", _SC_LINE_MAX},
7804 #endif
7805 #ifdef _SC_LOGIN_NAME_MAX
7806 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7807 #endif
7808 #ifdef _SC_LOGNAME_MAX
7809 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7810 #endif
7811 #ifdef _SC_LONG_BIT
7812 {"SC_LONG_BIT", _SC_LONG_BIT},
7813 #endif
7814 #ifdef _SC_MAC
7815 {"SC_MAC", _SC_MAC},
7816 #endif
7817 #ifdef _SC_MAPPED_FILES
7818 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7819 #endif
7820 #ifdef _SC_MAXPID
7821 {"SC_MAXPID", _SC_MAXPID},
7822 #endif
7823 #ifdef _SC_MB_LEN_MAX
7824 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7825 #endif
7826 #ifdef _SC_MEMLOCK
7827 {"SC_MEMLOCK", _SC_MEMLOCK},
7828 #endif
7829 #ifdef _SC_MEMLOCK_RANGE
7830 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7831 #endif
7832 #ifdef _SC_MEMORY_PROTECTION
7833 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7834 #endif
7835 #ifdef _SC_MESSAGE_PASSING
7836 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7837 #endif
7838 #ifdef _SC_MMAP_FIXED_ALIGNMENT
7839 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7840 #endif
7841 #ifdef _SC_MQ_OPEN_MAX
7842 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7843 #endif
7844 #ifdef _SC_MQ_PRIO_MAX
7845 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7846 #endif
7847 #ifdef _SC_NACLS_MAX
7848 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7849 #endif
7850 #ifdef _SC_NGROUPS_MAX
7851 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7852 #endif
7853 #ifdef _SC_NL_ARGMAX
7854 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7855 #endif
7856 #ifdef _SC_NL_LANGMAX
7857 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7858 #endif
7859 #ifdef _SC_NL_MSGMAX
7860 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7861 #endif
7862 #ifdef _SC_NL_NMAX
7863 {"SC_NL_NMAX", _SC_NL_NMAX},
7864 #endif
7865 #ifdef _SC_NL_SETMAX
7866 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7867 #endif
7868 #ifdef _SC_NL_TEXTMAX
7869 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7870 #endif
7871 #ifdef _SC_NPROCESSORS_CONF
7872 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7873 #endif
7874 #ifdef _SC_NPROCESSORS_ONLN
7875 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7876 #endif
7877 #ifdef _SC_NPROC_CONF
7878 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7879 #endif
7880 #ifdef _SC_NPROC_ONLN
7881 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7882 #endif
7883 #ifdef _SC_NZERO
7884 {"SC_NZERO", _SC_NZERO},
7885 #endif
7886 #ifdef _SC_OPEN_MAX
7887 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7888 #endif
7889 #ifdef _SC_PAGESIZE
7890 {"SC_PAGESIZE", _SC_PAGESIZE},
7891 #endif
7892 #ifdef _SC_PAGE_SIZE
7893 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7894 #endif
7895 #ifdef _SC_PASS_MAX
7896 {"SC_PASS_MAX", _SC_PASS_MAX},
7897 #endif
7898 #ifdef _SC_PHYS_PAGES
7899 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7900 #endif
7901 #ifdef _SC_PII
7902 {"SC_PII", _SC_PII},
7903 #endif
7904 #ifdef _SC_PII_INTERNET
7905 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7906 #endif
7907 #ifdef _SC_PII_INTERNET_DGRAM
7908 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7909 #endif
7910 #ifdef _SC_PII_INTERNET_STREAM
7911 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7912 #endif
7913 #ifdef _SC_PII_OSI
7914 {"SC_PII_OSI", _SC_PII_OSI},
7915 #endif
7916 #ifdef _SC_PII_OSI_CLTS
7917 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7918 #endif
7919 #ifdef _SC_PII_OSI_COTS
7920 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7921 #endif
7922 #ifdef _SC_PII_OSI_M
7923 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7924 #endif
7925 #ifdef _SC_PII_SOCKET
7926 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7927 #endif
7928 #ifdef _SC_PII_XTI
7929 {"SC_PII_XTI", _SC_PII_XTI},
7930 #endif
7931 #ifdef _SC_POLL
7932 {"SC_POLL", _SC_POLL},
7933 #endif
7934 #ifdef _SC_PRIORITIZED_IO
7935 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7936 #endif
7937 #ifdef _SC_PRIORITY_SCHEDULING
7938 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7939 #endif
7940 #ifdef _SC_REALTIME_SIGNALS
7941 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7942 #endif
7943 #ifdef _SC_RE_DUP_MAX
7944 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7945 #endif
7946 #ifdef _SC_RTSIG_MAX
7947 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7948 #endif
7949 #ifdef _SC_SAVED_IDS
7950 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7951 #endif
7952 #ifdef _SC_SCHAR_MAX
7953 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7954 #endif
7955 #ifdef _SC_SCHAR_MIN
7956 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7957 #endif
7958 #ifdef _SC_SELECT
7959 {"SC_SELECT", _SC_SELECT},
7960 #endif
7961 #ifdef _SC_SEMAPHORES
7962 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7963 #endif
7964 #ifdef _SC_SEM_NSEMS_MAX
7965 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7966 #endif
7967 #ifdef _SC_SEM_VALUE_MAX
7968 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7969 #endif
7970 #ifdef _SC_SHARED_MEMORY_OBJECTS
7971 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7972 #endif
7973 #ifdef _SC_SHRT_MAX
7974 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7975 #endif
7976 #ifdef _SC_SHRT_MIN
7977 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7978 #endif
7979 #ifdef _SC_SIGQUEUE_MAX
7980 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7981 #endif
7982 #ifdef _SC_SIGRT_MAX
7983 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7984 #endif
7985 #ifdef _SC_SIGRT_MIN
7986 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7987 #endif
7988 #ifdef _SC_SOFTPOWER
7989 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7990 #endif
7991 #ifdef _SC_SPLIT_CACHE
7992 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7993 #endif
7994 #ifdef _SC_SSIZE_MAX
7995 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7996 #endif
7997 #ifdef _SC_STACK_PROT
7998 {"SC_STACK_PROT", _SC_STACK_PROT},
7999 #endif
8000 #ifdef _SC_STREAM_MAX
8001 {"SC_STREAM_MAX", _SC_STREAM_MAX},
8002 #endif
8003 #ifdef _SC_SYNCHRONIZED_IO
8004 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
8005 #endif
8006 #ifdef _SC_THREADS
8007 {"SC_THREADS", _SC_THREADS},
8008 #endif
8009 #ifdef _SC_THREAD_ATTR_STACKADDR
8010 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
8011 #endif
8012 #ifdef _SC_THREAD_ATTR_STACKSIZE
8013 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
8014 #endif
8015 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
8016 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
8017 #endif
8018 #ifdef _SC_THREAD_KEYS_MAX
8019 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
8020 #endif
8021 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
8022 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
8023 #endif
8024 #ifdef _SC_THREAD_PRIO_INHERIT
8025 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
8026 #endif
8027 #ifdef _SC_THREAD_PRIO_PROTECT
8028 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
8029 #endif
8030 #ifdef _SC_THREAD_PROCESS_SHARED
8031 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
8032 #endif
8033 #ifdef _SC_THREAD_SAFE_FUNCTIONS
8034 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
8035 #endif
8036 #ifdef _SC_THREAD_STACK_MIN
8037 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
8038 #endif
8039 #ifdef _SC_THREAD_THREADS_MAX
8040 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
8041 #endif
8042 #ifdef _SC_TIMERS
8043 {"SC_TIMERS", _SC_TIMERS},
8044 #endif
8045 #ifdef _SC_TIMER_MAX
8046 {"SC_TIMER_MAX", _SC_TIMER_MAX},
8047 #endif
8048 #ifdef _SC_TTY_NAME_MAX
8049 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
8050 #endif
8051 #ifdef _SC_TZNAME_MAX
8052 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
8053 #endif
8054 #ifdef _SC_T_IOV_MAX
8055 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
8056 #endif
8057 #ifdef _SC_UCHAR_MAX
8058 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
8059 #endif
8060 #ifdef _SC_UINT_MAX
8061 {"SC_UINT_MAX", _SC_UINT_MAX},
8062 #endif
8063 #ifdef _SC_UIO_MAXIOV
8064 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
8065 #endif
8066 #ifdef _SC_ULONG_MAX
8067 {"SC_ULONG_MAX", _SC_ULONG_MAX},
8068 #endif
8069 #ifdef _SC_USHRT_MAX
8070 {"SC_USHRT_MAX", _SC_USHRT_MAX},
8071 #endif
8072 #ifdef _SC_VERSION
8073 {"SC_VERSION", _SC_VERSION},
8074 #endif
8075 #ifdef _SC_WORD_BIT
8076 {"SC_WORD_BIT", _SC_WORD_BIT},
8077 #endif
8078 #ifdef _SC_XBS5_ILP32_OFF32
8079 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
8080 #endif
8081 #ifdef _SC_XBS5_ILP32_OFFBIG
8082 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
8083 #endif
8084 #ifdef _SC_XBS5_LP64_OFF64
8085 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
8086 #endif
8087 #ifdef _SC_XBS5_LPBIG_OFFBIG
8088 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
8089 #endif
8090 #ifdef _SC_XOPEN_CRYPT
8091 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
8092 #endif
8093 #ifdef _SC_XOPEN_ENH_I18N
8094 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
8095 #endif
8096 #ifdef _SC_XOPEN_LEGACY
8097 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
8098 #endif
8099 #ifdef _SC_XOPEN_REALTIME
8100 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
8101 #endif
8102 #ifdef _SC_XOPEN_REALTIME_THREADS
8103 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
8104 #endif
8105 #ifdef _SC_XOPEN_SHM
8106 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
8107 #endif
8108 #ifdef _SC_XOPEN_UNIX
8109 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
8110 #endif
8111 #ifdef _SC_XOPEN_VERSION
8112 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
8113 #endif
8114 #ifdef _SC_XOPEN_XCU_VERSION
8115 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
8116 #endif
8117 #ifdef _SC_XOPEN_XPG2
8118 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
8119 #endif
8120 #ifdef _SC_XOPEN_XPG3
8121 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
8122 #endif
8123 #ifdef _SC_XOPEN_XPG4
8124 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
8125 #endif
8128 static int
8129 conv_sysconf_confname(PyObject *arg, int *valuep)
8131 return conv_confname(arg, valuep, posix_constants_sysconf,
8132 sizeof(posix_constants_sysconf)
8133 / sizeof(struct constdef));
8136 PyDoc_STRVAR(posix_sysconf__doc__,
8137 "sysconf(name) -> integer\n\n\
8138 Return an integer-valued system configuration variable.");
8140 static PyObject *
8141 posix_sysconf(PyObject *self, PyObject *args)
8143 PyObject *result = NULL;
8144 int name;
8146 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8147 int value;
8149 errno = 0;
8150 value = sysconf(name);
8151 if (value == -1 && errno != 0)
8152 posix_error();
8153 else
8154 result = PyInt_FromLong(value);
8156 return result;
8158 #endif
8161 /* This code is used to ensure that the tables of configuration value names
8162 * are in sorted order as required by conv_confname(), and also to build the
8163 * the exported dictionaries that are used to publish information about the
8164 * names available on the host platform.
8166 * Sorting the table at runtime ensures that the table is properly ordered
8167 * when used, even for platforms we're not able to test on. It also makes
8168 * it easier to add additional entries to the tables.
8171 static int
8172 cmp_constdefs(const void *v1, const void *v2)
8174 const struct constdef *c1 =
8175 (const struct constdef *) v1;
8176 const struct constdef *c2 =
8177 (const struct constdef *) v2;
8179 return strcmp(c1->name, c2->name);
8182 static int
8183 setup_confname_table(struct constdef *table, size_t tablesize,
8184 char *tablename, PyObject *module)
8186 PyObject *d = NULL;
8187 size_t i;
8189 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8190 d = PyDict_New();
8191 if (d == NULL)
8192 return -1;
8194 for (i=0; i < tablesize; ++i) {
8195 PyObject *o = PyInt_FromLong(table[i].value);
8196 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8197 Py_XDECREF(o);
8198 Py_DECREF(d);
8199 return -1;
8201 Py_DECREF(o);
8203 return PyModule_AddObject(module, tablename, d);
8206 /* Return -1 on failure, 0 on success. */
8207 static int
8208 setup_confname_tables(PyObject *module)
8210 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8211 if (setup_confname_table(posix_constants_pathconf,
8212 sizeof(posix_constants_pathconf)
8213 / sizeof(struct constdef),
8214 "pathconf_names", module))
8215 return -1;
8216 #endif
8217 #ifdef HAVE_CONFSTR
8218 if (setup_confname_table(posix_constants_confstr,
8219 sizeof(posix_constants_confstr)
8220 / sizeof(struct constdef),
8221 "confstr_names", module))
8222 return -1;
8223 #endif
8224 #ifdef HAVE_SYSCONF
8225 if (setup_confname_table(posix_constants_sysconf,
8226 sizeof(posix_constants_sysconf)
8227 / sizeof(struct constdef),
8228 "sysconf_names", module))
8229 return -1;
8230 #endif
8231 return 0;
8235 PyDoc_STRVAR(posix_abort__doc__,
8236 "abort() -> does not return!\n\n\
8237 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
8238 in the hardest way possible on the hosting operating system.");
8240 static PyObject *
8241 posix_abort(PyObject *self, PyObject *noargs)
8243 abort();
8244 /*NOTREACHED*/
8245 Py_FatalError("abort() called from Python code didn't abort!");
8246 return NULL;
8249 #ifdef MS_WINDOWS
8250 PyDoc_STRVAR(win32_startfile__doc__,
8251 "startfile(filepath [, operation]) - Start a file with its associated\n\
8252 application.\n\
8254 When \"operation\" is not specified or \"open\", this acts like\n\
8255 double-clicking the file in Explorer, or giving the file name as an\n\
8256 argument to the DOS \"start\" command: the file is opened with whatever\n\
8257 application (if any) its extension is associated.\n\
8258 When another \"operation\" is given, it specifies what should be done with\n\
8259 the file. A typical operation is \"print\".\n\
8261 startfile returns as soon as the associated application is launched.\n\
8262 There is no option to wait for the application to close, and no way\n\
8263 to retrieve the application's exit status.\n\
8265 The filepath is relative to the current directory. If you want to use\n\
8266 an absolute path, make sure the first character is not a slash (\"/\");\n\
8267 the underlying Win32 ShellExecute function doesn't work if it is.");
8269 static PyObject *
8270 win32_startfile(PyObject *self, PyObject *args)
8272 char *filepath;
8273 char *operation = NULL;
8274 HINSTANCE rc;
8275 #ifdef Py_WIN_WIDE_FILENAMES
8276 if (unicode_file_names()) {
8277 PyObject *unipath, *woperation = NULL;
8278 if (!PyArg_ParseTuple(args, "U|s:startfile",
8279 &unipath, &operation)) {
8280 PyErr_Clear();
8281 goto normal;
8285 if (operation) {
8286 woperation = PyUnicode_DecodeASCII(operation,
8287 strlen(operation), NULL);
8288 if (!woperation) {
8289 PyErr_Clear();
8290 operation = NULL;
8291 goto normal;
8295 Py_BEGIN_ALLOW_THREADS
8296 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8297 PyUnicode_AS_UNICODE(unipath),
8298 NULL, NULL, SW_SHOWNORMAL);
8299 Py_END_ALLOW_THREADS
8301 Py_XDECREF(woperation);
8302 if (rc <= (HINSTANCE)32) {
8303 PyObject *errval = win32_error_unicode("startfile",
8304 PyUnicode_AS_UNICODE(unipath));
8305 return errval;
8307 Py_INCREF(Py_None);
8308 return Py_None;
8310 #endif
8312 normal:
8313 if (!PyArg_ParseTuple(args, "et|s:startfile",
8314 Py_FileSystemDefaultEncoding, &filepath,
8315 &operation))
8316 return NULL;
8317 Py_BEGIN_ALLOW_THREADS
8318 rc = ShellExecute((HWND)0, operation, filepath,
8319 NULL, NULL, SW_SHOWNORMAL);
8320 Py_END_ALLOW_THREADS
8321 if (rc <= (HINSTANCE)32) {
8322 PyObject *errval = win32_error("startfile", filepath);
8323 PyMem_Free(filepath);
8324 return errval;
8326 PyMem_Free(filepath);
8327 Py_INCREF(Py_None);
8328 return Py_None;
8330 #endif
8332 #ifdef HAVE_GETLOADAVG
8333 PyDoc_STRVAR(posix_getloadavg__doc__,
8334 "getloadavg() -> (float, float, float)\n\n\
8335 Return the number of processes in the system run queue averaged over\n\
8336 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8337 was unobtainable");
8339 static PyObject *
8340 posix_getloadavg(PyObject *self, PyObject *noargs)
8342 double loadavg[3];
8343 if (getloadavg(loadavg, 3)!=3) {
8344 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8345 return NULL;
8346 } else
8347 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8349 #endif
8351 #ifdef MS_WINDOWS
8353 PyDoc_STRVAR(win32_urandom__doc__,
8354 "urandom(n) -> str\n\n\
8355 Return a string of n random bytes suitable for cryptographic use.");
8357 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8358 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8359 DWORD dwFlags );
8360 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8361 BYTE *pbBuffer );
8363 static CRYPTGENRANDOM pCryptGenRandom = NULL;
8364 /* This handle is never explicitly released. Instead, the operating
8365 system will release it when the process terminates. */
8366 static HCRYPTPROV hCryptProv = 0;
8368 static PyObject*
8369 win32_urandom(PyObject *self, PyObject *args)
8371 int howMany;
8372 PyObject* result;
8374 /* Read arguments */
8375 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8376 return NULL;
8377 if (howMany < 0)
8378 return PyErr_Format(PyExc_ValueError,
8379 "negative argument not allowed");
8381 if (hCryptProv == 0) {
8382 HINSTANCE hAdvAPI32 = NULL;
8383 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
8385 /* Obtain handle to the DLL containing CryptoAPI
8386 This should not fail */
8387 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8388 if(hAdvAPI32 == NULL)
8389 return win32_error("GetModuleHandle", NULL);
8391 /* Obtain pointers to the CryptoAPI functions
8392 This will fail on some early versions of Win95 */
8393 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8394 hAdvAPI32,
8395 "CryptAcquireContextA");
8396 if (pCryptAcquireContext == NULL)
8397 return PyErr_Format(PyExc_NotImplementedError,
8398 "CryptAcquireContextA not found");
8400 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8401 hAdvAPI32, "CryptGenRandom");
8402 if (pCryptGenRandom == NULL)
8403 return PyErr_Format(PyExc_NotImplementedError,
8404 "CryptGenRandom not found");
8406 /* Acquire context */
8407 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8408 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8409 return win32_error("CryptAcquireContext", NULL);
8412 /* Allocate bytes */
8413 result = PyString_FromStringAndSize(NULL, howMany);
8414 if (result != NULL) {
8415 /* Get random data */
8416 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
8417 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8418 PyString_AS_STRING(result))) {
8419 Py_DECREF(result);
8420 return win32_error("CryptGenRandom", NULL);
8423 return result;
8425 #endif
8427 #ifdef __VMS
8428 /* Use openssl random routine */
8429 #include <openssl/rand.h>
8430 PyDoc_STRVAR(vms_urandom__doc__,
8431 "urandom(n) -> str\n\n\
8432 Return a string of n random bytes suitable for cryptographic use.");
8434 static PyObject*
8435 vms_urandom(PyObject *self, PyObject *args)
8437 int howMany;
8438 PyObject* result;
8440 /* Read arguments */
8441 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8442 return NULL;
8443 if (howMany < 0)
8444 return PyErr_Format(PyExc_ValueError,
8445 "negative argument not allowed");
8447 /* Allocate bytes */
8448 result = PyString_FromStringAndSize(NULL, howMany);
8449 if (result != NULL) {
8450 /* Get random data */
8451 if (RAND_pseudo_bytes((unsigned char*)
8452 PyString_AS_STRING(result),
8453 howMany) < 0) {
8454 Py_DECREF(result);
8455 return PyErr_Format(PyExc_ValueError,
8456 "RAND_pseudo_bytes");
8459 return result;
8461 #endif
8463 static PyMethodDef posix_methods[] = {
8464 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8465 #ifdef HAVE_TTYNAME
8466 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8467 #endif
8468 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
8469 #ifdef HAVE_CHFLAGS
8470 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8471 #endif /* HAVE_CHFLAGS */
8472 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
8473 #ifdef HAVE_FCHMOD
8474 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8475 #endif /* HAVE_FCHMOD */
8476 #ifdef HAVE_CHOWN
8477 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
8478 #endif /* HAVE_CHOWN */
8479 #ifdef HAVE_LCHMOD
8480 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8481 #endif /* HAVE_LCHMOD */
8482 #ifdef HAVE_FCHOWN
8483 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8484 #endif /* HAVE_FCHOWN */
8485 #ifdef HAVE_LCHFLAGS
8486 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8487 #endif /* HAVE_LCHFLAGS */
8488 #ifdef HAVE_LCHOWN
8489 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8490 #endif /* HAVE_LCHOWN */
8491 #ifdef HAVE_CHROOT
8492 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8493 #endif
8494 #ifdef HAVE_CTERMID
8495 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
8496 #endif
8497 #ifdef HAVE_GETCWD
8498 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
8499 #ifdef Py_USING_UNICODE
8500 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
8501 #endif
8502 #endif
8503 #ifdef HAVE_LINK
8504 {"link", posix_link, METH_VARARGS, posix_link__doc__},
8505 #endif /* HAVE_LINK */
8506 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8507 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8508 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
8509 #ifdef HAVE_NICE
8510 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
8511 #endif /* HAVE_NICE */
8512 #ifdef HAVE_READLINK
8513 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
8514 #endif /* HAVE_READLINK */
8515 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8516 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8517 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8518 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
8519 #ifdef HAVE_SYMLINK
8520 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
8521 #endif /* HAVE_SYMLINK */
8522 #ifdef HAVE_SYSTEM
8523 {"system", posix_system, METH_VARARGS, posix_system__doc__},
8524 #endif
8525 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
8526 #ifdef HAVE_UNAME
8527 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
8528 #endif /* HAVE_UNAME */
8529 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8530 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8531 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
8532 #ifdef HAVE_TIMES
8533 {"times", posix_times, METH_NOARGS, posix_times__doc__},
8534 #endif /* HAVE_TIMES */
8535 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
8536 #ifdef HAVE_EXECV
8537 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8538 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
8539 #endif /* HAVE_EXECV */
8540 #ifdef HAVE_SPAWNV
8541 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8542 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
8543 #if defined(PYOS_OS2)
8544 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8545 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8546 #endif /* PYOS_OS2 */
8547 #endif /* HAVE_SPAWNV */
8548 #ifdef HAVE_FORK1
8549 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
8550 #endif /* HAVE_FORK1 */
8551 #ifdef HAVE_FORK
8552 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
8553 #endif /* HAVE_FORK */
8554 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
8555 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
8556 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
8557 #ifdef HAVE_FORKPTY
8558 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
8559 #endif /* HAVE_FORKPTY */
8560 #ifdef HAVE_GETEGID
8561 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
8562 #endif /* HAVE_GETEGID */
8563 #ifdef HAVE_GETEUID
8564 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
8565 #endif /* HAVE_GETEUID */
8566 #ifdef HAVE_GETGID
8567 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
8568 #endif /* HAVE_GETGID */
8569 #ifdef HAVE_GETGROUPS
8570 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
8571 #endif
8572 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
8573 #ifdef HAVE_GETPGRP
8574 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
8575 #endif /* HAVE_GETPGRP */
8576 #ifdef HAVE_GETPPID
8577 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
8578 #endif /* HAVE_GETPPID */
8579 #ifdef HAVE_GETUID
8580 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
8581 #endif /* HAVE_GETUID */
8582 #ifdef HAVE_GETLOGIN
8583 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
8584 #endif
8585 #ifdef HAVE_KILL
8586 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
8587 #endif /* HAVE_KILL */
8588 #ifdef HAVE_KILLPG
8589 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8590 #endif /* HAVE_KILLPG */
8591 #ifdef HAVE_PLOCK
8592 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
8593 #endif /* HAVE_PLOCK */
8594 #ifdef HAVE_POPEN
8595 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
8596 #ifdef MS_WINDOWS
8597 {"popen2", win32_popen2, METH_VARARGS},
8598 {"popen3", win32_popen3, METH_VARARGS},
8599 {"popen4", win32_popen4, METH_VARARGS},
8600 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8601 #else
8602 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8603 {"popen2", os2emx_popen2, METH_VARARGS},
8604 {"popen3", os2emx_popen3, METH_VARARGS},
8605 {"popen4", os2emx_popen4, METH_VARARGS},
8606 #endif
8607 #endif
8608 #endif /* HAVE_POPEN */
8609 #ifdef HAVE_SETUID
8610 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
8611 #endif /* HAVE_SETUID */
8612 #ifdef HAVE_SETEUID
8613 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8614 #endif /* HAVE_SETEUID */
8615 #ifdef HAVE_SETEGID
8616 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8617 #endif /* HAVE_SETEGID */
8618 #ifdef HAVE_SETREUID
8619 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8620 #endif /* HAVE_SETREUID */
8621 #ifdef HAVE_SETREGID
8622 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8623 #endif /* HAVE_SETREGID */
8624 #ifdef HAVE_SETGID
8625 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
8626 #endif /* HAVE_SETGID */
8627 #ifdef HAVE_SETGROUPS
8628 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
8629 #endif /* HAVE_SETGROUPS */
8630 #ifdef HAVE_GETPGID
8631 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8632 #endif /* HAVE_GETPGID */
8633 #ifdef HAVE_SETPGRP
8634 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
8635 #endif /* HAVE_SETPGRP */
8636 #ifdef HAVE_WAIT
8637 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
8638 #endif /* HAVE_WAIT */
8639 #ifdef HAVE_WAIT3
8640 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8641 #endif /* HAVE_WAIT3 */
8642 #ifdef HAVE_WAIT4
8643 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8644 #endif /* HAVE_WAIT4 */
8645 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
8646 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
8647 #endif /* HAVE_WAITPID */
8648 #ifdef HAVE_GETSID
8649 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8650 #endif /* HAVE_GETSID */
8651 #ifdef HAVE_SETSID
8652 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
8653 #endif /* HAVE_SETSID */
8654 #ifdef HAVE_SETPGID
8655 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
8656 #endif /* HAVE_SETPGID */
8657 #ifdef HAVE_TCGETPGRP
8658 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
8659 #endif /* HAVE_TCGETPGRP */
8660 #ifdef HAVE_TCSETPGRP
8661 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
8662 #endif /* HAVE_TCSETPGRP */
8663 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8664 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8665 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8666 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8667 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8668 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8669 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8670 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8671 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8672 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8673 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
8674 #ifdef HAVE_PIPE
8675 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
8676 #endif
8677 #ifdef HAVE_MKFIFO
8678 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
8679 #endif
8680 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8681 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8682 #endif
8683 #ifdef HAVE_DEVICE_MACROS
8684 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8685 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8686 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8687 #endif
8688 #ifdef HAVE_FTRUNCATE
8689 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
8690 #endif
8691 #ifdef HAVE_PUTENV
8692 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
8693 #endif
8694 #ifdef HAVE_UNSETENV
8695 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8696 #endif
8697 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
8698 #ifdef HAVE_FCHDIR
8699 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8700 #endif
8701 #ifdef HAVE_FSYNC
8702 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
8703 #endif
8704 #ifdef HAVE_FDATASYNC
8705 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
8706 #endif
8707 #ifdef HAVE_SYS_WAIT_H
8708 #ifdef WCOREDUMP
8709 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8710 #endif /* WCOREDUMP */
8711 #ifdef WIFCONTINUED
8712 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8713 #endif /* WIFCONTINUED */
8714 #ifdef WIFSTOPPED
8715 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
8716 #endif /* WIFSTOPPED */
8717 #ifdef WIFSIGNALED
8718 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
8719 #endif /* WIFSIGNALED */
8720 #ifdef WIFEXITED
8721 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
8722 #endif /* WIFEXITED */
8723 #ifdef WEXITSTATUS
8724 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
8725 #endif /* WEXITSTATUS */
8726 #ifdef WTERMSIG
8727 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
8728 #endif /* WTERMSIG */
8729 #ifdef WSTOPSIG
8730 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
8731 #endif /* WSTOPSIG */
8732 #endif /* HAVE_SYS_WAIT_H */
8733 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
8734 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
8735 #endif
8736 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
8737 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
8738 #endif
8739 #ifdef HAVE_TMPFILE
8740 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
8741 #endif
8742 #ifdef HAVE_TEMPNAM
8743 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8744 #endif
8745 #ifdef HAVE_TMPNAM
8746 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
8747 #endif
8748 #ifdef HAVE_CONFSTR
8749 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8750 #endif
8751 #ifdef HAVE_SYSCONF
8752 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8753 #endif
8754 #ifdef HAVE_FPATHCONF
8755 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8756 #endif
8757 #ifdef HAVE_PATHCONF
8758 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8759 #endif
8760 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
8761 #ifdef MS_WINDOWS
8762 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8763 #endif
8764 #ifdef HAVE_GETLOADAVG
8765 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
8766 #endif
8767 #ifdef MS_WINDOWS
8768 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8769 #endif
8770 #ifdef __VMS
8771 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8772 #endif
8773 {NULL, NULL} /* Sentinel */
8777 static int
8778 ins(PyObject *module, char *symbol, long value)
8780 return PyModule_AddIntConstant(module, symbol, value);
8783 #if defined(PYOS_OS2)
8784 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
8785 static int insertvalues(PyObject *module)
8787 APIRET rc;
8788 ULONG values[QSV_MAX+1];
8789 PyObject *v;
8790 char *ver, tmp[50];
8792 Py_BEGIN_ALLOW_THREADS
8793 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
8794 Py_END_ALLOW_THREADS
8796 if (rc != NO_ERROR) {
8797 os2_error(rc);
8798 return -1;
8801 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8802 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8803 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8804 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8805 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8806 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8807 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
8809 switch (values[QSV_VERSION_MINOR]) {
8810 case 0: ver = "2.00"; break;
8811 case 10: ver = "2.10"; break;
8812 case 11: ver = "2.11"; break;
8813 case 30: ver = "3.00"; break;
8814 case 40: ver = "4.00"; break;
8815 case 50: ver = "5.00"; break;
8816 default:
8817 PyOS_snprintf(tmp, sizeof(tmp),
8818 "%d-%d", values[QSV_VERSION_MAJOR],
8819 values[QSV_VERSION_MINOR]);
8820 ver = &tmp[0];
8823 /* Add Indicator of the Version of the Operating System */
8824 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
8825 return -1;
8827 /* Add Indicator of Which Drive was Used to Boot the System */
8828 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8829 tmp[1] = ':';
8830 tmp[2] = '\0';
8832 return PyModule_AddStringConstant(module, "bootdrive", tmp);
8834 #endif
8836 static int
8837 all_ins(PyObject *d)
8839 #ifdef F_OK
8840 if (ins(d, "F_OK", (long)F_OK)) return -1;
8841 #endif
8842 #ifdef R_OK
8843 if (ins(d, "R_OK", (long)R_OK)) return -1;
8844 #endif
8845 #ifdef W_OK
8846 if (ins(d, "W_OK", (long)W_OK)) return -1;
8847 #endif
8848 #ifdef X_OK
8849 if (ins(d, "X_OK", (long)X_OK)) return -1;
8850 #endif
8851 #ifdef NGROUPS_MAX
8852 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8853 #endif
8854 #ifdef TMP_MAX
8855 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8856 #endif
8857 #ifdef WCONTINUED
8858 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8859 #endif
8860 #ifdef WNOHANG
8861 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
8862 #endif
8863 #ifdef WUNTRACED
8864 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8865 #endif
8866 #ifdef O_RDONLY
8867 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8868 #endif
8869 #ifdef O_WRONLY
8870 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8871 #endif
8872 #ifdef O_RDWR
8873 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8874 #endif
8875 #ifdef O_NDELAY
8876 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8877 #endif
8878 #ifdef O_NONBLOCK
8879 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8880 #endif
8881 #ifdef O_APPEND
8882 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8883 #endif
8884 #ifdef O_DSYNC
8885 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8886 #endif
8887 #ifdef O_RSYNC
8888 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8889 #endif
8890 #ifdef O_SYNC
8891 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8892 #endif
8893 #ifdef O_NOCTTY
8894 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8895 #endif
8896 #ifdef O_CREAT
8897 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8898 #endif
8899 #ifdef O_EXCL
8900 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8901 #endif
8902 #ifdef O_TRUNC
8903 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8904 #endif
8905 #ifdef O_BINARY
8906 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8907 #endif
8908 #ifdef O_TEXT
8909 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8910 #endif
8911 #ifdef O_LARGEFILE
8912 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8913 #endif
8914 #ifdef O_SHLOCK
8915 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8916 #endif
8917 #ifdef O_EXLOCK
8918 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8919 #endif
8921 /* MS Windows */
8922 #ifdef O_NOINHERIT
8923 /* Don't inherit in child processes. */
8924 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8925 #endif
8926 #ifdef _O_SHORT_LIVED
8927 /* Optimize for short life (keep in memory). */
8928 /* MS forgot to define this one with a non-underscore form too. */
8929 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8930 #endif
8931 #ifdef O_TEMPORARY
8932 /* Automatically delete when last handle is closed. */
8933 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8934 #endif
8935 #ifdef O_RANDOM
8936 /* Optimize for random access. */
8937 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8938 #endif
8939 #ifdef O_SEQUENTIAL
8940 /* Optimize for sequential access. */
8941 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8942 #endif
8944 /* GNU extensions. */
8945 #ifdef O_ASYNC
8946 /* Send a SIGIO signal whenever input or output
8947 becomes available on file descriptor */
8948 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8949 #endif
8950 #ifdef O_DIRECT
8951 /* Direct disk access. */
8952 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8953 #endif
8954 #ifdef O_DIRECTORY
8955 /* Must be a directory. */
8956 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8957 #endif
8958 #ifdef O_NOFOLLOW
8959 /* Do not follow links. */
8960 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8961 #endif
8962 #ifdef O_NOATIME
8963 /* Do not update the access time. */
8964 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8965 #endif
8967 /* These come from sysexits.h */
8968 #ifdef EX_OK
8969 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
8970 #endif /* EX_OK */
8971 #ifdef EX_USAGE
8972 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
8973 #endif /* EX_USAGE */
8974 #ifdef EX_DATAERR
8975 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
8976 #endif /* EX_DATAERR */
8977 #ifdef EX_NOINPUT
8978 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
8979 #endif /* EX_NOINPUT */
8980 #ifdef EX_NOUSER
8981 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
8982 #endif /* EX_NOUSER */
8983 #ifdef EX_NOHOST
8984 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
8985 #endif /* EX_NOHOST */
8986 #ifdef EX_UNAVAILABLE
8987 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
8988 #endif /* EX_UNAVAILABLE */
8989 #ifdef EX_SOFTWARE
8990 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
8991 #endif /* EX_SOFTWARE */
8992 #ifdef EX_OSERR
8993 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
8994 #endif /* EX_OSERR */
8995 #ifdef EX_OSFILE
8996 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
8997 #endif /* EX_OSFILE */
8998 #ifdef EX_CANTCREAT
8999 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
9000 #endif /* EX_CANTCREAT */
9001 #ifdef EX_IOERR
9002 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
9003 #endif /* EX_IOERR */
9004 #ifdef EX_TEMPFAIL
9005 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
9006 #endif /* EX_TEMPFAIL */
9007 #ifdef EX_PROTOCOL
9008 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
9009 #endif /* EX_PROTOCOL */
9010 #ifdef EX_NOPERM
9011 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
9012 #endif /* EX_NOPERM */
9013 #ifdef EX_CONFIG
9014 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
9015 #endif /* EX_CONFIG */
9016 #ifdef EX_NOTFOUND
9017 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
9018 #endif /* EX_NOTFOUND */
9020 #ifdef HAVE_SPAWNV
9021 #if defined(PYOS_OS2) && defined(PYCC_GCC)
9022 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9023 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9024 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9025 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9026 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9027 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9028 if (ins(d, "P_PM", (long)P_PM)) return -1;
9029 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9030 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9031 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9032 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9033 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9034 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9035 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9036 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9037 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9038 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9039 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9040 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9041 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
9042 #else
9043 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9044 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9045 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9046 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9047 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
9048 #endif
9049 #endif
9051 #if defined(PYOS_OS2)
9052 if (insertvalues(d)) return -1;
9053 #endif
9054 return 0;
9058 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
9059 #define INITFUNC initnt
9060 #define MODNAME "nt"
9062 #elif defined(PYOS_OS2)
9063 #define INITFUNC initos2
9064 #define MODNAME "os2"
9066 #else
9067 #define INITFUNC initposix
9068 #define MODNAME "posix"
9069 #endif
9071 PyMODINIT_FUNC
9072 INITFUNC(void)
9074 PyObject *m, *v;
9076 m = Py_InitModule3(MODNAME,
9077 posix_methods,
9078 posix__doc__);
9079 if (m == NULL)
9080 return;
9082 /* Initialize environ dictionary */
9083 v = convertenviron();
9084 Py_XINCREF(v);
9085 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9086 return;
9087 Py_DECREF(v);
9089 if (all_ins(m))
9090 return;
9092 if (setup_confname_tables(m))
9093 return;
9095 Py_INCREF(PyExc_OSError);
9096 PyModule_AddObject(m, "error", PyExc_OSError);
9098 #ifdef HAVE_PUTENV
9099 if (posix_putenv_garbage == NULL)
9100 posix_putenv_garbage = PyDict_New();
9101 #endif
9103 if (!initialized) {
9104 stat_result_desc.name = MODNAME ".stat_result";
9105 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9106 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9107 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9108 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9109 structseq_new = StatResultType.tp_new;
9110 StatResultType.tp_new = statresult_new;
9112 statvfs_result_desc.name = MODNAME ".statvfs_result";
9113 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
9114 #ifdef NEED_TICKS_PER_SECOND
9115 # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9116 ticks_per_second = sysconf(_SC_CLK_TCK);
9117 # elif defined(HZ)
9118 ticks_per_second = HZ;
9119 # else
9120 ticks_per_second = 60; /* magic fallback value; may be bogus */
9121 # endif
9122 #endif
9124 Py_INCREF((PyObject*) &StatResultType);
9125 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9126 Py_INCREF((PyObject*) &StatVFSResultType);
9127 PyModule_AddObject(m, "statvfs_result",
9128 (PyObject*) &StatVFSResultType);
9129 initialized = 1;
9131 #ifdef __APPLE__
9133 * Step 2 of weak-linking support on Mac OS X.
9135 * The code below removes functions that are not available on the
9136 * currently active platform.
9138 * This block allow one to use a python binary that was build on
9139 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9140 * OSX 10.4.
9142 #ifdef HAVE_FSTATVFS
9143 if (fstatvfs == NULL) {
9144 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9145 return;
9148 #endif /* HAVE_FSTATVFS */
9150 #ifdef HAVE_STATVFS
9151 if (statvfs == NULL) {
9152 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9153 return;
9156 #endif /* HAVE_STATVFS */
9158 # ifdef HAVE_LCHOWN
9159 if (lchown == NULL) {
9160 if (PyObject_DelAttrString(m, "lchown") == -1) {
9161 return;
9164 #endif /* HAVE_LCHOWN */
9167 #endif /* __APPLE__ */
9171 #ifdef __cplusplus
9173 #endif