Issue 6305: Clarify error message for large arguments to itertools.islice().
[python.git] / Modules / posixmodule.c
blob2787164f394f977b36b92c84a3ccf24db43ec154
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 /* Issue #1983: pid_t can be longer than a C long on some systems */
315 #if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
316 #define PARSE_PID "i"
317 #define PyLong_FromPid PyInt_FromLong
318 #define PyLong_AsPid PyInt_AsLong
319 #elif SIZEOF_PID_T == SIZEOF_LONG
320 #define PARSE_PID "l"
321 #define PyLong_FromPid PyInt_FromLong
322 #define PyLong_AsPid PyInt_AsLong
323 #elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
324 #define PARSE_PID "L"
325 #define PyLong_FromPid PyLong_FromLongLong
326 #define PyLong_AsPid PyInt_AsLongLong
327 #else
328 #error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
329 #endif /* SIZEOF_PID_T */
331 /* Don't use the "_r" form if we don't need it (also, won't have a
332 prototype for it, at least on Solaris -- maybe others as well?). */
333 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
334 #define USE_CTERMID_R
335 #endif
337 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
338 #define USE_TMPNAM_R
339 #endif
341 /* choose the appropriate stat and fstat functions and return structs */
342 #undef STAT
343 #if defined(MS_WIN64) || defined(MS_WINDOWS)
344 # define STAT win32_stat
345 # define FSTAT win32_fstat
346 # define STRUCT_STAT struct win32_stat
347 #else
348 # define STAT stat
349 # define FSTAT fstat
350 # define STRUCT_STAT struct stat
351 #endif
353 #if defined(MAJOR_IN_MKDEV)
354 #include <sys/mkdev.h>
355 #else
356 #if defined(MAJOR_IN_SYSMACROS)
357 #include <sys/sysmacros.h>
358 #endif
359 #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
360 #include <sys/mkdev.h>
361 #endif
362 #endif
364 #if defined _MSC_VER && _MSC_VER >= 1400
365 /* Microsoft CRT in VS2005 and higher will verify that a filehandle is
366 * valid and throw an assertion if it isn't.
367 * Normally, an invalid fd is likely to be a C program error and therefore
368 * an assertion can be useful, but it does contradict the POSIX standard
369 * which for write(2) states:
370 * "Otherwise, -1 shall be returned and errno set to indicate the error."
371 * "[EBADF] The fildes argument is not a valid file descriptor open for
372 * writing."
373 * Furthermore, python allows the user to enter any old integer
374 * as a fd and should merely raise a python exception on error.
375 * The Microsoft CRT doesn't provide an official way to check for the
376 * validity of a file descriptor, but we can emulate its internal behaviour
377 * by using the exported __pinfo data member and knowledge of the
378 * internal structures involved.
379 * The structures below must be updated for each version of visual studio
380 * according to the file internal.h in the CRT source, until MS comes
381 * up with a less hacky way to do this.
382 * (all of this is to avoid globally modifying the CRT behaviour using
383 * _set_invalid_parameter_handler() and _CrtSetReportMode())
385 /* The actual size of the structure is determined at runtime.
386 * Only the first items must be present.
388 typedef struct {
389 intptr_t osfhnd;
390 char osfile;
391 } my_ioinfo;
393 extern __declspec(dllimport) char * __pioinfo[];
394 #define IOINFO_L2E 5
395 #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
396 #define IOINFO_ARRAYS 64
397 #define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
398 #define FOPEN 0x01
399 #define _NO_CONSOLE_FILENO (intptr_t)-2
401 /* This function emulates what the windows CRT does to validate file handles */
403 _PyVerify_fd(int fd)
405 const int i1 = fd >> IOINFO_L2E;
406 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
408 static int sizeof_ioinfo = 0;
410 /* Determine the actual size of the ioinfo structure,
411 * as used by the CRT loaded in memory
413 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
414 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
416 if (sizeof_ioinfo == 0) {
417 /* This should not happen... */
418 goto fail;
421 /* See that it isn't a special CLEAR fileno */
422 if (fd != _NO_CONSOLE_FILENO) {
423 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
424 * we check pointer validity and other info
426 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
427 /* finally, check that the file is open */
428 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
429 if (info->osfile & FOPEN) {
430 return 1;
434 fail:
435 errno = EBADF;
436 return 0;
439 /* the special case of checking dup2. The target fd must be in a sensible range */
440 static int
441 _PyVerify_fd_dup2(int fd1, int fd2)
443 if (!_PyVerify_fd(fd1))
444 return 0;
445 if (fd2 == _NO_CONSOLE_FILENO)
446 return 0;
447 if ((unsigned)fd2 < _NHANDLE_)
448 return 1;
449 else
450 return 0;
452 #else
453 /* dummy version. _PyVerify_fd() is already defined in fileobject.h */
454 #define _PyVerify_fd_dup2(A, B) (1)
455 #endif
457 /* Return a dictionary corresponding to the POSIX environment table */
458 #ifdef WITH_NEXT_FRAMEWORK
459 /* On Darwin/MacOSX a shared library or framework has no access to
460 ** environ directly, we must obtain it with _NSGetEnviron().
462 #include <crt_externs.h>
463 static char **environ;
464 #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
465 extern char **environ;
466 #endif /* !_MSC_VER */
468 static PyObject *
469 convertenviron(void)
471 PyObject *d;
472 char **e;
473 d = PyDict_New();
474 if (d == NULL)
475 return NULL;
476 #ifdef WITH_NEXT_FRAMEWORK
477 if (environ == NULL)
478 environ = *_NSGetEnviron();
479 #endif
480 if (environ == NULL)
481 return d;
482 /* This part ignores errors */
483 for (e = environ; *e != NULL; e++) {
484 PyObject *k;
485 PyObject *v;
486 char *p = strchr(*e, '=');
487 if (p == NULL)
488 continue;
489 k = PyString_FromStringAndSize(*e, (int)(p-*e));
490 if (k == NULL) {
491 PyErr_Clear();
492 continue;
494 v = PyString_FromString(p+1);
495 if (v == NULL) {
496 PyErr_Clear();
497 Py_DECREF(k);
498 continue;
500 if (PyDict_GetItem(d, k) == NULL) {
501 if (PyDict_SetItem(d, k, v) != 0)
502 PyErr_Clear();
504 Py_DECREF(k);
505 Py_DECREF(v);
507 #if defined(PYOS_OS2)
509 APIRET rc;
510 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
512 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
513 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
514 PyObject *v = PyString_FromString(buffer);
515 PyDict_SetItemString(d, "BEGINLIBPATH", v);
516 Py_DECREF(v);
518 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
519 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
520 PyObject *v = PyString_FromString(buffer);
521 PyDict_SetItemString(d, "ENDLIBPATH", v);
522 Py_DECREF(v);
525 #endif
526 return d;
530 /* Set a POSIX-specific error from errno, and return NULL */
532 static PyObject *
533 posix_error(void)
535 return PyErr_SetFromErrno(PyExc_OSError);
537 static PyObject *
538 posix_error_with_filename(char* name)
540 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
543 #ifdef MS_WINDOWS
544 static PyObject *
545 posix_error_with_unicode_filename(Py_UNICODE* name)
547 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
549 #endif /* MS_WINDOWS */
552 static PyObject *
553 posix_error_with_allocated_filename(char* name)
555 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
556 PyMem_Free(name);
557 return rc;
560 #ifdef MS_WINDOWS
561 static PyObject *
562 win32_error(char* function, char* filename)
564 /* XXX We should pass the function name along in the future.
565 (_winreg.c also wants to pass the function name.)
566 This would however require an additional param to the
567 Windows error object, which is non-trivial.
569 errno = GetLastError();
570 if (filename)
571 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
572 else
573 return PyErr_SetFromWindowsErr(errno);
576 static PyObject *
577 win32_error_unicode(char* function, Py_UNICODE* filename)
579 /* XXX - see win32_error for comments on 'function' */
580 errno = GetLastError();
581 if (filename)
582 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
583 else
584 return PyErr_SetFromWindowsErr(errno);
587 static int
588 convert_to_unicode(PyObject **param)
590 if (PyUnicode_CheckExact(*param))
591 Py_INCREF(*param);
592 else if (PyUnicode_Check(*param))
593 /* For a Unicode subtype that's not a Unicode object,
594 return a true Unicode object with the same data. */
595 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
596 PyUnicode_GET_SIZE(*param));
597 else
598 *param = PyUnicode_FromEncodedObject(*param,
599 Py_FileSystemDefaultEncoding,
600 "strict");
601 return (*param) != NULL;
604 #endif /* MS_WINDOWS */
606 #if defined(PYOS_OS2)
607 /**********************************************************************
608 * Helper Function to Trim and Format OS/2 Messages
609 **********************************************************************/
610 static void
611 os2_formatmsg(char *msgbuf, int msglen, char *reason)
613 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
615 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
616 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
618 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
619 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
622 /* Add Optional Reason Text */
623 if (reason) {
624 strcat(msgbuf, " : ");
625 strcat(msgbuf, reason);
629 /**********************************************************************
630 * Decode an OS/2 Operating System Error Code
632 * A convenience function to lookup an OS/2 error code and return a
633 * text message we can use to raise a Python exception.
635 * Notes:
636 * The messages for errors returned from the OS/2 kernel reside in
637 * the file OSO001.MSG in the \OS2 directory hierarchy.
639 **********************************************************************/
640 static char *
641 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
643 APIRET rc;
644 ULONG msglen;
646 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
647 Py_BEGIN_ALLOW_THREADS
648 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
649 errorcode, "oso001.msg", &msglen);
650 Py_END_ALLOW_THREADS
652 if (rc == NO_ERROR)
653 os2_formatmsg(msgbuf, msglen, reason);
654 else
655 PyOS_snprintf(msgbuf, msgbuflen,
656 "unknown OS error #%d", errorcode);
658 return msgbuf;
661 /* Set an OS/2-specific error and return NULL. OS/2 kernel
662 errors are not in a global variable e.g. 'errno' nor are
663 they congruent with posix error numbers. */
665 static PyObject * os2_error(int code)
667 char text[1024];
668 PyObject *v;
670 os2_strerror(text, sizeof(text), code, "");
672 v = Py_BuildValue("(is)", code, text);
673 if (v != NULL) {
674 PyErr_SetObject(PyExc_OSError, v);
675 Py_DECREF(v);
677 return NULL; /* Signal to Python that an Exception is Pending */
680 #endif /* OS2 */
682 /* POSIX generic methods */
684 static PyObject *
685 posix_fildes(PyObject *fdobj, int (*func)(int))
687 int fd;
688 int res;
689 fd = PyObject_AsFileDescriptor(fdobj);
690 if (fd < 0)
691 return NULL;
692 if (!_PyVerify_fd(fd))
693 return posix_error();
694 Py_BEGIN_ALLOW_THREADS
695 res = (*func)(fd);
696 Py_END_ALLOW_THREADS
697 if (res < 0)
698 return posix_error();
699 Py_INCREF(Py_None);
700 return Py_None;
703 #ifdef MS_WINDOWS
704 static int
705 unicode_file_names(void)
707 static int canusewide = -1;
708 if (canusewide == -1) {
709 /* As per doc for ::GetVersion(), this is the correct test for
710 the Windows NT family. */
711 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
713 return canusewide;
715 #endif
717 static PyObject *
718 posix_1str(PyObject *args, char *format, int (*func)(const char*))
720 char *path1 = NULL;
721 int res;
722 if (!PyArg_ParseTuple(args, format,
723 Py_FileSystemDefaultEncoding, &path1))
724 return NULL;
725 Py_BEGIN_ALLOW_THREADS
726 res = (*func)(path1);
727 Py_END_ALLOW_THREADS
728 if (res < 0)
729 return posix_error_with_allocated_filename(path1);
730 PyMem_Free(path1);
731 Py_INCREF(Py_None);
732 return Py_None;
735 static PyObject *
736 posix_2str(PyObject *args,
737 char *format,
738 int (*func)(const char *, const char *))
740 char *path1 = NULL, *path2 = NULL;
741 int res;
742 if (!PyArg_ParseTuple(args, format,
743 Py_FileSystemDefaultEncoding, &path1,
744 Py_FileSystemDefaultEncoding, &path2))
745 return NULL;
746 Py_BEGIN_ALLOW_THREADS
747 res = (*func)(path1, path2);
748 Py_END_ALLOW_THREADS
749 PyMem_Free(path1);
750 PyMem_Free(path2);
751 if (res != 0)
752 /* XXX how to report both path1 and path2??? */
753 return posix_error();
754 Py_INCREF(Py_None);
755 return Py_None;
758 #ifdef MS_WINDOWS
759 static PyObject*
760 win32_1str(PyObject* args, char* func,
761 char* format, BOOL (__stdcall *funcA)(LPCSTR),
762 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
764 PyObject *uni;
765 char *ansi;
766 BOOL result;
767 if (unicode_file_names()) {
768 if (!PyArg_ParseTuple(args, wformat, &uni))
769 PyErr_Clear();
770 else {
771 Py_BEGIN_ALLOW_THREADS
772 result = funcW(PyUnicode_AsUnicode(uni));
773 Py_END_ALLOW_THREADS
774 if (!result)
775 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
776 Py_INCREF(Py_None);
777 return Py_None;
780 if (!PyArg_ParseTuple(args, format, &ansi))
781 return NULL;
782 Py_BEGIN_ALLOW_THREADS
783 result = funcA(ansi);
784 Py_END_ALLOW_THREADS
785 if (!result)
786 return win32_error(func, ansi);
787 Py_INCREF(Py_None);
788 return Py_None;
792 /* This is a reimplementation of the C library's chdir function,
793 but one that produces Win32 errors instead of DOS error codes.
794 chdir is essentially a wrapper around SetCurrentDirectory; however,
795 it also needs to set "magic" environment variables indicating
796 the per-drive current directory, which are of the form =<drive>: */
797 static BOOL __stdcall
798 win32_chdir(LPCSTR path)
800 char new_path[MAX_PATH+1];
801 int result;
802 char env[4] = "=x:";
804 if(!SetCurrentDirectoryA(path))
805 return FALSE;
806 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
807 if (!result)
808 return FALSE;
809 /* In the ANSI API, there should not be any paths longer
810 than MAX_PATH. */
811 assert(result <= MAX_PATH+1);
812 if (strncmp(new_path, "\\\\", 2) == 0 ||
813 strncmp(new_path, "//", 2) == 0)
814 /* UNC path, nothing to do. */
815 return TRUE;
816 env[1] = new_path[0];
817 return SetEnvironmentVariableA(env, new_path);
820 /* The Unicode version differs from the ANSI version
821 since the current directory might exceed MAX_PATH characters */
822 static BOOL __stdcall
823 win32_wchdir(LPCWSTR path)
825 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
826 int result;
827 wchar_t env[4] = L"=x:";
829 if(!SetCurrentDirectoryW(path))
830 return FALSE;
831 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
832 if (!result)
833 return FALSE;
834 if (result > MAX_PATH+1) {
835 new_path = malloc(result * sizeof(wchar_t));
836 if (!new_path) {
837 SetLastError(ERROR_OUTOFMEMORY);
838 return FALSE;
840 result = GetCurrentDirectoryW(result, new_path);
841 if (!result) {
842 free(new_path);
843 return FALSE;
846 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
847 wcsncmp(new_path, L"//", 2) == 0)
848 /* UNC path, nothing to do. */
849 return TRUE;
850 env[1] = new_path[0];
851 result = SetEnvironmentVariableW(env, new_path);
852 if (new_path != _new_path)
853 free(new_path);
854 return result;
856 #endif
858 #ifdef MS_WINDOWS
859 /* The CRT of Windows has a number of flaws wrt. its stat() implementation:
860 - time stamps are restricted to second resolution
861 - file modification times suffer from forth-and-back conversions between
862 UTC and local time
863 Therefore, we implement our own stat, based on the Win32 API directly.
865 #define HAVE_STAT_NSEC 1
867 struct win32_stat{
868 int st_dev;
869 __int64 st_ino;
870 unsigned short st_mode;
871 int st_nlink;
872 int st_uid;
873 int st_gid;
874 int st_rdev;
875 __int64 st_size;
876 int st_atime;
877 int st_atime_nsec;
878 int st_mtime;
879 int st_mtime_nsec;
880 int st_ctime;
881 int st_ctime_nsec;
884 static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
886 static void
887 FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
889 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
890 /* Cannot simply cast and dereference in_ptr,
891 since it might not be aligned properly */
892 __int64 in;
893 memcpy(&in, in_ptr, sizeof(in));
894 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
895 /* XXX Win32 supports time stamps past 2038; we currently don't */
896 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
899 static void
900 time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
902 /* XXX endianness */
903 __int64 out;
904 out = time_in + secs_between_epochs;
905 out = out * 10000000 + nsec_in / 100;
906 memcpy(out_ptr, &out, sizeof(out));
909 /* Below, we *know* that ugo+r is 0444 */
910 #if _S_IREAD != 0400
911 #error Unsupported C library
912 #endif
913 static int
914 attributes_to_mode(DWORD attr)
916 int m = 0;
917 if (attr & FILE_ATTRIBUTE_DIRECTORY)
918 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
919 else
920 m |= _S_IFREG;
921 if (attr & FILE_ATTRIBUTE_READONLY)
922 m |= 0444;
923 else
924 m |= 0666;
925 return m;
928 static int
929 attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
931 memset(result, 0, sizeof(*result));
932 result->st_mode = attributes_to_mode(info->dwFileAttributes);
933 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
934 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
935 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
936 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
938 return 0;
941 /* Emulate GetFileAttributesEx[AW] on Windows 95 */
942 static int checked = 0;
943 static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
944 static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
945 static void
946 check_gfax()
948 HINSTANCE hKernel32;
949 if (checked)
950 return;
951 checked = 1;
952 hKernel32 = GetModuleHandle("KERNEL32");
953 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
954 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
957 static BOOL
958 attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
960 HANDLE hFindFile;
961 WIN32_FIND_DATAA FileData;
962 hFindFile = FindFirstFileA(pszFile, &FileData);
963 if (hFindFile == INVALID_HANDLE_VALUE)
964 return FALSE;
965 FindClose(hFindFile);
966 pfad->dwFileAttributes = FileData.dwFileAttributes;
967 pfad->ftCreationTime = FileData.ftCreationTime;
968 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
969 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
970 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
971 pfad->nFileSizeLow = FileData.nFileSizeLow;
972 return TRUE;
975 static BOOL
976 attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
978 HANDLE hFindFile;
979 WIN32_FIND_DATAW FileData;
980 hFindFile = FindFirstFileW(pszFile, &FileData);
981 if (hFindFile == INVALID_HANDLE_VALUE)
982 return FALSE;
983 FindClose(hFindFile);
984 pfad->dwFileAttributes = FileData.dwFileAttributes;
985 pfad->ftCreationTime = FileData.ftCreationTime;
986 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
987 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
988 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
989 pfad->nFileSizeLow = FileData.nFileSizeLow;
990 return TRUE;
993 static BOOL WINAPI
994 Py_GetFileAttributesExA(LPCSTR pszFile,
995 GET_FILEEX_INFO_LEVELS level,
996 LPVOID pv)
998 BOOL result;
999 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1000 /* First try to use the system's implementation, if that is
1001 available and either succeeds to gives an error other than
1002 that it isn't implemented. */
1003 check_gfax();
1004 if (gfaxa) {
1005 result = gfaxa(pszFile, level, pv);
1006 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1007 return result;
1009 /* It's either not present, or not implemented.
1010 Emulate using FindFirstFile. */
1011 if (level != GetFileExInfoStandard) {
1012 SetLastError(ERROR_INVALID_PARAMETER);
1013 return FALSE;
1015 /* Use GetFileAttributes to validate that the file name
1016 does not contain wildcards (which FindFirstFile would
1017 accept). */
1018 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1019 return FALSE;
1020 return attributes_from_dir(pszFile, pfad);
1023 static BOOL WINAPI
1024 Py_GetFileAttributesExW(LPCWSTR pszFile,
1025 GET_FILEEX_INFO_LEVELS level,
1026 LPVOID pv)
1028 BOOL result;
1029 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1030 /* First try to use the system's implementation, if that is
1031 available and either succeeds to gives an error other than
1032 that it isn't implemented. */
1033 check_gfax();
1034 if (gfaxa) {
1035 result = gfaxw(pszFile, level, pv);
1036 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1037 return result;
1039 /* It's either not present, or not implemented.
1040 Emulate using FindFirstFile. */
1041 if (level != GetFileExInfoStandard) {
1042 SetLastError(ERROR_INVALID_PARAMETER);
1043 return FALSE;
1045 /* Use GetFileAttributes to validate that the file name
1046 does not contain wildcards (which FindFirstFile would
1047 accept). */
1048 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1049 return FALSE;
1050 return attributes_from_dir_w(pszFile, pfad);
1053 static int
1054 win32_stat(const char* path, struct win32_stat *result)
1056 WIN32_FILE_ATTRIBUTE_DATA info;
1057 int code;
1058 char *dot;
1059 /* XXX not supported on Win95 and NT 3.x */
1060 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1061 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1062 /* Protocol violation: we explicitly clear errno, instead of
1063 setting it to a POSIX error. Callers should use GetLastError. */
1064 errno = 0;
1065 return -1;
1066 } else {
1067 /* Could not get attributes on open file. Fall back to
1068 reading the directory. */
1069 if (!attributes_from_dir(path, &info)) {
1070 /* Very strange. This should not fail now */
1071 errno = 0;
1072 return -1;
1076 code = attribute_data_to_stat(&info, result);
1077 if (code != 0)
1078 return code;
1079 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1080 dot = strrchr(path, '.');
1081 if (dot) {
1082 if (stricmp(dot, ".bat") == 0 ||
1083 stricmp(dot, ".cmd") == 0 ||
1084 stricmp(dot, ".exe") == 0 ||
1085 stricmp(dot, ".com") == 0)
1086 result->st_mode |= 0111;
1088 return code;
1091 static int
1092 win32_wstat(const wchar_t* path, struct win32_stat *result)
1094 int code;
1095 const wchar_t *dot;
1096 WIN32_FILE_ATTRIBUTE_DATA info;
1097 /* XXX not supported on Win95 and NT 3.x */
1098 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1099 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1100 /* Protocol violation: we explicitly clear errno, instead of
1101 setting it to a POSIX error. Callers should use GetLastError. */
1102 errno = 0;
1103 return -1;
1104 } else {
1105 /* Could not get attributes on open file. Fall back to
1106 reading the directory. */
1107 if (!attributes_from_dir_w(path, &info)) {
1108 /* Very strange. This should not fail now */
1109 errno = 0;
1110 return -1;
1114 code = attribute_data_to_stat(&info, result);
1115 if (code < 0)
1116 return code;
1117 /* Set IFEXEC if it is an .exe, .bat, ... */
1118 dot = wcsrchr(path, '.');
1119 if (dot) {
1120 if (_wcsicmp(dot, L".bat") == 0 ||
1121 _wcsicmp(dot, L".cmd") == 0 ||
1122 _wcsicmp(dot, L".exe") == 0 ||
1123 _wcsicmp(dot, L".com") == 0)
1124 result->st_mode |= 0111;
1126 return code;
1129 static int
1130 win32_fstat(int file_number, struct win32_stat *result)
1132 BY_HANDLE_FILE_INFORMATION info;
1133 HANDLE h;
1134 int type;
1136 h = (HANDLE)_get_osfhandle(file_number);
1138 /* Protocol violation: we explicitly clear errno, instead of
1139 setting it to a POSIX error. Callers should use GetLastError. */
1140 errno = 0;
1142 if (h == INVALID_HANDLE_VALUE) {
1143 /* This is really a C library error (invalid file handle).
1144 We set the Win32 error to the closes one matching. */
1145 SetLastError(ERROR_INVALID_HANDLE);
1146 return -1;
1148 memset(result, 0, sizeof(*result));
1150 type = GetFileType(h);
1151 if (type == FILE_TYPE_UNKNOWN) {
1152 DWORD error = GetLastError();
1153 if (error != 0) {
1154 return -1;
1156 /* else: valid but unknown file */
1159 if (type != FILE_TYPE_DISK) {
1160 if (type == FILE_TYPE_CHAR)
1161 result->st_mode = _S_IFCHR;
1162 else if (type == FILE_TYPE_PIPE)
1163 result->st_mode = _S_IFIFO;
1164 return 0;
1167 if (!GetFileInformationByHandle(h, &info)) {
1168 return -1;
1171 /* similar to stat() */
1172 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1173 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1174 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1175 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1176 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1177 /* specific to fstat() */
1178 result->st_nlink = info.nNumberOfLinks;
1179 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1180 return 0;
1183 #endif /* MS_WINDOWS */
1185 PyDoc_STRVAR(stat_result__doc__,
1186 "stat_result: Result from stat or lstat.\n\n\
1187 This object may be accessed either as a tuple of\n\
1188 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
1189 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1191 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1192 or st_flags, they are available as attributes only.\n\
1194 See os.stat for more information.");
1196 static PyStructSequence_Field stat_result_fields[] = {
1197 {"st_mode", "protection bits"},
1198 {"st_ino", "inode"},
1199 {"st_dev", "device"},
1200 {"st_nlink", "number of hard links"},
1201 {"st_uid", "user ID of owner"},
1202 {"st_gid", "group ID of owner"},
1203 {"st_size", "total size, in bytes"},
1204 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1205 {NULL, "integer time of last access"},
1206 {NULL, "integer time of last modification"},
1207 {NULL, "integer time of last change"},
1208 {"st_atime", "time of last access"},
1209 {"st_mtime", "time of last modification"},
1210 {"st_ctime", "time of last change"},
1211 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1212 {"st_blksize", "blocksize for filesystem I/O"},
1213 #endif
1214 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1215 {"st_blocks", "number of blocks allocated"},
1216 #endif
1217 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1218 {"st_rdev", "device type (if inode device)"},
1219 #endif
1220 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1221 {"st_flags", "user defined flags for file"},
1222 #endif
1223 #ifdef HAVE_STRUCT_STAT_ST_GEN
1224 {"st_gen", "generation number"},
1225 #endif
1226 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1227 {"st_birthtime", "time of creation"},
1228 #endif
1232 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1233 #define ST_BLKSIZE_IDX 13
1234 #else
1235 #define ST_BLKSIZE_IDX 12
1236 #endif
1238 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1239 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1240 #else
1241 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1242 #endif
1244 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1245 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1246 #else
1247 #define ST_RDEV_IDX ST_BLOCKS_IDX
1248 #endif
1250 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1251 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1252 #else
1253 #define ST_FLAGS_IDX ST_RDEV_IDX
1254 #endif
1256 #ifdef HAVE_STRUCT_STAT_ST_GEN
1257 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
1258 #else
1259 #define ST_GEN_IDX ST_FLAGS_IDX
1260 #endif
1262 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1263 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1264 #else
1265 #define ST_BIRTHTIME_IDX ST_GEN_IDX
1266 #endif
1268 static PyStructSequence_Desc stat_result_desc = {
1269 "stat_result", /* name */
1270 stat_result__doc__, /* doc */
1271 stat_result_fields,
1275 PyDoc_STRVAR(statvfs_result__doc__,
1276 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
1277 This object may be accessed either as a tuple of\n\
1278 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
1279 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
1281 See os.statvfs for more information.");
1283 static PyStructSequence_Field statvfs_result_fields[] = {
1284 {"f_bsize", },
1285 {"f_frsize", },
1286 {"f_blocks", },
1287 {"f_bfree", },
1288 {"f_bavail", },
1289 {"f_files", },
1290 {"f_ffree", },
1291 {"f_favail", },
1292 {"f_flag", },
1293 {"f_namemax",},
1297 static PyStructSequence_Desc statvfs_result_desc = {
1298 "statvfs_result", /* name */
1299 statvfs_result__doc__, /* doc */
1300 statvfs_result_fields,
1304 static int initialized;
1305 static PyTypeObject StatResultType;
1306 static PyTypeObject StatVFSResultType;
1307 static newfunc structseq_new;
1309 static PyObject *
1310 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1312 PyStructSequence *result;
1313 int i;
1315 result = (PyStructSequence*)structseq_new(type, args, kwds);
1316 if (!result)
1317 return NULL;
1318 /* If we have been initialized from a tuple,
1319 st_?time might be set to None. Initialize it
1320 from the int slots. */
1321 for (i = 7; i <= 9; i++) {
1322 if (result->ob_item[i+3] == Py_None) {
1323 Py_DECREF(Py_None);
1324 Py_INCREF(result->ob_item[i]);
1325 result->ob_item[i+3] = result->ob_item[i];
1328 return (PyObject*)result;
1333 /* If true, st_?time is float. */
1334 static int _stat_float_times = 1;
1336 PyDoc_STRVAR(stat_float_times__doc__,
1337 "stat_float_times([newval]) -> oldval\n\n\
1338 Determine whether os.[lf]stat represents time stamps as float objects.\n\
1339 If newval is True, future calls to stat() return floats, if it is False,\n\
1340 future calls return ints. \n\
1341 If newval is omitted, return the current setting.\n");
1343 static PyObject*
1344 stat_float_times(PyObject* self, PyObject *args)
1346 int newval = -1;
1347 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1348 return NULL;
1349 if (newval == -1)
1350 /* Return old value */
1351 return PyBool_FromLong(_stat_float_times);
1352 _stat_float_times = newval;
1353 Py_INCREF(Py_None);
1354 return Py_None;
1357 static void
1358 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1360 PyObject *fval,*ival;
1361 #if SIZEOF_TIME_T > SIZEOF_LONG
1362 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
1363 #else
1364 ival = PyInt_FromLong((long)sec);
1365 #endif
1366 if (!ival)
1367 return;
1368 if (_stat_float_times) {
1369 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1370 } else {
1371 fval = ival;
1372 Py_INCREF(fval);
1374 PyStructSequence_SET_ITEM(v, index, ival);
1375 PyStructSequence_SET_ITEM(v, index+3, fval);
1378 /* pack a system stat C structure into the Python stat tuple
1379 (used by posix_stat() and posix_fstat()) */
1380 static PyObject*
1381 _pystat_fromstructstat(STRUCT_STAT *st)
1383 unsigned long ansec, mnsec, cnsec;
1384 PyObject *v = PyStructSequence_New(&StatResultType);
1385 if (v == NULL)
1386 return NULL;
1388 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
1389 #ifdef HAVE_LARGEFILE_SUPPORT
1390 PyStructSequence_SET_ITEM(v, 1,
1391 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
1392 #else
1393 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
1394 #endif
1395 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
1396 PyStructSequence_SET_ITEM(v, 2,
1397 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
1398 #else
1399 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
1400 #endif
1401 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1402 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1403 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
1404 #ifdef HAVE_LARGEFILE_SUPPORT
1405 PyStructSequence_SET_ITEM(v, 6,
1406 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
1407 #else
1408 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
1409 #endif
1411 #if defined(HAVE_STAT_TV_NSEC)
1412 ansec = st->st_atim.tv_nsec;
1413 mnsec = st->st_mtim.tv_nsec;
1414 cnsec = st->st_ctim.tv_nsec;
1415 #elif defined(HAVE_STAT_TV_NSEC2)
1416 ansec = st->st_atimespec.tv_nsec;
1417 mnsec = st->st_mtimespec.tv_nsec;
1418 cnsec = st->st_ctimespec.tv_nsec;
1419 #elif defined(HAVE_STAT_NSEC)
1420 ansec = st->st_atime_nsec;
1421 mnsec = st->st_mtime_nsec;
1422 cnsec = st->st_ctime_nsec;
1423 #else
1424 ansec = mnsec = cnsec = 0;
1425 #endif
1426 fill_time(v, 7, st->st_atime, ansec);
1427 fill_time(v, 8, st->st_mtime, mnsec);
1428 fill_time(v, 9, st->st_ctime, cnsec);
1430 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1431 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1432 PyInt_FromLong((long)st->st_blksize));
1433 #endif
1434 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1435 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1436 PyInt_FromLong((long)st->st_blocks));
1437 #endif
1438 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1439 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1440 PyInt_FromLong((long)st->st_rdev));
1441 #endif
1442 #ifdef HAVE_STRUCT_STAT_ST_GEN
1443 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1444 PyInt_FromLong((long)st->st_gen));
1445 #endif
1446 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1448 PyObject *val;
1449 unsigned long bsec,bnsec;
1450 bsec = (long)st->st_birthtime;
1451 #ifdef HAVE_STAT_TV_NSEC2
1452 bnsec = st->st_birthtimespec.tv_nsec;
1453 #else
1454 bnsec = 0;
1455 #endif
1456 if (_stat_float_times) {
1457 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1458 } else {
1459 val = PyInt_FromLong((long)bsec);
1461 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1462 val);
1464 #endif
1465 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1466 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1467 PyInt_FromLong((long)st->st_flags));
1468 #endif
1470 if (PyErr_Occurred()) {
1471 Py_DECREF(v);
1472 return NULL;
1475 return v;
1478 #ifdef MS_WINDOWS
1480 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1481 where / can be used in place of \ and the trailing slash is optional.
1482 Both SERVER and SHARE must have at least one character.
1485 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1486 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1487 #ifndef ARRAYSIZE
1488 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1489 #endif
1491 static BOOL
1492 IsUNCRootA(char *path, int pathlen)
1494 #define ISSLASH ISSLASHA
1496 int i, share;
1498 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1499 /* minimum UNCRoot is \\x\y */
1500 return FALSE;
1501 for (i = 2; i < pathlen ; i++)
1502 if (ISSLASH(path[i])) break;
1503 if (i == 2 || i == pathlen)
1504 /* do not allow \\\SHARE or \\SERVER */
1505 return FALSE;
1506 share = i+1;
1507 for (i = share; i < pathlen; i++)
1508 if (ISSLASH(path[i])) break;
1509 return (i != share && (i == pathlen || i == pathlen-1));
1511 #undef ISSLASH
1514 static BOOL
1515 IsUNCRootW(Py_UNICODE *path, int pathlen)
1517 #define ISSLASH ISSLASHW
1519 int i, share;
1521 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1522 /* minimum UNCRoot is \\x\y */
1523 return FALSE;
1524 for (i = 2; i < pathlen ; i++)
1525 if (ISSLASH(path[i])) break;
1526 if (i == 2 || i == pathlen)
1527 /* do not allow \\\SHARE or \\SERVER */
1528 return FALSE;
1529 share = i+1;
1530 for (i = share; i < pathlen; i++)
1531 if (ISSLASH(path[i])) break;
1532 return (i != share && (i == pathlen || i == pathlen-1));
1534 #undef ISSLASH
1536 #endif /* MS_WINDOWS */
1538 static PyObject *
1539 posix_do_stat(PyObject *self, PyObject *args,
1540 char *format,
1541 #ifdef __VMS
1542 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1543 #else
1544 int (*statfunc)(const char *, STRUCT_STAT *),
1545 #endif
1546 char *wformat,
1547 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
1549 STRUCT_STAT st;
1550 char *path = NULL; /* pass this to stat; do not free() it */
1551 char *pathfree = NULL; /* this memory must be free'd */
1552 int res;
1553 PyObject *result;
1555 #ifdef MS_WINDOWS
1556 /* If on wide-character-capable OS see if argument
1557 is Unicode and if so use wide API. */
1558 if (unicode_file_names()) {
1559 PyUnicodeObject *po;
1560 if (PyArg_ParseTuple(args, wformat, &po)) {
1561 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1563 Py_BEGIN_ALLOW_THREADS
1564 /* PyUnicode_AS_UNICODE result OK without
1565 thread lock as it is a simple dereference. */
1566 res = wstatfunc(wpath, &st);
1567 Py_END_ALLOW_THREADS
1569 if (res != 0)
1570 return win32_error_unicode("stat", wpath);
1571 return _pystat_fromstructstat(&st);
1573 /* Drop the argument parsing error as narrow strings
1574 are also valid. */
1575 PyErr_Clear();
1577 #endif
1579 if (!PyArg_ParseTuple(args, format,
1580 Py_FileSystemDefaultEncoding, &path))
1581 return NULL;
1582 pathfree = path;
1584 Py_BEGIN_ALLOW_THREADS
1585 res = (*statfunc)(path, &st);
1586 Py_END_ALLOW_THREADS
1588 if (res != 0) {
1589 #ifdef MS_WINDOWS
1590 result = win32_error("stat", pathfree);
1591 #else
1592 result = posix_error_with_filename(pathfree);
1593 #endif
1595 else
1596 result = _pystat_fromstructstat(&st);
1598 PyMem_Free(pathfree);
1599 return result;
1602 /* POSIX methods */
1604 PyDoc_STRVAR(posix_access__doc__,
1605 "access(path, mode) -> True if granted, False otherwise\n\n\
1606 Use the real uid/gid to test for access to a path. Note that most\n\
1607 operations will use the effective uid/gid, therefore this routine can\n\
1608 be used in a suid/sgid environment to test if the invoking user has the\n\
1609 specified access to the path. The mode argument can be F_OK to test\n\
1610 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1612 static PyObject *
1613 posix_access(PyObject *self, PyObject *args)
1615 char *path;
1616 int mode;
1618 #ifdef MS_WINDOWS
1619 DWORD attr;
1620 if (unicode_file_names()) {
1621 PyUnicodeObject *po;
1622 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1623 Py_BEGIN_ALLOW_THREADS
1624 /* PyUnicode_AS_UNICODE OK without thread lock as
1625 it is a simple dereference. */
1626 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1627 Py_END_ALLOW_THREADS
1628 goto finish;
1630 /* Drop the argument parsing error as narrow strings
1631 are also valid. */
1632 PyErr_Clear();
1634 if (!PyArg_ParseTuple(args, "eti:access",
1635 Py_FileSystemDefaultEncoding, &path, &mode))
1636 return 0;
1637 Py_BEGIN_ALLOW_THREADS
1638 attr = GetFileAttributesA(path);
1639 Py_END_ALLOW_THREADS
1640 PyMem_Free(path);
1641 finish:
1642 if (attr == 0xFFFFFFFF)
1643 /* File does not exist, or cannot read attributes */
1644 return PyBool_FromLong(0);
1645 /* Access is possible if either write access wasn't requested, or
1646 the file isn't read-only, or if it's a directory, as there are
1647 no read-only directories on Windows. */
1648 return PyBool_FromLong(!(mode & 2)
1649 || !(attr & FILE_ATTRIBUTE_READONLY)
1650 || (attr & FILE_ATTRIBUTE_DIRECTORY));
1651 #else /* MS_WINDOWS */
1652 int res;
1653 if (!PyArg_ParseTuple(args, "eti:access",
1654 Py_FileSystemDefaultEncoding, &path, &mode))
1655 return NULL;
1656 Py_BEGIN_ALLOW_THREADS
1657 res = access(path, mode);
1658 Py_END_ALLOW_THREADS
1659 PyMem_Free(path);
1660 return PyBool_FromLong(res == 0);
1661 #endif /* MS_WINDOWS */
1664 #ifndef F_OK
1665 #define F_OK 0
1666 #endif
1667 #ifndef R_OK
1668 #define R_OK 4
1669 #endif
1670 #ifndef W_OK
1671 #define W_OK 2
1672 #endif
1673 #ifndef X_OK
1674 #define X_OK 1
1675 #endif
1677 #ifdef HAVE_TTYNAME
1678 PyDoc_STRVAR(posix_ttyname__doc__,
1679 "ttyname(fd) -> string\n\n\
1680 Return the name of the terminal device connected to 'fd'.");
1682 static PyObject *
1683 posix_ttyname(PyObject *self, PyObject *args)
1685 int id;
1686 char *ret;
1688 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1689 return NULL;
1691 #if defined(__VMS)
1692 /* file descriptor 0 only, the default input device (stdin) */
1693 if (id == 0) {
1694 ret = ttyname();
1696 else {
1697 ret = NULL;
1699 #else
1700 ret = ttyname(id);
1701 #endif
1702 if (ret == NULL)
1703 return posix_error();
1704 return PyString_FromString(ret);
1706 #endif
1708 #ifdef HAVE_CTERMID
1709 PyDoc_STRVAR(posix_ctermid__doc__,
1710 "ctermid() -> string\n\n\
1711 Return the name of the controlling terminal for this process.");
1713 static PyObject *
1714 posix_ctermid(PyObject *self, PyObject *noargs)
1716 char *ret;
1717 char buffer[L_ctermid];
1719 #ifdef USE_CTERMID_R
1720 ret = ctermid_r(buffer);
1721 #else
1722 ret = ctermid(buffer);
1723 #endif
1724 if (ret == NULL)
1725 return posix_error();
1726 return PyString_FromString(buffer);
1728 #endif
1730 PyDoc_STRVAR(posix_chdir__doc__,
1731 "chdir(path)\n\n\
1732 Change the current working directory to the specified path.");
1734 static PyObject *
1735 posix_chdir(PyObject *self, PyObject *args)
1737 #ifdef MS_WINDOWS
1738 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
1739 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1740 return posix_1str(args, "et:chdir", _chdir2);
1741 #elif defined(__VMS)
1742 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
1743 #else
1744 return posix_1str(args, "et:chdir", chdir);
1745 #endif
1748 #ifdef HAVE_FCHDIR
1749 PyDoc_STRVAR(posix_fchdir__doc__,
1750 "fchdir(fildes)\n\n\
1751 Change to the directory of the given file descriptor. fildes must be\n\
1752 opened on a directory, not a file.");
1754 static PyObject *
1755 posix_fchdir(PyObject *self, PyObject *fdobj)
1757 return posix_fildes(fdobj, fchdir);
1759 #endif /* HAVE_FCHDIR */
1762 PyDoc_STRVAR(posix_chmod__doc__,
1763 "chmod(path, mode)\n\n\
1764 Change the access permissions of a file.");
1766 static PyObject *
1767 posix_chmod(PyObject *self, PyObject *args)
1769 char *path = NULL;
1770 int i;
1771 int res;
1772 #ifdef MS_WINDOWS
1773 DWORD attr;
1774 if (unicode_file_names()) {
1775 PyUnicodeObject *po;
1776 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1777 Py_BEGIN_ALLOW_THREADS
1778 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1779 if (attr != 0xFFFFFFFF) {
1780 if (i & _S_IWRITE)
1781 attr &= ~FILE_ATTRIBUTE_READONLY;
1782 else
1783 attr |= FILE_ATTRIBUTE_READONLY;
1784 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1786 else
1787 res = 0;
1788 Py_END_ALLOW_THREADS
1789 if (!res)
1790 return win32_error_unicode("chmod",
1791 PyUnicode_AS_UNICODE(po));
1792 Py_INCREF(Py_None);
1793 return Py_None;
1795 /* Drop the argument parsing error as narrow strings
1796 are also valid. */
1797 PyErr_Clear();
1799 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1800 &path, &i))
1801 return NULL;
1802 Py_BEGIN_ALLOW_THREADS
1803 attr = GetFileAttributesA(path);
1804 if (attr != 0xFFFFFFFF) {
1805 if (i & _S_IWRITE)
1806 attr &= ~FILE_ATTRIBUTE_READONLY;
1807 else
1808 attr |= FILE_ATTRIBUTE_READONLY;
1809 res = SetFileAttributesA(path, attr);
1811 else
1812 res = 0;
1813 Py_END_ALLOW_THREADS
1814 if (!res) {
1815 win32_error("chmod", path);
1816 PyMem_Free(path);
1817 return NULL;
1819 PyMem_Free(path);
1820 Py_INCREF(Py_None);
1821 return Py_None;
1822 #else /* MS_WINDOWS */
1823 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1824 &path, &i))
1825 return NULL;
1826 Py_BEGIN_ALLOW_THREADS
1827 res = chmod(path, i);
1828 Py_END_ALLOW_THREADS
1829 if (res < 0)
1830 return posix_error_with_allocated_filename(path);
1831 PyMem_Free(path);
1832 Py_INCREF(Py_None);
1833 return Py_None;
1834 #endif
1837 #ifdef HAVE_FCHMOD
1838 PyDoc_STRVAR(posix_fchmod__doc__,
1839 "fchmod(fd, mode)\n\n\
1840 Change the access permissions of the file given by file\n\
1841 descriptor fd.");
1843 static PyObject *
1844 posix_fchmod(PyObject *self, PyObject *args)
1846 int fd, mode, res;
1847 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1848 return NULL;
1849 Py_BEGIN_ALLOW_THREADS
1850 res = fchmod(fd, mode);
1851 Py_END_ALLOW_THREADS
1852 if (res < 0)
1853 return posix_error();
1854 Py_RETURN_NONE;
1856 #endif /* HAVE_FCHMOD */
1858 #ifdef HAVE_LCHMOD
1859 PyDoc_STRVAR(posix_lchmod__doc__,
1860 "lchmod(path, mode)\n\n\
1861 Change the access permissions of a file. If path is a symlink, this\n\
1862 affects the link itself rather than the target.");
1864 static PyObject *
1865 posix_lchmod(PyObject *self, PyObject *args)
1867 char *path = NULL;
1868 int i;
1869 int res;
1870 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1871 &path, &i))
1872 return NULL;
1873 Py_BEGIN_ALLOW_THREADS
1874 res = lchmod(path, i);
1875 Py_END_ALLOW_THREADS
1876 if (res < 0)
1877 return posix_error_with_allocated_filename(path);
1878 PyMem_Free(path);
1879 Py_RETURN_NONE;
1881 #endif /* HAVE_LCHMOD */
1884 #ifdef HAVE_CHFLAGS
1885 PyDoc_STRVAR(posix_chflags__doc__,
1886 "chflags(path, flags)\n\n\
1887 Set file flags.");
1889 static PyObject *
1890 posix_chflags(PyObject *self, PyObject *args)
1892 char *path;
1893 unsigned long flags;
1894 int res;
1895 if (!PyArg_ParseTuple(args, "etk:chflags",
1896 Py_FileSystemDefaultEncoding, &path, &flags))
1897 return NULL;
1898 Py_BEGIN_ALLOW_THREADS
1899 res = chflags(path, flags);
1900 Py_END_ALLOW_THREADS
1901 if (res < 0)
1902 return posix_error_with_allocated_filename(path);
1903 PyMem_Free(path);
1904 Py_INCREF(Py_None);
1905 return Py_None;
1907 #endif /* HAVE_CHFLAGS */
1909 #ifdef HAVE_LCHFLAGS
1910 PyDoc_STRVAR(posix_lchflags__doc__,
1911 "lchflags(path, flags)\n\n\
1912 Set file flags.\n\
1913 This function will not follow symbolic links.");
1915 static PyObject *
1916 posix_lchflags(PyObject *self, PyObject *args)
1918 char *path;
1919 unsigned long flags;
1920 int res;
1921 if (!PyArg_ParseTuple(args, "etk:lchflags",
1922 Py_FileSystemDefaultEncoding, &path, &flags))
1923 return NULL;
1924 Py_BEGIN_ALLOW_THREADS
1925 res = lchflags(path, flags);
1926 Py_END_ALLOW_THREADS
1927 if (res < 0)
1928 return posix_error_with_allocated_filename(path);
1929 PyMem_Free(path);
1930 Py_INCREF(Py_None);
1931 return Py_None;
1933 #endif /* HAVE_LCHFLAGS */
1935 #ifdef HAVE_CHROOT
1936 PyDoc_STRVAR(posix_chroot__doc__,
1937 "chroot(path)\n\n\
1938 Change root directory to path.");
1940 static PyObject *
1941 posix_chroot(PyObject *self, PyObject *args)
1943 return posix_1str(args, "et:chroot", chroot);
1945 #endif
1947 #ifdef HAVE_FSYNC
1948 PyDoc_STRVAR(posix_fsync__doc__,
1949 "fsync(fildes)\n\n\
1950 force write of file with filedescriptor to disk.");
1952 static PyObject *
1953 posix_fsync(PyObject *self, PyObject *fdobj)
1955 return posix_fildes(fdobj, fsync);
1957 #endif /* HAVE_FSYNC */
1959 #ifdef HAVE_FDATASYNC
1961 #ifdef __hpux
1962 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1963 #endif
1965 PyDoc_STRVAR(posix_fdatasync__doc__,
1966 "fdatasync(fildes)\n\n\
1967 force write of file with filedescriptor to disk.\n\
1968 does not force update of metadata.");
1970 static PyObject *
1971 posix_fdatasync(PyObject *self, PyObject *fdobj)
1973 return posix_fildes(fdobj, fdatasync);
1975 #endif /* HAVE_FDATASYNC */
1978 #ifdef HAVE_CHOWN
1979 PyDoc_STRVAR(posix_chown__doc__,
1980 "chown(path, uid, gid)\n\n\
1981 Change the owner and group id of path to the numeric uid and gid.");
1983 static PyObject *
1984 posix_chown(PyObject *self, PyObject *args)
1986 char *path = NULL;
1987 long uid, gid;
1988 int res;
1989 if (!PyArg_ParseTuple(args, "etll:chown",
1990 Py_FileSystemDefaultEncoding, &path,
1991 &uid, &gid))
1992 return NULL;
1993 Py_BEGIN_ALLOW_THREADS
1994 res = chown(path, (uid_t) uid, (gid_t) gid);
1995 Py_END_ALLOW_THREADS
1996 if (res < 0)
1997 return posix_error_with_allocated_filename(path);
1998 PyMem_Free(path);
1999 Py_INCREF(Py_None);
2000 return Py_None;
2002 #endif /* HAVE_CHOWN */
2004 #ifdef HAVE_FCHOWN
2005 PyDoc_STRVAR(posix_fchown__doc__,
2006 "fchown(fd, uid, gid)\n\n\
2007 Change the owner and group id of the file given by file descriptor\n\
2008 fd to the numeric uid and gid.");
2010 static PyObject *
2011 posix_fchown(PyObject *self, PyObject *args)
2013 int fd, uid, gid;
2014 int res;
2015 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
2016 return NULL;
2017 Py_BEGIN_ALLOW_THREADS
2018 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2019 Py_END_ALLOW_THREADS
2020 if (res < 0)
2021 return posix_error();
2022 Py_RETURN_NONE;
2024 #endif /* HAVE_FCHOWN */
2026 #ifdef HAVE_LCHOWN
2027 PyDoc_STRVAR(posix_lchown__doc__,
2028 "lchown(path, uid, gid)\n\n\
2029 Change the owner and group id of path to the numeric uid and gid.\n\
2030 This function will not follow symbolic links.");
2032 static PyObject *
2033 posix_lchown(PyObject *self, PyObject *args)
2035 char *path = NULL;
2036 int uid, gid;
2037 int res;
2038 if (!PyArg_ParseTuple(args, "etii:lchown",
2039 Py_FileSystemDefaultEncoding, &path,
2040 &uid, &gid))
2041 return NULL;
2042 Py_BEGIN_ALLOW_THREADS
2043 res = lchown(path, (uid_t) uid, (gid_t) gid);
2044 Py_END_ALLOW_THREADS
2045 if (res < 0)
2046 return posix_error_with_allocated_filename(path);
2047 PyMem_Free(path);
2048 Py_INCREF(Py_None);
2049 return Py_None;
2051 #endif /* HAVE_LCHOWN */
2054 #ifdef HAVE_GETCWD
2055 PyDoc_STRVAR(posix_getcwd__doc__,
2056 "getcwd() -> path\n\n\
2057 Return a string representing the current working directory.");
2059 static PyObject *
2060 posix_getcwd(PyObject *self, PyObject *noargs)
2062 int bufsize_incr = 1024;
2063 int bufsize = 0;
2064 char *tmpbuf = NULL;
2065 char *res = NULL;
2066 PyObject *dynamic_return;
2068 Py_BEGIN_ALLOW_THREADS
2069 do {
2070 bufsize = bufsize + bufsize_incr;
2071 tmpbuf = malloc(bufsize);
2072 if (tmpbuf == NULL) {
2073 break;
2075 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2076 res = _getcwd2(tmpbuf, bufsize);
2077 #else
2078 res = getcwd(tmpbuf, bufsize);
2079 #endif
2081 if (res == NULL) {
2082 free(tmpbuf);
2084 } while ((res == NULL) && (errno == ERANGE));
2085 Py_END_ALLOW_THREADS
2087 if (res == NULL)
2088 return posix_error();
2090 dynamic_return = PyString_FromString(tmpbuf);
2091 free(tmpbuf);
2093 return dynamic_return;
2096 #ifdef Py_USING_UNICODE
2097 PyDoc_STRVAR(posix_getcwdu__doc__,
2098 "getcwdu() -> path\n\n\
2099 Return a unicode string representing the current working directory.");
2101 static PyObject *
2102 posix_getcwdu(PyObject *self, PyObject *noargs)
2104 char buf[1026];
2105 char *res;
2107 #ifdef MS_WINDOWS
2108 DWORD len;
2109 if (unicode_file_names()) {
2110 wchar_t wbuf[1026];
2111 wchar_t *wbuf2 = wbuf;
2112 PyObject *resobj;
2113 Py_BEGIN_ALLOW_THREADS
2114 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2115 /* If the buffer is large enough, len does not include the
2116 terminating \0. If the buffer is too small, len includes
2117 the space needed for the terminator. */
2118 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2119 wbuf2 = malloc(len * sizeof(wchar_t));
2120 if (wbuf2)
2121 len = GetCurrentDirectoryW(len, wbuf2);
2123 Py_END_ALLOW_THREADS
2124 if (!wbuf2) {
2125 PyErr_NoMemory();
2126 return NULL;
2128 if (!len) {
2129 if (wbuf2 != wbuf) free(wbuf2);
2130 return win32_error("getcwdu", NULL);
2132 resobj = PyUnicode_FromWideChar(wbuf2, len);
2133 if (wbuf2 != wbuf) free(wbuf2);
2134 return resobj;
2136 #endif /* MS_WINDOWS */
2138 Py_BEGIN_ALLOW_THREADS
2139 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2140 res = _getcwd2(buf, sizeof buf);
2141 #else
2142 res = getcwd(buf, sizeof buf);
2143 #endif
2144 Py_END_ALLOW_THREADS
2145 if (res == NULL)
2146 return posix_error();
2147 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2149 #endif /* Py_USING_UNICODE */
2150 #endif /* HAVE_GETCWD */
2153 #ifdef HAVE_LINK
2154 PyDoc_STRVAR(posix_link__doc__,
2155 "link(src, dst)\n\n\
2156 Create a hard link to a file.");
2158 static PyObject *
2159 posix_link(PyObject *self, PyObject *args)
2161 return posix_2str(args, "etet:link", link);
2163 #endif /* HAVE_LINK */
2166 PyDoc_STRVAR(posix_listdir__doc__,
2167 "listdir(path) -> list_of_strings\n\n\
2168 Return a list containing the names of the entries in the directory.\n\
2170 path: path of directory to list\n\
2172 The list is in arbitrary order. It does not include the special\n\
2173 entries '.' and '..' even if they are present in the directory.");
2175 static PyObject *
2176 posix_listdir(PyObject *self, PyObject *args)
2178 /* XXX Should redo this putting the (now four) versions of opendir
2179 in separate files instead of having them all here... */
2180 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
2182 PyObject *d, *v;
2183 HANDLE hFindFile;
2184 BOOL result;
2185 WIN32_FIND_DATA FileData;
2186 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2187 char *bufptr = namebuf;
2188 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
2190 /* If on wide-character-capable OS see if argument
2191 is Unicode and if so use wide API. */
2192 if (unicode_file_names()) {
2193 PyObject *po;
2194 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2195 WIN32_FIND_DATAW wFileData;
2196 Py_UNICODE *wnamebuf;
2197 /* Overallocate for \\*.*\0 */
2198 len = PyUnicode_GET_SIZE(po);
2199 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2200 if (!wnamebuf) {
2201 PyErr_NoMemory();
2202 return NULL;
2204 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2205 if (len > 0) {
2206 Py_UNICODE wch = wnamebuf[len-1];
2207 if (wch != L'/' && wch != L'\\' && wch != L':')
2208 wnamebuf[len++] = L'\\';
2209 wcscpy(wnamebuf + len, L"*.*");
2211 if ((d = PyList_New(0)) == NULL) {
2212 free(wnamebuf);
2213 return NULL;
2215 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2216 if (hFindFile == INVALID_HANDLE_VALUE) {
2217 int error = GetLastError();
2218 if (error == ERROR_FILE_NOT_FOUND) {
2219 free(wnamebuf);
2220 return d;
2222 Py_DECREF(d);
2223 win32_error_unicode("FindFirstFileW", wnamebuf);
2224 free(wnamebuf);
2225 return NULL;
2227 do {
2228 /* Skip over . and .. */
2229 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2230 wcscmp(wFileData.cFileName, L"..") != 0) {
2231 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2232 if (v == NULL) {
2233 Py_DECREF(d);
2234 d = NULL;
2235 break;
2237 if (PyList_Append(d, v) != 0) {
2238 Py_DECREF(v);
2239 Py_DECREF(d);
2240 d = NULL;
2241 break;
2243 Py_DECREF(v);
2245 Py_BEGIN_ALLOW_THREADS
2246 result = FindNextFileW(hFindFile, &wFileData);
2247 Py_END_ALLOW_THREADS
2248 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2249 it got to the end of the directory. */
2250 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2251 Py_DECREF(d);
2252 win32_error_unicode("FindNextFileW", wnamebuf);
2253 FindClose(hFindFile);
2254 free(wnamebuf);
2255 return NULL;
2257 } while (result == TRUE);
2259 if (FindClose(hFindFile) == FALSE) {
2260 Py_DECREF(d);
2261 win32_error_unicode("FindClose", wnamebuf);
2262 free(wnamebuf);
2263 return NULL;
2265 free(wnamebuf);
2266 return d;
2268 /* Drop the argument parsing error as narrow strings
2269 are also valid. */
2270 PyErr_Clear();
2273 if (!PyArg_ParseTuple(args, "et#:listdir",
2274 Py_FileSystemDefaultEncoding, &bufptr, &len))
2275 return NULL;
2276 if (len > 0) {
2277 char ch = namebuf[len-1];
2278 if (ch != SEP && ch != ALTSEP && ch != ':')
2279 namebuf[len++] = '/';
2280 strcpy(namebuf + len, "*.*");
2283 if ((d = PyList_New(0)) == NULL)
2284 return NULL;
2286 hFindFile = FindFirstFile(namebuf, &FileData);
2287 if (hFindFile == INVALID_HANDLE_VALUE) {
2288 int error = GetLastError();
2289 if (error == ERROR_FILE_NOT_FOUND)
2290 return d;
2291 Py_DECREF(d);
2292 return win32_error("FindFirstFile", namebuf);
2294 do {
2295 /* Skip over . and .. */
2296 if (strcmp(FileData.cFileName, ".") != 0 &&
2297 strcmp(FileData.cFileName, "..") != 0) {
2298 v = PyString_FromString(FileData.cFileName);
2299 if (v == NULL) {
2300 Py_DECREF(d);
2301 d = NULL;
2302 break;
2304 if (PyList_Append(d, v) != 0) {
2305 Py_DECREF(v);
2306 Py_DECREF(d);
2307 d = NULL;
2308 break;
2310 Py_DECREF(v);
2312 Py_BEGIN_ALLOW_THREADS
2313 result = FindNextFile(hFindFile, &FileData);
2314 Py_END_ALLOW_THREADS
2315 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2316 it got to the end of the directory. */
2317 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2318 Py_DECREF(d);
2319 win32_error("FindNextFile", namebuf);
2320 FindClose(hFindFile);
2321 return NULL;
2323 } while (result == TRUE);
2325 if (FindClose(hFindFile) == FALSE) {
2326 Py_DECREF(d);
2327 return win32_error("FindClose", namebuf);
2330 return d;
2332 #elif defined(PYOS_OS2)
2334 #ifndef MAX_PATH
2335 #define MAX_PATH CCHMAXPATH
2336 #endif
2337 char *name, *pt;
2338 Py_ssize_t len;
2339 PyObject *d, *v;
2340 char namebuf[MAX_PATH+5];
2341 HDIR hdir = 1;
2342 ULONG srchcnt = 1;
2343 FILEFINDBUF3 ep;
2344 APIRET rc;
2346 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
2347 return NULL;
2348 if (len >= MAX_PATH) {
2349 PyErr_SetString(PyExc_ValueError, "path too long");
2350 return NULL;
2352 strcpy(namebuf, name);
2353 for (pt = namebuf; *pt; pt++)
2354 if (*pt == ALTSEP)
2355 *pt = SEP;
2356 if (namebuf[len-1] != SEP)
2357 namebuf[len++] = SEP;
2358 strcpy(namebuf + len, "*.*");
2360 if ((d = PyList_New(0)) == NULL)
2361 return NULL;
2363 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2364 &hdir, /* Handle to Use While Search Directory */
2365 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
2366 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2367 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2368 FIL_STANDARD); /* Format of Entry (EAs or Not) */
2370 if (rc != NO_ERROR) {
2371 errno = ENOENT;
2372 return posix_error_with_filename(name);
2375 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
2376 do {
2377 if (ep.achName[0] == '.'
2378 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
2379 continue; /* Skip Over "." and ".." Names */
2381 strcpy(namebuf, ep.achName);
2383 /* Leave Case of Name Alone -- In Native Form */
2384 /* (Removed Forced Lowercasing Code) */
2386 v = PyString_FromString(namebuf);
2387 if (v == NULL) {
2388 Py_DECREF(d);
2389 d = NULL;
2390 break;
2392 if (PyList_Append(d, v) != 0) {
2393 Py_DECREF(v);
2394 Py_DECREF(d);
2395 d = NULL;
2396 break;
2398 Py_DECREF(v);
2399 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2402 return d;
2403 #else
2405 char *name = NULL;
2406 PyObject *d, *v;
2407 DIR *dirp;
2408 struct dirent *ep;
2409 int arg_is_unicode = 1;
2411 errno = 0;
2412 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2413 arg_is_unicode = 0;
2414 PyErr_Clear();
2416 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2417 return NULL;
2418 if ((dirp = opendir(name)) == NULL) {
2419 return posix_error_with_allocated_filename(name);
2421 if ((d = PyList_New(0)) == NULL) {
2422 closedir(dirp);
2423 PyMem_Free(name);
2424 return NULL;
2426 for (;;) {
2427 errno = 0;
2428 Py_BEGIN_ALLOW_THREADS
2429 ep = readdir(dirp);
2430 Py_END_ALLOW_THREADS
2431 if (ep == NULL) {
2432 if (errno == 0) {
2433 break;
2434 } else {
2435 closedir(dirp);
2436 Py_DECREF(d);
2437 return posix_error_with_allocated_filename(name);
2440 if (ep->d_name[0] == '.' &&
2441 (NAMLEN(ep) == 1 ||
2442 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2443 continue;
2444 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2445 if (v == NULL) {
2446 Py_DECREF(d);
2447 d = NULL;
2448 break;
2450 #ifdef Py_USING_UNICODE
2451 if (arg_is_unicode) {
2452 PyObject *w;
2454 w = PyUnicode_FromEncodedObject(v,
2455 Py_FileSystemDefaultEncoding,
2456 "strict");
2457 if (w != NULL) {
2458 Py_DECREF(v);
2459 v = w;
2461 else {
2462 /* fall back to the original byte string, as
2463 discussed in patch #683592 */
2464 PyErr_Clear();
2467 #endif
2468 if (PyList_Append(d, v) != 0) {
2469 Py_DECREF(v);
2470 Py_DECREF(d);
2471 d = NULL;
2472 break;
2474 Py_DECREF(v);
2476 closedir(dirp);
2477 PyMem_Free(name);
2479 return d;
2481 #endif /* which OS */
2482 } /* end of posix_listdir */
2484 #ifdef MS_WINDOWS
2485 /* A helper function for abspath on win32 */
2486 static PyObject *
2487 posix__getfullpathname(PyObject *self, PyObject *args)
2489 /* assume encoded strings won't more than double no of chars */
2490 char inbuf[MAX_PATH*2];
2491 char *inbufp = inbuf;
2492 Py_ssize_t insize = sizeof(inbuf);
2493 char outbuf[MAX_PATH*2];
2494 char *temp;
2496 if (unicode_file_names()) {
2497 PyUnicodeObject *po;
2498 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2499 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2500 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2501 Py_UNICODE *wtemp;
2502 DWORD result;
2503 PyObject *v;
2504 result = GetFullPathNameW(wpath,
2505 sizeof(woutbuf)/sizeof(woutbuf[0]),
2506 woutbuf, &wtemp);
2507 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2508 woutbufp = malloc(result * sizeof(Py_UNICODE));
2509 if (!woutbufp)
2510 return PyErr_NoMemory();
2511 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2513 if (result)
2514 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2515 else
2516 v = win32_error_unicode("GetFullPathNameW", wpath);
2517 if (woutbufp != woutbuf)
2518 free(woutbufp);
2519 return v;
2521 /* Drop the argument parsing error as narrow strings
2522 are also valid. */
2523 PyErr_Clear();
2526 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2527 Py_FileSystemDefaultEncoding, &inbufp,
2528 &insize))
2529 return NULL;
2530 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2531 outbuf, &temp))
2532 return win32_error("GetFullPathName", inbuf);
2533 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2534 return PyUnicode_Decode(outbuf, strlen(outbuf),
2535 Py_FileSystemDefaultEncoding, NULL);
2537 return PyString_FromString(outbuf);
2538 } /* end of posix__getfullpathname */
2539 #endif /* MS_WINDOWS */
2541 PyDoc_STRVAR(posix_mkdir__doc__,
2542 "mkdir(path [, mode=0777])\n\n\
2543 Create a directory.");
2545 static PyObject *
2546 posix_mkdir(PyObject *self, PyObject *args)
2548 int res;
2549 char *path = NULL;
2550 int mode = 0777;
2552 #ifdef MS_WINDOWS
2553 if (unicode_file_names()) {
2554 PyUnicodeObject *po;
2555 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2556 Py_BEGIN_ALLOW_THREADS
2557 /* PyUnicode_AS_UNICODE OK without thread lock as
2558 it is a simple dereference. */
2559 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2560 Py_END_ALLOW_THREADS
2561 if (!res)
2562 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2563 Py_INCREF(Py_None);
2564 return Py_None;
2566 /* Drop the argument parsing error as narrow strings
2567 are also valid. */
2568 PyErr_Clear();
2570 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2571 Py_FileSystemDefaultEncoding, &path, &mode))
2572 return NULL;
2573 Py_BEGIN_ALLOW_THREADS
2574 /* PyUnicode_AS_UNICODE OK without thread lock as
2575 it is a simple dereference. */
2576 res = CreateDirectoryA(path, NULL);
2577 Py_END_ALLOW_THREADS
2578 if (!res) {
2579 win32_error("mkdir", path);
2580 PyMem_Free(path);
2581 return NULL;
2583 PyMem_Free(path);
2584 Py_INCREF(Py_None);
2585 return Py_None;
2586 #else /* MS_WINDOWS */
2588 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2589 Py_FileSystemDefaultEncoding, &path, &mode))
2590 return NULL;
2591 Py_BEGIN_ALLOW_THREADS
2592 #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
2593 res = mkdir(path);
2594 #else
2595 res = mkdir(path, mode);
2596 #endif
2597 Py_END_ALLOW_THREADS
2598 if (res < 0)
2599 return posix_error_with_allocated_filename(path);
2600 PyMem_Free(path);
2601 Py_INCREF(Py_None);
2602 return Py_None;
2603 #endif /* MS_WINDOWS */
2607 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2608 #if defined(HAVE_SYS_RESOURCE_H)
2609 #include <sys/resource.h>
2610 #endif
2613 #ifdef HAVE_NICE
2614 PyDoc_STRVAR(posix_nice__doc__,
2615 "nice(inc) -> new_priority\n\n\
2616 Decrease the priority of process by inc and return the new priority.");
2618 static PyObject *
2619 posix_nice(PyObject *self, PyObject *args)
2621 int increment, value;
2623 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2624 return NULL;
2626 /* There are two flavours of 'nice': one that returns the new
2627 priority (as required by almost all standards out there) and the
2628 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2629 the use of getpriority() to get the new priority.
2631 If we are of the nice family that returns the new priority, we
2632 need to clear errno before the call, and check if errno is filled
2633 before calling posix_error() on a returnvalue of -1, because the
2634 -1 may be the actual new priority! */
2636 errno = 0;
2637 value = nice(increment);
2638 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
2639 if (value == 0)
2640 value = getpriority(PRIO_PROCESS, 0);
2641 #endif
2642 if (value == -1 && errno != 0)
2643 /* either nice() or getpriority() returned an error */
2644 return posix_error();
2645 return PyInt_FromLong((long) value);
2647 #endif /* HAVE_NICE */
2649 PyDoc_STRVAR(posix_rename__doc__,
2650 "rename(old, new)\n\n\
2651 Rename a file or directory.");
2653 static PyObject *
2654 posix_rename(PyObject *self, PyObject *args)
2656 #ifdef MS_WINDOWS
2657 PyObject *o1, *o2;
2658 char *p1, *p2;
2659 BOOL result;
2660 if (unicode_file_names()) {
2661 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2662 goto error;
2663 if (!convert_to_unicode(&o1))
2664 goto error;
2665 if (!convert_to_unicode(&o2)) {
2666 Py_DECREF(o1);
2667 goto error;
2669 Py_BEGIN_ALLOW_THREADS
2670 result = MoveFileW(PyUnicode_AsUnicode(o1),
2671 PyUnicode_AsUnicode(o2));
2672 Py_END_ALLOW_THREADS
2673 Py_DECREF(o1);
2674 Py_DECREF(o2);
2675 if (!result)
2676 return win32_error("rename", NULL);
2677 Py_INCREF(Py_None);
2678 return Py_None;
2679 error:
2680 PyErr_Clear();
2682 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2683 return NULL;
2684 Py_BEGIN_ALLOW_THREADS
2685 result = MoveFileA(p1, p2);
2686 Py_END_ALLOW_THREADS
2687 if (!result)
2688 return win32_error("rename", NULL);
2689 Py_INCREF(Py_None);
2690 return Py_None;
2691 #else
2692 return posix_2str(args, "etet:rename", rename);
2693 #endif
2697 PyDoc_STRVAR(posix_rmdir__doc__,
2698 "rmdir(path)\n\n\
2699 Remove a directory.");
2701 static PyObject *
2702 posix_rmdir(PyObject *self, PyObject *args)
2704 #ifdef MS_WINDOWS
2705 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
2706 #else
2707 return posix_1str(args, "et:rmdir", rmdir);
2708 #endif
2712 PyDoc_STRVAR(posix_stat__doc__,
2713 "stat(path) -> stat result\n\n\
2714 Perform a stat system call on the given path.");
2716 static PyObject *
2717 posix_stat(PyObject *self, PyObject *args)
2719 #ifdef MS_WINDOWS
2720 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
2721 #else
2722 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2723 #endif
2727 #ifdef HAVE_SYSTEM
2728 PyDoc_STRVAR(posix_system__doc__,
2729 "system(command) -> exit_status\n\n\
2730 Execute the command (a string) in a subshell.");
2732 static PyObject *
2733 posix_system(PyObject *self, PyObject *args)
2735 char *command;
2736 long sts;
2737 if (!PyArg_ParseTuple(args, "s:system", &command))
2738 return NULL;
2739 Py_BEGIN_ALLOW_THREADS
2740 sts = system(command);
2741 Py_END_ALLOW_THREADS
2742 return PyInt_FromLong(sts);
2744 #endif
2747 PyDoc_STRVAR(posix_umask__doc__,
2748 "umask(new_mask) -> old_mask\n\n\
2749 Set the current numeric umask and return the previous umask.");
2751 static PyObject *
2752 posix_umask(PyObject *self, PyObject *args)
2754 int i;
2755 if (!PyArg_ParseTuple(args, "i:umask", &i))
2756 return NULL;
2757 i = (int)umask(i);
2758 if (i < 0)
2759 return posix_error();
2760 return PyInt_FromLong((long)i);
2764 PyDoc_STRVAR(posix_unlink__doc__,
2765 "unlink(path)\n\n\
2766 Remove a file (same as remove(path)).");
2768 PyDoc_STRVAR(posix_remove__doc__,
2769 "remove(path)\n\n\
2770 Remove a file (same as unlink(path)).");
2772 static PyObject *
2773 posix_unlink(PyObject *self, PyObject *args)
2775 #ifdef MS_WINDOWS
2776 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
2777 #else
2778 return posix_1str(args, "et:remove", unlink);
2779 #endif
2783 #ifdef HAVE_UNAME
2784 PyDoc_STRVAR(posix_uname__doc__,
2785 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2786 Return a tuple identifying the current operating system.");
2788 static PyObject *
2789 posix_uname(PyObject *self, PyObject *noargs)
2791 struct utsname u;
2792 int res;
2794 Py_BEGIN_ALLOW_THREADS
2795 res = uname(&u);
2796 Py_END_ALLOW_THREADS
2797 if (res < 0)
2798 return posix_error();
2799 return Py_BuildValue("(sssss)",
2800 u.sysname,
2801 u.nodename,
2802 u.release,
2803 u.version,
2804 u.machine);
2806 #endif /* HAVE_UNAME */
2808 static int
2809 extract_time(PyObject *t, long* sec, long* usec)
2811 long intval;
2812 if (PyFloat_Check(t)) {
2813 double tval = PyFloat_AsDouble(t);
2814 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
2815 if (!intobj)
2816 return -1;
2817 intval = PyInt_AsLong(intobj);
2818 Py_DECREF(intobj);
2819 if (intval == -1 && PyErr_Occurred())
2820 return -1;
2821 *sec = intval;
2822 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2823 if (*usec < 0)
2824 /* If rounding gave us a negative number,
2825 truncate. */
2826 *usec = 0;
2827 return 0;
2829 intval = PyInt_AsLong(t);
2830 if (intval == -1 && PyErr_Occurred())
2831 return -1;
2832 *sec = intval;
2833 *usec = 0;
2834 return 0;
2837 PyDoc_STRVAR(posix_utime__doc__,
2838 "utime(path, (atime, mtime))\n\
2839 utime(path, None)\n\n\
2840 Set the access and modified time of the file to the given values. If the\n\
2841 second form is used, set the access and modified times to the current time.");
2843 static PyObject *
2844 posix_utime(PyObject *self, PyObject *args)
2846 #ifdef MS_WINDOWS
2847 PyObject *arg;
2848 PyUnicodeObject *obwpath;
2849 wchar_t *wpath = NULL;
2850 char *apath = NULL;
2851 HANDLE hFile;
2852 long atimesec, mtimesec, ausec, musec;
2853 FILETIME atime, mtime;
2854 PyObject *result = NULL;
2856 if (unicode_file_names()) {
2857 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2858 wpath = PyUnicode_AS_UNICODE(obwpath);
2859 Py_BEGIN_ALLOW_THREADS
2860 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2861 NULL, OPEN_EXISTING,
2862 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2863 Py_END_ALLOW_THREADS
2864 if (hFile == INVALID_HANDLE_VALUE)
2865 return win32_error_unicode("utime", wpath);
2866 } else
2867 /* Drop the argument parsing error as narrow strings
2868 are also valid. */
2869 PyErr_Clear();
2871 if (!wpath) {
2872 if (!PyArg_ParseTuple(args, "etO:utime",
2873 Py_FileSystemDefaultEncoding, &apath, &arg))
2874 return NULL;
2875 Py_BEGIN_ALLOW_THREADS
2876 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2877 NULL, OPEN_EXISTING,
2878 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2879 Py_END_ALLOW_THREADS
2880 if (hFile == INVALID_HANDLE_VALUE) {
2881 win32_error("utime", apath);
2882 PyMem_Free(apath);
2883 return NULL;
2885 PyMem_Free(apath);
2888 if (arg == Py_None) {
2889 SYSTEMTIME now;
2890 GetSystemTime(&now);
2891 if (!SystemTimeToFileTime(&now, &mtime) ||
2892 !SystemTimeToFileTime(&now, &atime)) {
2893 win32_error("utime", NULL);
2894 goto done;
2897 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2898 PyErr_SetString(PyExc_TypeError,
2899 "utime() arg 2 must be a tuple (atime, mtime)");
2900 goto done;
2902 else {
2903 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2904 &atimesec, &ausec) == -1)
2905 goto done;
2906 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
2907 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2908 &mtimesec, &musec) == -1)
2909 goto done;
2910 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
2912 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2913 /* Avoid putting the file name into the error here,
2914 as that may confuse the user into believing that
2915 something is wrong with the file, when it also
2916 could be the time stamp that gives a problem. */
2917 win32_error("utime", NULL);
2919 Py_INCREF(Py_None);
2920 result = Py_None;
2921 done:
2922 CloseHandle(hFile);
2923 return result;
2924 #else /* MS_WINDOWS */
2926 char *path = NULL;
2927 long atime, mtime, ausec, musec;
2928 int res;
2929 PyObject* arg;
2931 #if defined(HAVE_UTIMES)
2932 struct timeval buf[2];
2933 #define ATIME buf[0].tv_sec
2934 #define MTIME buf[1].tv_sec
2935 #elif defined(HAVE_UTIME_H)
2936 /* XXX should define struct utimbuf instead, above */
2937 struct utimbuf buf;
2938 #define ATIME buf.actime
2939 #define MTIME buf.modtime
2940 #define UTIME_ARG &buf
2941 #else /* HAVE_UTIMES */
2942 time_t buf[2];
2943 #define ATIME buf[0]
2944 #define MTIME buf[1]
2945 #define UTIME_ARG buf
2946 #endif /* HAVE_UTIMES */
2949 if (!PyArg_ParseTuple(args, "etO:utime",
2950 Py_FileSystemDefaultEncoding, &path, &arg))
2951 return NULL;
2952 if (arg == Py_None) {
2953 /* optional time values not given */
2954 Py_BEGIN_ALLOW_THREADS
2955 res = utime(path, NULL);
2956 Py_END_ALLOW_THREADS
2958 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2959 PyErr_SetString(PyExc_TypeError,
2960 "utime() arg 2 must be a tuple (atime, mtime)");
2961 PyMem_Free(path);
2962 return NULL;
2964 else {
2965 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2966 &atime, &ausec) == -1) {
2967 PyMem_Free(path);
2968 return NULL;
2970 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2971 &mtime, &musec) == -1) {
2972 PyMem_Free(path);
2973 return NULL;
2975 ATIME = atime;
2976 MTIME = mtime;
2977 #ifdef HAVE_UTIMES
2978 buf[0].tv_usec = ausec;
2979 buf[1].tv_usec = musec;
2980 Py_BEGIN_ALLOW_THREADS
2981 res = utimes(path, buf);
2982 Py_END_ALLOW_THREADS
2983 #else
2984 Py_BEGIN_ALLOW_THREADS
2985 res = utime(path, UTIME_ARG);
2986 Py_END_ALLOW_THREADS
2987 #endif /* HAVE_UTIMES */
2989 if (res < 0) {
2990 return posix_error_with_allocated_filename(path);
2992 PyMem_Free(path);
2993 Py_INCREF(Py_None);
2994 return Py_None;
2995 #undef UTIME_ARG
2996 #undef ATIME
2997 #undef MTIME
2998 #endif /* MS_WINDOWS */
3002 /* Process operations */
3004 PyDoc_STRVAR(posix__exit__doc__,
3005 "_exit(status)\n\n\
3006 Exit to the system with specified status, without normal exit processing.");
3008 static PyObject *
3009 posix__exit(PyObject *self, PyObject *args)
3011 int sts;
3012 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3013 return NULL;
3014 _exit(sts);
3015 return NULL; /* Make gcc -Wall happy */
3018 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3019 static void
3020 free_string_array(char **array, Py_ssize_t count)
3022 Py_ssize_t i;
3023 for (i = 0; i < count; i++)
3024 PyMem_Free(array[i]);
3025 PyMem_DEL(array);
3027 #endif
3030 #ifdef HAVE_EXECV
3031 PyDoc_STRVAR(posix_execv__doc__,
3032 "execv(path, args)\n\n\
3033 Execute an executable path with arguments, replacing current process.\n\
3035 path: path of executable file\n\
3036 args: tuple or list of strings");
3038 static PyObject *
3039 posix_execv(PyObject *self, PyObject *args)
3041 char *path;
3042 PyObject *argv;
3043 char **argvlist;
3044 Py_ssize_t i, argc;
3045 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3047 /* execv has two arguments: (path, argv), where
3048 argv is a list or tuple of strings. */
3050 if (!PyArg_ParseTuple(args, "etO:execv",
3051 Py_FileSystemDefaultEncoding,
3052 &path, &argv))
3053 return NULL;
3054 if (PyList_Check(argv)) {
3055 argc = PyList_Size(argv);
3056 getitem = PyList_GetItem;
3058 else if (PyTuple_Check(argv)) {
3059 argc = PyTuple_Size(argv);
3060 getitem = PyTuple_GetItem;
3062 else {
3063 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3064 PyMem_Free(path);
3065 return NULL;
3068 argvlist = PyMem_NEW(char *, argc+1);
3069 if (argvlist == NULL) {
3070 PyMem_Free(path);
3071 return PyErr_NoMemory();
3073 for (i = 0; i < argc; i++) {
3074 if (!PyArg_Parse((*getitem)(argv, i), "et",
3075 Py_FileSystemDefaultEncoding,
3076 &argvlist[i])) {
3077 free_string_array(argvlist, i);
3078 PyErr_SetString(PyExc_TypeError,
3079 "execv() arg 2 must contain only strings");
3080 PyMem_Free(path);
3081 return NULL;
3085 argvlist[argc] = NULL;
3087 execv(path, argvlist);
3089 /* If we get here it's definitely an error */
3091 free_string_array(argvlist, argc);
3092 PyMem_Free(path);
3093 return posix_error();
3097 PyDoc_STRVAR(posix_execve__doc__,
3098 "execve(path, args, env)\n\n\
3099 Execute a path with arguments and environment, replacing current process.\n\
3101 path: path of executable file\n\
3102 args: tuple or list of arguments\n\
3103 env: dictionary of strings mapping to strings");
3105 static PyObject *
3106 posix_execve(PyObject *self, PyObject *args)
3108 char *path;
3109 PyObject *argv, *env;
3110 char **argvlist;
3111 char **envlist;
3112 PyObject *key, *val, *keys=NULL, *vals=NULL;
3113 Py_ssize_t i, pos, argc, envc;
3114 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3115 Py_ssize_t lastarg = 0;
3117 /* execve has three arguments: (path, argv, env), where
3118 argv is a list or tuple of strings and env is a dictionary
3119 like posix.environ. */
3121 if (!PyArg_ParseTuple(args, "etOO:execve",
3122 Py_FileSystemDefaultEncoding,
3123 &path, &argv, &env))
3124 return NULL;
3125 if (PyList_Check(argv)) {
3126 argc = PyList_Size(argv);
3127 getitem = PyList_GetItem;
3129 else if (PyTuple_Check(argv)) {
3130 argc = PyTuple_Size(argv);
3131 getitem = PyTuple_GetItem;
3133 else {
3134 PyErr_SetString(PyExc_TypeError,
3135 "execve() arg 2 must be a tuple or list");
3136 goto fail_0;
3138 if (!PyMapping_Check(env)) {
3139 PyErr_SetString(PyExc_TypeError,
3140 "execve() arg 3 must be a mapping object");
3141 goto fail_0;
3144 argvlist = PyMem_NEW(char *, argc+1);
3145 if (argvlist == NULL) {
3146 PyErr_NoMemory();
3147 goto fail_0;
3149 for (i = 0; i < argc; i++) {
3150 if (!PyArg_Parse((*getitem)(argv, i),
3151 "et;execve() arg 2 must contain only strings",
3152 Py_FileSystemDefaultEncoding,
3153 &argvlist[i]))
3155 lastarg = i;
3156 goto fail_1;
3159 lastarg = argc;
3160 argvlist[argc] = NULL;
3162 i = PyMapping_Size(env);
3163 if (i < 0)
3164 goto fail_1;
3165 envlist = PyMem_NEW(char *, i + 1);
3166 if (envlist == NULL) {
3167 PyErr_NoMemory();
3168 goto fail_1;
3170 envc = 0;
3171 keys = PyMapping_Keys(env);
3172 vals = PyMapping_Values(env);
3173 if (!keys || !vals)
3174 goto fail_2;
3175 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3176 PyErr_SetString(PyExc_TypeError,
3177 "execve(): env.keys() or env.values() is not a list");
3178 goto fail_2;
3181 for (pos = 0; pos < i; pos++) {
3182 char *p, *k, *v;
3183 size_t len;
3185 key = PyList_GetItem(keys, pos);
3186 val = PyList_GetItem(vals, pos);
3187 if (!key || !val)
3188 goto fail_2;
3190 if (!PyArg_Parse(
3191 key,
3192 "s;execve() arg 3 contains a non-string key",
3193 &k) ||
3194 !PyArg_Parse(
3195 val,
3196 "s;execve() arg 3 contains a non-string value",
3197 &v))
3199 goto fail_2;
3202 #if defined(PYOS_OS2)
3203 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3204 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3205 #endif
3206 len = PyString_Size(key) + PyString_Size(val) + 2;
3207 p = PyMem_NEW(char, len);
3208 if (p == NULL) {
3209 PyErr_NoMemory();
3210 goto fail_2;
3212 PyOS_snprintf(p, len, "%s=%s", k, v);
3213 envlist[envc++] = p;
3214 #if defined(PYOS_OS2)
3216 #endif
3218 envlist[envc] = 0;
3220 execve(path, argvlist, envlist);
3222 /* If we get here it's definitely an error */
3224 (void) posix_error();
3226 fail_2:
3227 while (--envc >= 0)
3228 PyMem_DEL(envlist[envc]);
3229 PyMem_DEL(envlist);
3230 fail_1:
3231 free_string_array(argvlist, lastarg);
3232 Py_XDECREF(vals);
3233 Py_XDECREF(keys);
3234 fail_0:
3235 PyMem_Free(path);
3236 return NULL;
3238 #endif /* HAVE_EXECV */
3241 #ifdef HAVE_SPAWNV
3242 PyDoc_STRVAR(posix_spawnv__doc__,
3243 "spawnv(mode, path, args)\n\n\
3244 Execute the program 'path' in a new process.\n\
3246 mode: mode of process creation\n\
3247 path: path of executable file\n\
3248 args: tuple or list of strings");
3250 static PyObject *
3251 posix_spawnv(PyObject *self, PyObject *args)
3253 char *path;
3254 PyObject *argv;
3255 char **argvlist;
3256 int mode, i;
3257 Py_ssize_t argc;
3258 Py_intptr_t spawnval;
3259 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3261 /* spawnv has three arguments: (mode, path, argv), where
3262 argv is a list or tuple of strings. */
3264 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3265 Py_FileSystemDefaultEncoding,
3266 &path, &argv))
3267 return NULL;
3268 if (PyList_Check(argv)) {
3269 argc = PyList_Size(argv);
3270 getitem = PyList_GetItem;
3272 else if (PyTuple_Check(argv)) {
3273 argc = PyTuple_Size(argv);
3274 getitem = PyTuple_GetItem;
3276 else {
3277 PyErr_SetString(PyExc_TypeError,
3278 "spawnv() arg 2 must be a tuple or list");
3279 PyMem_Free(path);
3280 return NULL;
3283 argvlist = PyMem_NEW(char *, argc+1);
3284 if (argvlist == NULL) {
3285 PyMem_Free(path);
3286 return PyErr_NoMemory();
3288 for (i = 0; i < argc; i++) {
3289 if (!PyArg_Parse((*getitem)(argv, i), "et",
3290 Py_FileSystemDefaultEncoding,
3291 &argvlist[i])) {
3292 free_string_array(argvlist, i);
3293 PyErr_SetString(
3294 PyExc_TypeError,
3295 "spawnv() arg 2 must contain only strings");
3296 PyMem_Free(path);
3297 return NULL;
3300 argvlist[argc] = NULL;
3302 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3303 Py_BEGIN_ALLOW_THREADS
3304 spawnval = spawnv(mode, path, argvlist);
3305 Py_END_ALLOW_THREADS
3306 #else
3307 if (mode == _OLD_P_OVERLAY)
3308 mode = _P_OVERLAY;
3310 Py_BEGIN_ALLOW_THREADS
3311 spawnval = _spawnv(mode, path, argvlist);
3312 Py_END_ALLOW_THREADS
3313 #endif
3315 free_string_array(argvlist, argc);
3316 PyMem_Free(path);
3318 if (spawnval == -1)
3319 return posix_error();
3320 else
3321 #if SIZEOF_LONG == SIZEOF_VOID_P
3322 return Py_BuildValue("l", (long) spawnval);
3323 #else
3324 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3325 #endif
3329 PyDoc_STRVAR(posix_spawnve__doc__,
3330 "spawnve(mode, path, args, env)\n\n\
3331 Execute the program 'path' in a new process.\n\
3333 mode: mode of process creation\n\
3334 path: path of executable file\n\
3335 args: tuple or list of arguments\n\
3336 env: dictionary of strings mapping to strings");
3338 static PyObject *
3339 posix_spawnve(PyObject *self, PyObject *args)
3341 char *path;
3342 PyObject *argv, *env;
3343 char **argvlist;
3344 char **envlist;
3345 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3346 int mode, pos, envc;
3347 Py_ssize_t argc, i;
3348 Py_intptr_t spawnval;
3349 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3350 Py_ssize_t lastarg = 0;
3352 /* spawnve has four arguments: (mode, path, argv, env), where
3353 argv is a list or tuple of strings and env is a dictionary
3354 like posix.environ. */
3356 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3357 Py_FileSystemDefaultEncoding,
3358 &path, &argv, &env))
3359 return NULL;
3360 if (PyList_Check(argv)) {
3361 argc = PyList_Size(argv);
3362 getitem = PyList_GetItem;
3364 else if (PyTuple_Check(argv)) {
3365 argc = PyTuple_Size(argv);
3366 getitem = PyTuple_GetItem;
3368 else {
3369 PyErr_SetString(PyExc_TypeError,
3370 "spawnve() arg 2 must be a tuple or list");
3371 goto fail_0;
3373 if (!PyMapping_Check(env)) {
3374 PyErr_SetString(PyExc_TypeError,
3375 "spawnve() arg 3 must be a mapping object");
3376 goto fail_0;
3379 argvlist = PyMem_NEW(char *, argc+1);
3380 if (argvlist == NULL) {
3381 PyErr_NoMemory();
3382 goto fail_0;
3384 for (i = 0; i < argc; i++) {
3385 if (!PyArg_Parse((*getitem)(argv, i),
3386 "et;spawnve() arg 2 must contain only strings",
3387 Py_FileSystemDefaultEncoding,
3388 &argvlist[i]))
3390 lastarg = i;
3391 goto fail_1;
3394 lastarg = argc;
3395 argvlist[argc] = NULL;
3397 i = PyMapping_Size(env);
3398 if (i < 0)
3399 goto fail_1;
3400 envlist = PyMem_NEW(char *, i + 1);
3401 if (envlist == NULL) {
3402 PyErr_NoMemory();
3403 goto fail_1;
3405 envc = 0;
3406 keys = PyMapping_Keys(env);
3407 vals = PyMapping_Values(env);
3408 if (!keys || !vals)
3409 goto fail_2;
3410 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3411 PyErr_SetString(PyExc_TypeError,
3412 "spawnve(): env.keys() or env.values() is not a list");
3413 goto fail_2;
3416 for (pos = 0; pos < i; pos++) {
3417 char *p, *k, *v;
3418 size_t len;
3420 key = PyList_GetItem(keys, pos);
3421 val = PyList_GetItem(vals, pos);
3422 if (!key || !val)
3423 goto fail_2;
3425 if (!PyArg_Parse(
3426 key,
3427 "s;spawnve() arg 3 contains a non-string key",
3428 &k) ||
3429 !PyArg_Parse(
3430 val,
3431 "s;spawnve() arg 3 contains a non-string value",
3432 &v))
3434 goto fail_2;
3436 len = PyString_Size(key) + PyString_Size(val) + 2;
3437 p = PyMem_NEW(char, len);
3438 if (p == NULL) {
3439 PyErr_NoMemory();
3440 goto fail_2;
3442 PyOS_snprintf(p, len, "%s=%s", k, v);
3443 envlist[envc++] = p;
3445 envlist[envc] = 0;
3447 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3448 Py_BEGIN_ALLOW_THREADS
3449 spawnval = spawnve(mode, path, argvlist, envlist);
3450 Py_END_ALLOW_THREADS
3451 #else
3452 if (mode == _OLD_P_OVERLAY)
3453 mode = _P_OVERLAY;
3455 Py_BEGIN_ALLOW_THREADS
3456 spawnval = _spawnve(mode, path, argvlist, envlist);
3457 Py_END_ALLOW_THREADS
3458 #endif
3460 if (spawnval == -1)
3461 (void) posix_error();
3462 else
3463 #if SIZEOF_LONG == SIZEOF_VOID_P
3464 res = Py_BuildValue("l", (long) spawnval);
3465 #else
3466 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3467 #endif
3469 fail_2:
3470 while (--envc >= 0)
3471 PyMem_DEL(envlist[envc]);
3472 PyMem_DEL(envlist);
3473 fail_1:
3474 free_string_array(argvlist, lastarg);
3475 Py_XDECREF(vals);
3476 Py_XDECREF(keys);
3477 fail_0:
3478 PyMem_Free(path);
3479 return res;
3482 /* OS/2 supports spawnvp & spawnvpe natively */
3483 #if defined(PYOS_OS2)
3484 PyDoc_STRVAR(posix_spawnvp__doc__,
3485 "spawnvp(mode, file, args)\n\n\
3486 Execute the program 'file' in a new process, using the environment\n\
3487 search path to find the file.\n\
3489 mode: mode of process creation\n\
3490 file: executable file name\n\
3491 args: tuple or list of strings");
3493 static PyObject *
3494 posix_spawnvp(PyObject *self, PyObject *args)
3496 char *path;
3497 PyObject *argv;
3498 char **argvlist;
3499 int mode, i, argc;
3500 Py_intptr_t spawnval;
3501 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3503 /* spawnvp has three arguments: (mode, path, argv), where
3504 argv is a list or tuple of strings. */
3506 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3507 Py_FileSystemDefaultEncoding,
3508 &path, &argv))
3509 return NULL;
3510 if (PyList_Check(argv)) {
3511 argc = PyList_Size(argv);
3512 getitem = PyList_GetItem;
3514 else if (PyTuple_Check(argv)) {
3515 argc = PyTuple_Size(argv);
3516 getitem = PyTuple_GetItem;
3518 else {
3519 PyErr_SetString(PyExc_TypeError,
3520 "spawnvp() arg 2 must be a tuple or list");
3521 PyMem_Free(path);
3522 return NULL;
3525 argvlist = PyMem_NEW(char *, argc+1);
3526 if (argvlist == NULL) {
3527 PyMem_Free(path);
3528 return PyErr_NoMemory();
3530 for (i = 0; i < argc; i++) {
3531 if (!PyArg_Parse((*getitem)(argv, i), "et",
3532 Py_FileSystemDefaultEncoding,
3533 &argvlist[i])) {
3534 free_string_array(argvlist, i);
3535 PyErr_SetString(
3536 PyExc_TypeError,
3537 "spawnvp() arg 2 must contain only strings");
3538 PyMem_Free(path);
3539 return NULL;
3542 argvlist[argc] = NULL;
3544 Py_BEGIN_ALLOW_THREADS
3545 #if defined(PYCC_GCC)
3546 spawnval = spawnvp(mode, path, argvlist);
3547 #else
3548 spawnval = _spawnvp(mode, path, argvlist);
3549 #endif
3550 Py_END_ALLOW_THREADS
3552 free_string_array(argvlist, argc);
3553 PyMem_Free(path);
3555 if (spawnval == -1)
3556 return posix_error();
3557 else
3558 return Py_BuildValue("l", (long) spawnval);
3562 PyDoc_STRVAR(posix_spawnvpe__doc__,
3563 "spawnvpe(mode, file, args, env)\n\n\
3564 Execute the program 'file' in a new process, using the environment\n\
3565 search path to find the file.\n\
3567 mode: mode of process creation\n\
3568 file: executable file name\n\
3569 args: tuple or list of arguments\n\
3570 env: dictionary of strings mapping to strings");
3572 static PyObject *
3573 posix_spawnvpe(PyObject *self, PyObject *args)
3575 char *path;
3576 PyObject *argv, *env;
3577 char **argvlist;
3578 char **envlist;
3579 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3580 int mode, i, pos, argc, envc;
3581 Py_intptr_t spawnval;
3582 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3583 int lastarg = 0;
3585 /* spawnvpe has four arguments: (mode, path, argv, env), where
3586 argv is a list or tuple of strings and env is a dictionary
3587 like posix.environ. */
3589 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3590 Py_FileSystemDefaultEncoding,
3591 &path, &argv, &env))
3592 return NULL;
3593 if (PyList_Check(argv)) {
3594 argc = PyList_Size(argv);
3595 getitem = PyList_GetItem;
3597 else if (PyTuple_Check(argv)) {
3598 argc = PyTuple_Size(argv);
3599 getitem = PyTuple_GetItem;
3601 else {
3602 PyErr_SetString(PyExc_TypeError,
3603 "spawnvpe() arg 2 must be a tuple or list");
3604 goto fail_0;
3606 if (!PyMapping_Check(env)) {
3607 PyErr_SetString(PyExc_TypeError,
3608 "spawnvpe() arg 3 must be a mapping object");
3609 goto fail_0;
3612 argvlist = PyMem_NEW(char *, argc+1);
3613 if (argvlist == NULL) {
3614 PyErr_NoMemory();
3615 goto fail_0;
3617 for (i = 0; i < argc; i++) {
3618 if (!PyArg_Parse((*getitem)(argv, i),
3619 "et;spawnvpe() arg 2 must contain only strings",
3620 Py_FileSystemDefaultEncoding,
3621 &argvlist[i]))
3623 lastarg = i;
3624 goto fail_1;
3627 lastarg = argc;
3628 argvlist[argc] = NULL;
3630 i = PyMapping_Size(env);
3631 if (i < 0)
3632 goto fail_1;
3633 envlist = PyMem_NEW(char *, i + 1);
3634 if (envlist == NULL) {
3635 PyErr_NoMemory();
3636 goto fail_1;
3638 envc = 0;
3639 keys = PyMapping_Keys(env);
3640 vals = PyMapping_Values(env);
3641 if (!keys || !vals)
3642 goto fail_2;
3643 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3644 PyErr_SetString(PyExc_TypeError,
3645 "spawnvpe(): env.keys() or env.values() is not a list");
3646 goto fail_2;
3649 for (pos = 0; pos < i; pos++) {
3650 char *p, *k, *v;
3651 size_t len;
3653 key = PyList_GetItem(keys, pos);
3654 val = PyList_GetItem(vals, pos);
3655 if (!key || !val)
3656 goto fail_2;
3658 if (!PyArg_Parse(
3659 key,
3660 "s;spawnvpe() arg 3 contains a non-string key",
3661 &k) ||
3662 !PyArg_Parse(
3663 val,
3664 "s;spawnvpe() arg 3 contains a non-string value",
3665 &v))
3667 goto fail_2;
3669 len = PyString_Size(key) + PyString_Size(val) + 2;
3670 p = PyMem_NEW(char, len);
3671 if (p == NULL) {
3672 PyErr_NoMemory();
3673 goto fail_2;
3675 PyOS_snprintf(p, len, "%s=%s", k, v);
3676 envlist[envc++] = p;
3678 envlist[envc] = 0;
3680 Py_BEGIN_ALLOW_THREADS
3681 #if defined(PYCC_GCC)
3682 spawnval = spawnvpe(mode, path, argvlist, envlist);
3683 #else
3684 spawnval = _spawnvpe(mode, path, argvlist, envlist);
3685 #endif
3686 Py_END_ALLOW_THREADS
3688 if (spawnval == -1)
3689 (void) posix_error();
3690 else
3691 res = Py_BuildValue("l", (long) spawnval);
3693 fail_2:
3694 while (--envc >= 0)
3695 PyMem_DEL(envlist[envc]);
3696 PyMem_DEL(envlist);
3697 fail_1:
3698 free_string_array(argvlist, lastarg);
3699 Py_XDECREF(vals);
3700 Py_XDECREF(keys);
3701 fail_0:
3702 PyMem_Free(path);
3703 return res;
3705 #endif /* PYOS_OS2 */
3706 #endif /* HAVE_SPAWNV */
3709 #ifdef HAVE_FORK1
3710 PyDoc_STRVAR(posix_fork1__doc__,
3711 "fork1() -> pid\n\n\
3712 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3714 Return 0 to child process and PID of child to parent process.");
3716 static PyObject *
3717 posix_fork1(PyObject *self, PyObject *noargs)
3719 pid_t pid = fork1();
3720 if (pid == -1)
3721 return posix_error();
3722 if (pid == 0)
3723 PyOS_AfterFork();
3724 return PyLong_FromPid(pid);
3726 #endif
3729 #ifdef HAVE_FORK
3730 PyDoc_STRVAR(posix_fork__doc__,
3731 "fork() -> pid\n\n\
3732 Fork a child process.\n\
3733 Return 0 to child process and PID of child to parent process.");
3735 static PyObject *
3736 posix_fork(PyObject *self, PyObject *noargs)
3738 pid_t pid = fork();
3739 if (pid == -1)
3740 return posix_error();
3741 if (pid == 0)
3742 PyOS_AfterFork();
3743 return PyLong_FromPid(pid);
3745 #endif
3747 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
3748 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3749 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
3750 #define DEV_PTY_FILE "/dev/ptc"
3751 #define HAVE_DEV_PTMX
3752 #else
3753 #define DEV_PTY_FILE "/dev/ptmx"
3754 #endif
3756 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
3757 #ifdef HAVE_PTY_H
3758 #include <pty.h>
3759 #else
3760 #ifdef HAVE_LIBUTIL_H
3761 #include <libutil.h>
3762 #endif /* HAVE_LIBUTIL_H */
3763 #endif /* HAVE_PTY_H */
3764 #ifdef HAVE_STROPTS_H
3765 #include <stropts.h>
3766 #endif
3767 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
3769 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3770 PyDoc_STRVAR(posix_openpty__doc__,
3771 "openpty() -> (master_fd, slave_fd)\n\n\
3772 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
3774 static PyObject *
3775 posix_openpty(PyObject *self, PyObject *noargs)
3777 int master_fd, slave_fd;
3778 #ifndef HAVE_OPENPTY
3779 char * slave_name;
3780 #endif
3781 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
3782 PyOS_sighandler_t sig_saved;
3783 #ifdef sun
3784 extern char *ptsname(int fildes);
3785 #endif
3786 #endif
3788 #ifdef HAVE_OPENPTY
3789 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3790 return posix_error();
3791 #elif defined(HAVE__GETPTY)
3792 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3793 if (slave_name == NULL)
3794 return posix_error();
3796 slave_fd = open(slave_name, O_RDWR);
3797 if (slave_fd < 0)
3798 return posix_error();
3799 #else
3800 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3801 if (master_fd < 0)
3802 return posix_error();
3803 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3804 /* change permission of slave */
3805 if (grantpt(master_fd) < 0) {
3806 PyOS_setsig(SIGCHLD, sig_saved);
3807 return posix_error();
3809 /* unlock slave */
3810 if (unlockpt(master_fd) < 0) {
3811 PyOS_setsig(SIGCHLD, sig_saved);
3812 return posix_error();
3814 PyOS_setsig(SIGCHLD, sig_saved);
3815 slave_name = ptsname(master_fd); /* get name of slave */
3816 if (slave_name == NULL)
3817 return posix_error();
3818 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3819 if (slave_fd < 0)
3820 return posix_error();
3821 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
3822 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3823 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
3824 #ifndef __hpux
3825 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
3826 #endif /* __hpux */
3827 #endif /* HAVE_CYGWIN */
3828 #endif /* HAVE_OPENPTY */
3830 return Py_BuildValue("(ii)", master_fd, slave_fd);
3833 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3835 #ifdef HAVE_FORKPTY
3836 PyDoc_STRVAR(posix_forkpty__doc__,
3837 "forkpty() -> (pid, master_fd)\n\n\
3838 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3839 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3840 To both, return fd of newly opened pseudo-terminal.\n");
3842 static PyObject *
3843 posix_forkpty(PyObject *self, PyObject *noargs)
3845 int master_fd = -1;
3846 pid_t pid;
3848 pid = forkpty(&master_fd, NULL, NULL, NULL);
3849 if (pid == -1)
3850 return posix_error();
3851 if (pid == 0)
3852 PyOS_AfterFork();
3853 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
3855 #endif
3857 #ifdef HAVE_GETEGID
3858 PyDoc_STRVAR(posix_getegid__doc__,
3859 "getegid() -> egid\n\n\
3860 Return the current process's effective group id.");
3862 static PyObject *
3863 posix_getegid(PyObject *self, PyObject *noargs)
3865 return PyInt_FromLong((long)getegid());
3867 #endif
3870 #ifdef HAVE_GETEUID
3871 PyDoc_STRVAR(posix_geteuid__doc__,
3872 "geteuid() -> euid\n\n\
3873 Return the current process's effective user id.");
3875 static PyObject *
3876 posix_geteuid(PyObject *self, PyObject *noargs)
3878 return PyInt_FromLong((long)geteuid());
3880 #endif
3883 #ifdef HAVE_GETGID
3884 PyDoc_STRVAR(posix_getgid__doc__,
3885 "getgid() -> gid\n\n\
3886 Return the current process's group id.");
3888 static PyObject *
3889 posix_getgid(PyObject *self, PyObject *noargs)
3891 return PyInt_FromLong((long)getgid());
3893 #endif
3896 PyDoc_STRVAR(posix_getpid__doc__,
3897 "getpid() -> pid\n\n\
3898 Return the current process id");
3900 static PyObject *
3901 posix_getpid(PyObject *self, PyObject *noargs)
3903 return PyLong_FromPid(getpid());
3907 #ifdef HAVE_GETGROUPS
3908 PyDoc_STRVAR(posix_getgroups__doc__,
3909 "getgroups() -> list of group IDs\n\n\
3910 Return list of supplemental group IDs for the process.");
3912 static PyObject *
3913 posix_getgroups(PyObject *self, PyObject *noargs)
3915 PyObject *result = NULL;
3917 #ifdef NGROUPS_MAX
3918 #define MAX_GROUPS NGROUPS_MAX
3919 #else
3920 /* defined to be 16 on Solaris7, so this should be a small number */
3921 #define MAX_GROUPS 64
3922 #endif
3923 gid_t grouplist[MAX_GROUPS];
3924 int n;
3926 n = getgroups(MAX_GROUPS, grouplist);
3927 if (n < 0)
3928 posix_error();
3929 else {
3930 result = PyList_New(n);
3931 if (result != NULL) {
3932 int i;
3933 for (i = 0; i < n; ++i) {
3934 PyObject *o = PyInt_FromLong((long)grouplist[i]);
3935 if (o == NULL) {
3936 Py_DECREF(result);
3937 result = NULL;
3938 break;
3940 PyList_SET_ITEM(result, i, o);
3945 return result;
3947 #endif
3949 #ifdef HAVE_GETPGID
3950 PyDoc_STRVAR(posix_getpgid__doc__,
3951 "getpgid(pid) -> pgid\n\n\
3952 Call the system call getpgid().");
3954 static PyObject *
3955 posix_getpgid(PyObject *self, PyObject *args)
3957 pid_t pid, pgid;
3958 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
3959 return NULL;
3960 pgid = getpgid(pid);
3961 if (pgid < 0)
3962 return posix_error();
3963 return PyLong_FromPid(pgid);
3965 #endif /* HAVE_GETPGID */
3968 #ifdef HAVE_GETPGRP
3969 PyDoc_STRVAR(posix_getpgrp__doc__,
3970 "getpgrp() -> pgrp\n\n\
3971 Return the current process group id.");
3973 static PyObject *
3974 posix_getpgrp(PyObject *self, PyObject *noargs)
3976 #ifdef GETPGRP_HAVE_ARG
3977 return PyLong_FromPid(getpgrp(0));
3978 #else /* GETPGRP_HAVE_ARG */
3979 return PyLong_FromPid(getpgrp());
3980 #endif /* GETPGRP_HAVE_ARG */
3982 #endif /* HAVE_GETPGRP */
3985 #ifdef HAVE_SETPGRP
3986 PyDoc_STRVAR(posix_setpgrp__doc__,
3987 "setpgrp()\n\n\
3988 Make this process a session leader.");
3990 static PyObject *
3991 posix_setpgrp(PyObject *self, PyObject *noargs)
3993 #ifdef SETPGRP_HAVE_ARG
3994 if (setpgrp(0, 0) < 0)
3995 #else /* SETPGRP_HAVE_ARG */
3996 if (setpgrp() < 0)
3997 #endif /* SETPGRP_HAVE_ARG */
3998 return posix_error();
3999 Py_INCREF(Py_None);
4000 return Py_None;
4003 #endif /* HAVE_SETPGRP */
4005 #ifdef HAVE_GETPPID
4006 PyDoc_STRVAR(posix_getppid__doc__,
4007 "getppid() -> ppid\n\n\
4008 Return the parent's process id.");
4010 static PyObject *
4011 posix_getppid(PyObject *self, PyObject *noargs)
4013 return PyLong_FromPid(getppid());
4015 #endif
4018 #ifdef HAVE_GETLOGIN
4019 PyDoc_STRVAR(posix_getlogin__doc__,
4020 "getlogin() -> string\n\n\
4021 Return the actual login name.");
4023 static PyObject *
4024 posix_getlogin(PyObject *self, PyObject *noargs)
4026 PyObject *result = NULL;
4027 char *name;
4028 int old_errno = errno;
4030 errno = 0;
4031 name = getlogin();
4032 if (name == NULL) {
4033 if (errno)
4034 posix_error();
4035 else
4036 PyErr_SetString(PyExc_OSError,
4037 "unable to determine login name");
4039 else
4040 result = PyString_FromString(name);
4041 errno = old_errno;
4043 return result;
4045 #endif
4047 #ifdef HAVE_GETUID
4048 PyDoc_STRVAR(posix_getuid__doc__,
4049 "getuid() -> uid\n\n\
4050 Return the current process's user id.");
4052 static PyObject *
4053 posix_getuid(PyObject *self, PyObject *noargs)
4055 return PyInt_FromLong((long)getuid());
4057 #endif
4060 #ifdef HAVE_KILL
4061 PyDoc_STRVAR(posix_kill__doc__,
4062 "kill(pid, sig)\n\n\
4063 Kill a process with a signal.");
4065 static PyObject *
4066 posix_kill(PyObject *self, PyObject *args)
4068 pid_t pid;
4069 int sig;
4070 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4071 return NULL;
4072 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
4073 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4074 APIRET rc;
4075 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
4076 return os2_error(rc);
4078 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4079 APIRET rc;
4080 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
4081 return os2_error(rc);
4083 } else
4084 return NULL; /* Unrecognized Signal Requested */
4085 #else
4086 if (kill(pid, sig) == -1)
4087 return posix_error();
4088 #endif
4089 Py_INCREF(Py_None);
4090 return Py_None;
4092 #endif
4094 #ifdef HAVE_KILLPG
4095 PyDoc_STRVAR(posix_killpg__doc__,
4096 "killpg(pgid, sig)\n\n\
4097 Kill a process group with a signal.");
4099 static PyObject *
4100 posix_killpg(PyObject *self, PyObject *args)
4102 int sig;
4103 pid_t pgid;
4104 /* XXX some man pages make the `pgid` parameter an int, others
4105 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4106 take the same type. Moreover, pid_t is always at least as wide as
4107 int (else compilation of this module fails), which is safe. */
4108 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4109 return NULL;
4110 if (killpg(pgid, sig) == -1)
4111 return posix_error();
4112 Py_INCREF(Py_None);
4113 return Py_None;
4115 #endif
4117 #ifdef HAVE_PLOCK
4119 #ifdef HAVE_SYS_LOCK_H
4120 #include <sys/lock.h>
4121 #endif
4123 PyDoc_STRVAR(posix_plock__doc__,
4124 "plock(op)\n\n\
4125 Lock program segments into memory.");
4127 static PyObject *
4128 posix_plock(PyObject *self, PyObject *args)
4130 int op;
4131 if (!PyArg_ParseTuple(args, "i:plock", &op))
4132 return NULL;
4133 if (plock(op) == -1)
4134 return posix_error();
4135 Py_INCREF(Py_None);
4136 return Py_None;
4138 #endif
4141 #ifdef HAVE_POPEN
4142 PyDoc_STRVAR(posix_popen__doc__,
4143 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
4144 Open a pipe to/from a command returning a file object.");
4146 #if defined(PYOS_OS2)
4147 #if defined(PYCC_VACPP)
4148 static int
4149 async_system(const char *command)
4151 char errormsg[256], args[1024];
4152 RESULTCODES rcodes;
4153 APIRET rc;
4155 char *shell = getenv("COMSPEC");
4156 if (!shell)
4157 shell = "cmd";
4159 /* avoid overflowing the argument buffer */
4160 if (strlen(shell) + 3 + strlen(command) >= 1024)
4161 return ERROR_NOT_ENOUGH_MEMORY
4163 args[0] = '\0';
4164 strcat(args, shell);
4165 strcat(args, "/c ");
4166 strcat(args, command);
4168 /* execute asynchronously, inheriting the environment */
4169 rc = DosExecPgm(errormsg,
4170 sizeof(errormsg),
4171 EXEC_ASYNC,
4172 args,
4173 NULL,
4174 &rcodes,
4175 shell);
4176 return rc;
4179 static FILE *
4180 popen(const char *command, const char *mode, int pipesize, int *err)
4182 int oldfd, tgtfd;
4183 HFILE pipeh[2];
4184 APIRET rc;
4186 /* mode determines which of stdin or stdout is reconnected to
4187 * the pipe to the child
4189 if (strchr(mode, 'r') != NULL) {
4190 tgt_fd = 1; /* stdout */
4191 } else if (strchr(mode, 'w')) {
4192 tgt_fd = 0; /* stdin */
4193 } else {
4194 *err = ERROR_INVALID_ACCESS;
4195 return NULL;
4198 /* setup the pipe */
4199 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4200 *err = rc;
4201 return NULL;
4204 /* prevent other threads accessing stdio */
4205 DosEnterCritSec();
4207 /* reconnect stdio and execute child */
4208 oldfd = dup(tgtfd);
4209 close(tgtfd);
4210 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4211 DosClose(pipeh[tgtfd]);
4212 rc = async_system(command);
4215 /* restore stdio */
4216 dup2(oldfd, tgtfd);
4217 close(oldfd);
4219 /* allow other threads access to stdio */
4220 DosExitCritSec();
4222 /* if execution of child was successful return file stream */
4223 if (rc == NO_ERROR)
4224 return fdopen(pipeh[1 - tgtfd], mode);
4225 else {
4226 DosClose(pipeh[1 - tgtfd]);
4227 *err = rc;
4228 return NULL;
4232 static PyObject *
4233 posix_popen(PyObject *self, PyObject *args)
4235 char *name;
4236 char *mode = "r";
4237 int err, bufsize = -1;
4238 FILE *fp;
4239 PyObject *f;
4240 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4241 return NULL;
4242 Py_BEGIN_ALLOW_THREADS
4243 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4244 Py_END_ALLOW_THREADS
4245 if (fp == NULL)
4246 return os2_error(err);
4248 f = PyFile_FromFile(fp, name, mode, fclose);
4249 if (f != NULL)
4250 PyFile_SetBufSize(f, bufsize);
4251 return f;
4254 #elif defined(PYCC_GCC)
4256 /* standard posix version of popen() support */
4257 static PyObject *
4258 posix_popen(PyObject *self, PyObject *args)
4260 char *name;
4261 char *mode = "r";
4262 int bufsize = -1;
4263 FILE *fp;
4264 PyObject *f;
4265 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4266 return NULL;
4267 Py_BEGIN_ALLOW_THREADS
4268 fp = popen(name, mode);
4269 Py_END_ALLOW_THREADS
4270 if (fp == NULL)
4271 return posix_error();
4272 f = PyFile_FromFile(fp, name, mode, pclose);
4273 if (f != NULL)
4274 PyFile_SetBufSize(f, bufsize);
4275 return f;
4278 /* fork() under OS/2 has lots'o'warts
4279 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4280 * most of this code is a ripoff of the win32 code, but using the
4281 * capabilities of EMX's C library routines
4284 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4285 #define POPEN_1 1
4286 #define POPEN_2 2
4287 #define POPEN_3 3
4288 #define POPEN_4 4
4290 static PyObject *_PyPopen(char *, int, int, int);
4291 static int _PyPclose(FILE *file);
4294 * Internal dictionary mapping popen* file pointers to process handles,
4295 * for use when retrieving the process exit code. See _PyPclose() below
4296 * for more information on this dictionary's use.
4298 static PyObject *_PyPopenProcs = NULL;
4300 /* os2emx version of popen2()
4302 * The result of this function is a pipe (file) connected to the
4303 * process's stdin, and a pipe connected to the process's stdout.
4306 static PyObject *
4307 os2emx_popen2(PyObject *self, PyObject *args)
4309 PyObject *f;
4310 int tm=0;
4312 char *cmdstring;
4313 char *mode = "t";
4314 int bufsize = -1;
4315 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4316 return NULL;
4318 if (*mode == 't')
4319 tm = O_TEXT;
4320 else if (*mode != 'b') {
4321 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4322 return NULL;
4323 } else
4324 tm = O_BINARY;
4326 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4328 return f;
4332 * Variation on os2emx.popen2
4334 * The result of this function is 3 pipes - the process's stdin,
4335 * stdout and stderr
4338 static PyObject *
4339 os2emx_popen3(PyObject *self, PyObject *args)
4341 PyObject *f;
4342 int tm = 0;
4344 char *cmdstring;
4345 char *mode = "t";
4346 int bufsize = -1;
4347 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4348 return NULL;
4350 if (*mode == 't')
4351 tm = O_TEXT;
4352 else if (*mode != 'b') {
4353 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4354 return NULL;
4355 } else
4356 tm = O_BINARY;
4358 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4360 return f;
4364 * Variation on os2emx.popen2
4366 * The result of this function is 2 pipes - the processes stdin,
4367 * and stdout+stderr combined as a single pipe.
4370 static PyObject *
4371 os2emx_popen4(PyObject *self, PyObject *args)
4373 PyObject *f;
4374 int tm = 0;
4376 char *cmdstring;
4377 char *mode = "t";
4378 int bufsize = -1;
4379 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4380 return NULL;
4382 if (*mode == 't')
4383 tm = O_TEXT;
4384 else if (*mode != 'b') {
4385 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4386 return NULL;
4387 } else
4388 tm = O_BINARY;
4390 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4392 return f;
4395 /* a couple of structures for convenient handling of multiple
4396 * file handles and pipes
4398 struct file_ref
4400 int handle;
4401 int flags;
4404 struct pipe_ref
4406 int rd;
4407 int wr;
4410 /* The following code is derived from the win32 code */
4412 static PyObject *
4413 _PyPopen(char *cmdstring, int mode, int n, int bufsize)
4415 struct file_ref stdio[3];
4416 struct pipe_ref p_fd[3];
4417 FILE *p_s[3];
4418 int file_count, i, pipe_err;
4419 pid_t pipe_pid;
4420 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4421 PyObject *f, *p_f[3];
4423 /* file modes for subsequent fdopen's on pipe handles */
4424 if (mode == O_TEXT)
4426 rd_mode = "rt";
4427 wr_mode = "wt";
4429 else
4431 rd_mode = "rb";
4432 wr_mode = "wb";
4435 /* prepare shell references */
4436 if ((shell = getenv("EMXSHELL")) == NULL)
4437 if ((shell = getenv("COMSPEC")) == NULL)
4439 errno = ENOENT;
4440 return posix_error();
4443 sh_name = _getname(shell);
4444 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4445 opt = "/c";
4446 else
4447 opt = "-c";
4449 /* save current stdio fds + their flags, and set not inheritable */
4450 i = pipe_err = 0;
4451 while (pipe_err >= 0 && i < 3)
4453 pipe_err = stdio[i].handle = dup(i);
4454 stdio[i].flags = fcntl(i, F_GETFD, 0);
4455 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4456 i++;
4458 if (pipe_err < 0)
4460 /* didn't get them all saved - clean up and bail out */
4461 int saved_err = errno;
4462 while (i-- > 0)
4464 close(stdio[i].handle);
4466 errno = saved_err;
4467 return posix_error();
4470 /* create pipe ends */
4471 file_count = 2;
4472 if (n == POPEN_3)
4473 file_count = 3;
4474 i = pipe_err = 0;
4475 while ((pipe_err == 0) && (i < file_count))
4476 pipe_err = pipe((int *)&p_fd[i++]);
4477 if (pipe_err < 0)
4479 /* didn't get them all made - clean up and bail out */
4480 while (i-- > 0)
4482 close(p_fd[i].wr);
4483 close(p_fd[i].rd);
4485 errno = EPIPE;
4486 return posix_error();
4489 /* change the actual standard IO streams over temporarily,
4490 * making the retained pipe ends non-inheritable
4492 pipe_err = 0;
4494 /* - stdin */
4495 if (dup2(p_fd[0].rd, 0) == 0)
4497 close(p_fd[0].rd);
4498 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4499 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4500 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4502 close(p_fd[0].wr);
4503 pipe_err = -1;
4506 else
4508 pipe_err = -1;
4511 /* - stdout */
4512 if (pipe_err == 0)
4514 if (dup2(p_fd[1].wr, 1) == 1)
4516 close(p_fd[1].wr);
4517 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4518 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4519 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4521 close(p_fd[1].rd);
4522 pipe_err = -1;
4525 else
4527 pipe_err = -1;
4531 /* - stderr, as required */
4532 if (pipe_err == 0)
4533 switch (n)
4535 case POPEN_3:
4537 if (dup2(p_fd[2].wr, 2) == 2)
4539 close(p_fd[2].wr);
4540 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4541 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4542 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4544 close(p_fd[2].rd);
4545 pipe_err = -1;
4548 else
4550 pipe_err = -1;
4552 break;
4555 case POPEN_4:
4557 if (dup2(1, 2) != 2)
4559 pipe_err = -1;
4561 break;
4565 /* spawn the child process */
4566 if (pipe_err == 0)
4568 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4569 if (pipe_pid == -1)
4571 pipe_err = -1;
4573 else
4575 /* save the PID into the FILE structure
4576 * NOTE: this implementation doesn't actually
4577 * take advantage of this, but do it for
4578 * completeness - AIM Apr01
4580 for (i = 0; i < file_count; i++)
4581 p_s[i]->_pid = pipe_pid;
4585 /* reset standard IO to normal */
4586 for (i = 0; i < 3; i++)
4588 dup2(stdio[i].handle, i);
4589 fcntl(i, F_SETFD, stdio[i].flags);
4590 close(stdio[i].handle);
4593 /* if any remnant problems, clean up and bail out */
4594 if (pipe_err < 0)
4596 for (i = 0; i < 3; i++)
4598 close(p_fd[i].rd);
4599 close(p_fd[i].wr);
4601 errno = EPIPE;
4602 return posix_error_with_filename(cmdstring);
4605 /* build tuple of file objects to return */
4606 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4607 PyFile_SetBufSize(p_f[0], bufsize);
4608 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4609 PyFile_SetBufSize(p_f[1], bufsize);
4610 if (n == POPEN_3)
4612 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4613 PyFile_SetBufSize(p_f[0], bufsize);
4614 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4616 else
4617 f = PyTuple_Pack(2, p_f[0], p_f[1]);
4620 * Insert the files we've created into the process dictionary
4621 * all referencing the list with the process handle and the
4622 * initial number of files (see description below in _PyPclose).
4623 * Since if _PyPclose later tried to wait on a process when all
4624 * handles weren't closed, it could create a deadlock with the
4625 * child, we spend some energy here to try to ensure that we
4626 * either insert all file handles into the dictionary or none
4627 * at all. It's a little clumsy with the various popen modes
4628 * and variable number of files involved.
4630 if (!_PyPopenProcs)
4632 _PyPopenProcs = PyDict_New();
4635 if (_PyPopenProcs)
4637 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4638 int ins_rc[3];
4640 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4641 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4643 procObj = PyList_New(2);
4644 pidObj = PyLong_FromPid(pipe_pid);
4645 intObj = PyInt_FromLong((long) file_count);
4647 if (procObj && pidObj && intObj)
4649 PyList_SetItem(procObj, 0, pidObj);
4650 PyList_SetItem(procObj, 1, intObj);
4652 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4653 if (fileObj[0])
4655 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4656 fileObj[0],
4657 procObj);
4659 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4660 if (fileObj[1])
4662 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4663 fileObj[1],
4664 procObj);
4666 if (file_count >= 3)
4668 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4669 if (fileObj[2])
4671 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4672 fileObj[2],
4673 procObj);
4677 if (ins_rc[0] < 0 || !fileObj[0] ||
4678 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4679 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4681 /* Something failed - remove any dictionary
4682 * entries that did make it.
4684 if (!ins_rc[0] && fileObj[0])
4686 PyDict_DelItem(_PyPopenProcs,
4687 fileObj[0]);
4689 if (!ins_rc[1] && fileObj[1])
4691 PyDict_DelItem(_PyPopenProcs,
4692 fileObj[1]);
4694 if (!ins_rc[2] && fileObj[2])
4696 PyDict_DelItem(_PyPopenProcs,
4697 fileObj[2]);
4703 * Clean up our localized references for the dictionary keys
4704 * and value since PyDict_SetItem will Py_INCREF any copies
4705 * that got placed in the dictionary.
4707 Py_XDECREF(procObj);
4708 Py_XDECREF(fileObj[0]);
4709 Py_XDECREF(fileObj[1]);
4710 Py_XDECREF(fileObj[2]);
4713 /* Child is launched. */
4714 return f;
4718 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4719 * exit code for the child process and return as a result of the close.
4721 * This function uses the _PyPopenProcs dictionary in order to map the
4722 * input file pointer to information about the process that was
4723 * originally created by the popen* call that created the file pointer.
4724 * The dictionary uses the file pointer as a key (with one entry
4725 * inserted for each file returned by the original popen* call) and a
4726 * single list object as the value for all files from a single call.
4727 * The list object contains the Win32 process handle at [0], and a file
4728 * count at [1], which is initialized to the total number of file
4729 * handles using that list.
4731 * This function closes whichever handle it is passed, and decrements
4732 * the file count in the dictionary for the process handle pointed to
4733 * by this file. On the last close (when the file count reaches zero),
4734 * this function will wait for the child process and then return its
4735 * exit code as the result of the close() operation. This permits the
4736 * files to be closed in any order - it is always the close() of the
4737 * final handle that will return the exit code.
4739 * NOTE: This function is currently called with the GIL released.
4740 * hence we use the GILState API to manage our state.
4743 static int _PyPclose(FILE *file)
4745 int result;
4746 int exit_code;
4747 pid_t pipe_pid;
4748 PyObject *procObj, *pidObj, *intObj, *fileObj;
4749 int file_count;
4750 #ifdef WITH_THREAD
4751 PyGILState_STATE state;
4752 #endif
4754 /* Close the file handle first, to ensure it can't block the
4755 * child from exiting if it's the last handle.
4757 result = fclose(file);
4759 #ifdef WITH_THREAD
4760 state = PyGILState_Ensure();
4761 #endif
4762 if (_PyPopenProcs)
4764 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4765 (procObj = PyDict_GetItem(_PyPopenProcs,
4766 fileObj)) != NULL &&
4767 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4768 (intObj = PyList_GetItem(procObj,1)) != NULL)
4770 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
4771 file_count = (int) PyInt_AsLong(intObj);
4773 if (file_count > 1)
4775 /* Still other files referencing process */
4776 file_count--;
4777 PyList_SetItem(procObj,1,
4778 PyInt_FromLong((long) file_count));
4780 else
4782 /* Last file for this process */
4783 if (result != EOF &&
4784 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4786 /* extract exit status */
4787 if (WIFEXITED(exit_code))
4789 result = WEXITSTATUS(exit_code);
4791 else
4793 errno = EPIPE;
4794 result = -1;
4797 else
4799 /* Indicate failure - this will cause the file object
4800 * to raise an I/O error and translate the last
4801 * error code from errno. We do have a problem with
4802 * last errors that overlap the normal errno table,
4803 * but that's a consistent problem with the file object.
4805 result = -1;
4809 /* Remove this file pointer from dictionary */
4810 PyDict_DelItem(_PyPopenProcs, fileObj);
4812 if (PyDict_Size(_PyPopenProcs) == 0)
4814 Py_DECREF(_PyPopenProcs);
4815 _PyPopenProcs = NULL;
4818 } /* if object retrieval ok */
4820 Py_XDECREF(fileObj);
4821 } /* if _PyPopenProcs */
4823 #ifdef WITH_THREAD
4824 PyGILState_Release(state);
4825 #endif
4826 return result;
4829 #endif /* PYCC_??? */
4831 #elif defined(MS_WINDOWS)
4834 * Portable 'popen' replacement for Win32.
4836 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4837 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
4838 * Return code handling by David Bolen <db3l@fitlinxx.com>.
4841 #include <malloc.h>
4842 #include <io.h>
4843 #include <fcntl.h>
4845 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4846 #define POPEN_1 1
4847 #define POPEN_2 2
4848 #define POPEN_3 3
4849 #define POPEN_4 4
4851 static PyObject *_PyPopen(char *, int, int);
4852 static int _PyPclose(FILE *file);
4855 * Internal dictionary mapping popen* file pointers to process handles,
4856 * for use when retrieving the process exit code. See _PyPclose() below
4857 * for more information on this dictionary's use.
4859 static PyObject *_PyPopenProcs = NULL;
4862 /* popen that works from a GUI.
4864 * The result of this function is a pipe (file) connected to the
4865 * processes stdin or stdout, depending on the requested mode.
4868 static PyObject *
4869 posix_popen(PyObject *self, PyObject *args)
4871 PyObject *f;
4872 int tm = 0;
4874 char *cmdstring;
4875 char *mode = "r";
4876 int bufsize = -1;
4877 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
4878 return NULL;
4880 if (*mode == 'r')
4881 tm = _O_RDONLY;
4882 else if (*mode != 'w') {
4883 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
4884 return NULL;
4885 } else
4886 tm = _O_WRONLY;
4888 if (bufsize != -1) {
4889 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
4890 return NULL;
4893 if (*(mode+1) == 't')
4894 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4895 else if (*(mode+1) == 'b')
4896 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
4897 else
4898 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4900 return f;
4903 /* Variation on win32pipe.popen
4905 * The result of this function is a pipe (file) connected to the
4906 * process's stdin, and a pipe connected to the process's stdout.
4909 static PyObject *
4910 win32_popen2(PyObject *self, PyObject *args)
4912 PyObject *f;
4913 int tm=0;
4915 char *cmdstring;
4916 char *mode = "t";
4917 int bufsize = -1;
4918 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4919 return NULL;
4921 if (*mode == 't')
4922 tm = _O_TEXT;
4923 else if (*mode != 'b') {
4924 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
4925 return NULL;
4926 } else
4927 tm = _O_BINARY;
4929 if (bufsize != -1) {
4930 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
4931 return NULL;
4934 f = _PyPopen(cmdstring, tm, POPEN_2);
4936 return f;
4940 * Variation on <om win32pipe.popen>
4942 * The result of this function is 3 pipes - the process's stdin,
4943 * stdout and stderr
4946 static PyObject *
4947 win32_popen3(PyObject *self, PyObject *args)
4949 PyObject *f;
4950 int tm = 0;
4952 char *cmdstring;
4953 char *mode = "t";
4954 int bufsize = -1;
4955 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4956 return NULL;
4958 if (*mode == 't')
4959 tm = _O_TEXT;
4960 else if (*mode != 'b') {
4961 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
4962 return NULL;
4963 } else
4964 tm = _O_BINARY;
4966 if (bufsize != -1) {
4967 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
4968 return NULL;
4971 f = _PyPopen(cmdstring, tm, POPEN_3);
4973 return f;
4977 * Variation on win32pipe.popen
4979 * The result of this function is 2 pipes - the processes stdin,
4980 * and stdout+stderr combined as a single pipe.
4983 static PyObject *
4984 win32_popen4(PyObject *self, PyObject *args)
4986 PyObject *f;
4987 int tm = 0;
4989 char *cmdstring;
4990 char *mode = "t";
4991 int bufsize = -1;
4992 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4993 return NULL;
4995 if (*mode == 't')
4996 tm = _O_TEXT;
4997 else if (*mode != 'b') {
4998 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
4999 return NULL;
5000 } else
5001 tm = _O_BINARY;
5003 if (bufsize != -1) {
5004 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5005 return NULL;
5008 f = _PyPopen(cmdstring, tm, POPEN_4);
5010 return f;
5013 static BOOL
5014 _PyPopenCreateProcess(char *cmdstring,
5015 HANDLE hStdin,
5016 HANDLE hStdout,
5017 HANDLE hStderr,
5018 HANDLE *hProcess)
5020 PROCESS_INFORMATION piProcInfo;
5021 STARTUPINFO siStartInfo;
5022 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5023 char *s1,*s2, *s3 = " /c ";
5024 const char *szConsoleSpawn = "w9xpopen.exe";
5025 int i;
5026 Py_ssize_t x;
5028 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5029 char *comshell;
5031 s1 = (char *)alloca(i);
5032 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5033 /* x < i, so x fits into an integer */
5034 return (int)x;
5036 /* Explicitly check if we are using COMMAND.COM. If we are
5037 * then use the w9xpopen hack.
5039 comshell = s1 + x;
5040 while (comshell >= s1 && *comshell != '\\')
5041 --comshell;
5042 ++comshell;
5044 if (GetVersion() < 0x80000000 &&
5045 _stricmp(comshell, "command.com") != 0) {
5046 /* NT/2000 and not using command.com. */
5047 x = i + strlen(s3) + strlen(cmdstring) + 1;
5048 s2 = (char *)alloca(x);
5049 ZeroMemory(s2, x);
5050 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5052 else {
5054 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5055 * the workaround listed in KB: Q150956
5057 char modulepath[_MAX_PATH];
5058 struct stat statinfo;
5059 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5060 for (x = i = 0; modulepath[i]; i++)
5061 if (modulepath[i] == SEP)
5062 x = i+1;
5063 modulepath[x] = '\0';
5064 /* Create the full-name to w9xpopen, so we can test it exists */
5065 strncat(modulepath,
5066 szConsoleSpawn,
5067 (sizeof(modulepath)/sizeof(modulepath[0]))
5068 -strlen(modulepath));
5069 if (stat(modulepath, &statinfo) != 0) {
5070 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5071 /* Eeek - file-not-found - possibly an embedding
5072 situation - see if we can locate it in sys.prefix
5074 strncpy(modulepath,
5075 Py_GetExecPrefix(),
5076 mplen);
5077 modulepath[mplen-1] = '\0';
5078 if (modulepath[strlen(modulepath)-1] != '\\')
5079 strcat(modulepath, "\\");
5080 strncat(modulepath,
5081 szConsoleSpawn,
5082 mplen-strlen(modulepath));
5083 /* No where else to look - raise an easily identifiable
5084 error, rather than leaving Windows to report
5085 "file not found" - as the user is probably blissfully
5086 unaware this shim EXE is used, and it will confuse them.
5087 (well, it confused me for a while ;-)
5089 if (stat(modulepath, &statinfo) != 0) {
5090 PyErr_Format(PyExc_RuntimeError,
5091 "Can not locate '%s' which is needed "
5092 "for popen to work with your shell "
5093 "or platform.",
5094 szConsoleSpawn);
5095 return FALSE;
5098 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5099 strlen(modulepath) +
5100 strlen(szConsoleSpawn) + 1;
5102 s2 = (char *)alloca(x);
5103 ZeroMemory(s2, x);
5104 /* To maintain correct argument passing semantics,
5105 we pass the command-line as it stands, and allow
5106 quoting to be applied. w9xpopen.exe will then
5107 use its argv vector, and re-quote the necessary
5108 args for the ultimate child process.
5110 PyOS_snprintf(
5111 s2, x,
5112 "\"%s\" %s%s%s",
5113 modulepath,
5116 cmdstring);
5117 /* Not passing CREATE_NEW_CONSOLE has been known to
5118 cause random failures on win9x. Specifically a
5119 dialog:
5120 "Your program accessed mem currently in use at xxx"
5121 and a hopeful warning about the stability of your
5122 system.
5123 Cost is Ctrl+C won't kill children, but anyone
5124 who cares can have a go!
5126 dwProcessFlags |= CREATE_NEW_CONSOLE;
5130 /* Could be an else here to try cmd.exe / command.com in the path
5131 Now we'll just error out.. */
5132 else {
5133 PyErr_SetString(PyExc_RuntimeError,
5134 "Cannot locate a COMSPEC environment variable to "
5135 "use as the shell");
5136 return FALSE;
5139 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5140 siStartInfo.cb = sizeof(STARTUPINFO);
5141 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5142 siStartInfo.hStdInput = hStdin;
5143 siStartInfo.hStdOutput = hStdout;
5144 siStartInfo.hStdError = hStderr;
5145 siStartInfo.wShowWindow = SW_HIDE;
5147 if (CreateProcess(NULL,
5149 NULL,
5150 NULL,
5151 TRUE,
5152 dwProcessFlags,
5153 NULL,
5154 NULL,
5155 &siStartInfo,
5156 &piProcInfo) ) {
5157 /* Close the handles now so anyone waiting is woken. */
5158 CloseHandle(piProcInfo.hThread);
5160 /* Return process handle */
5161 *hProcess = piProcInfo.hProcess;
5162 return TRUE;
5164 win32_error("CreateProcess", s2);
5165 return FALSE;
5168 /* The following code is based off of KB: Q190351 */
5170 static PyObject *
5171 _PyPopen(char *cmdstring, int mode, int n)
5173 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5174 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5175 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
5177 SECURITY_ATTRIBUTES saAttr;
5178 BOOL fSuccess;
5179 int fd1, fd2, fd3;
5180 FILE *f1, *f2, *f3;
5181 long file_count;
5182 PyObject *f;
5184 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5185 saAttr.bInheritHandle = TRUE;
5186 saAttr.lpSecurityDescriptor = NULL;
5188 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5189 return win32_error("CreatePipe", NULL);
5191 /* Create new output read handle and the input write handle. Set
5192 * the inheritance properties to FALSE. Otherwise, the child inherits
5193 * these handles; resulting in non-closeable handles to the pipes
5194 * being created. */
5195 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5196 GetCurrentProcess(), &hChildStdinWrDup, 0,
5197 FALSE,
5198 DUPLICATE_SAME_ACCESS);
5199 if (!fSuccess)
5200 return win32_error("DuplicateHandle", NULL);
5202 /* Close the inheritable version of ChildStdin
5203 that we're using. */
5204 CloseHandle(hChildStdinWr);
5206 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5207 return win32_error("CreatePipe", NULL);
5209 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5210 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5211 FALSE, DUPLICATE_SAME_ACCESS);
5212 if (!fSuccess)
5213 return win32_error("DuplicateHandle", NULL);
5215 /* Close the inheritable version of ChildStdout
5216 that we're using. */
5217 CloseHandle(hChildStdoutRd);
5219 if (n != POPEN_4) {
5220 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5221 return win32_error("CreatePipe", NULL);
5222 fSuccess = DuplicateHandle(GetCurrentProcess(),
5223 hChildStderrRd,
5224 GetCurrentProcess(),
5225 &hChildStderrRdDup, 0,
5226 FALSE, DUPLICATE_SAME_ACCESS);
5227 if (!fSuccess)
5228 return win32_error("DuplicateHandle", NULL);
5229 /* Close the inheritable version of ChildStdErr that we're using. */
5230 CloseHandle(hChildStderrRd);
5233 switch (n) {
5234 case POPEN_1:
5235 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5236 case _O_WRONLY | _O_TEXT:
5237 /* Case for writing to child Stdin in text mode. */
5238 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5239 f1 = _fdopen(fd1, "w");
5240 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5241 PyFile_SetBufSize(f, 0);
5242 /* We don't care about these pipes anymore, so close them. */
5243 CloseHandle(hChildStdoutRdDup);
5244 CloseHandle(hChildStderrRdDup);
5245 break;
5247 case _O_RDONLY | _O_TEXT:
5248 /* Case for reading from child Stdout in text mode. */
5249 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5250 f1 = _fdopen(fd1, "r");
5251 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5252 PyFile_SetBufSize(f, 0);
5253 /* We don't care about these pipes anymore, so close them. */
5254 CloseHandle(hChildStdinWrDup);
5255 CloseHandle(hChildStderrRdDup);
5256 break;
5258 case _O_RDONLY | _O_BINARY:
5259 /* Case for readinig from child Stdout in binary mode. */
5260 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5261 f1 = _fdopen(fd1, "rb");
5262 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5263 PyFile_SetBufSize(f, 0);
5264 /* We don't care about these pipes anymore, so close them. */
5265 CloseHandle(hChildStdinWrDup);
5266 CloseHandle(hChildStderrRdDup);
5267 break;
5269 case _O_WRONLY | _O_BINARY:
5270 /* Case for writing to child Stdin in binary mode. */
5271 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5272 f1 = _fdopen(fd1, "wb");
5273 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5274 PyFile_SetBufSize(f, 0);
5275 /* We don't care about these pipes anymore, so close them. */
5276 CloseHandle(hChildStdoutRdDup);
5277 CloseHandle(hChildStderrRdDup);
5278 break;
5280 file_count = 1;
5281 break;
5283 case POPEN_2:
5284 case POPEN_4:
5286 char *m1, *m2;
5287 PyObject *p1, *p2;
5289 if (mode & _O_TEXT) {
5290 m1 = "r";
5291 m2 = "w";
5292 } else {
5293 m1 = "rb";
5294 m2 = "wb";
5297 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5298 f1 = _fdopen(fd1, m2);
5299 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5300 f2 = _fdopen(fd2, m1);
5301 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5302 PyFile_SetBufSize(p1, 0);
5303 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5304 PyFile_SetBufSize(p2, 0);
5306 if (n != 4)
5307 CloseHandle(hChildStderrRdDup);
5309 f = PyTuple_Pack(2,p1,p2);
5310 Py_XDECREF(p1);
5311 Py_XDECREF(p2);
5312 file_count = 2;
5313 break;
5316 case POPEN_3:
5318 char *m1, *m2;
5319 PyObject *p1, *p2, *p3;
5321 if (mode & _O_TEXT) {
5322 m1 = "r";
5323 m2 = "w";
5324 } else {
5325 m1 = "rb";
5326 m2 = "wb";
5329 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5330 f1 = _fdopen(fd1, m2);
5331 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5332 f2 = _fdopen(fd2, m1);
5333 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5334 f3 = _fdopen(fd3, m1);
5335 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5336 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5337 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5338 PyFile_SetBufSize(p1, 0);
5339 PyFile_SetBufSize(p2, 0);
5340 PyFile_SetBufSize(p3, 0);
5341 f = PyTuple_Pack(3,p1,p2,p3);
5342 Py_XDECREF(p1);
5343 Py_XDECREF(p2);
5344 Py_XDECREF(p3);
5345 file_count = 3;
5346 break;
5350 if (n == POPEN_4) {
5351 if (!_PyPopenCreateProcess(cmdstring,
5352 hChildStdinRd,
5353 hChildStdoutWr,
5354 hChildStdoutWr,
5355 &hProcess))
5356 return NULL;
5358 else {
5359 if (!_PyPopenCreateProcess(cmdstring,
5360 hChildStdinRd,
5361 hChildStdoutWr,
5362 hChildStderrWr,
5363 &hProcess))
5364 return NULL;
5368 * Insert the files we've created into the process dictionary
5369 * all referencing the list with the process handle and the
5370 * initial number of files (see description below in _PyPclose).
5371 * Since if _PyPclose later tried to wait on a process when all
5372 * handles weren't closed, it could create a deadlock with the
5373 * child, we spend some energy here to try to ensure that we
5374 * either insert all file handles into the dictionary or none
5375 * at all. It's a little clumsy with the various popen modes
5376 * and variable number of files involved.
5378 if (!_PyPopenProcs) {
5379 _PyPopenProcs = PyDict_New();
5382 if (_PyPopenProcs) {
5383 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5384 int ins_rc[3];
5386 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5387 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5389 procObj = PyList_New(2);
5390 hProcessObj = PyLong_FromVoidPtr(hProcess);
5391 intObj = PyInt_FromLong(file_count);
5393 if (procObj && hProcessObj && intObj) {
5394 PyList_SetItem(procObj,0,hProcessObj);
5395 PyList_SetItem(procObj,1,intObj);
5397 fileObj[0] = PyLong_FromVoidPtr(f1);
5398 if (fileObj[0]) {
5399 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5400 fileObj[0],
5401 procObj);
5403 if (file_count >= 2) {
5404 fileObj[1] = PyLong_FromVoidPtr(f2);
5405 if (fileObj[1]) {
5406 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5407 fileObj[1],
5408 procObj);
5411 if (file_count >= 3) {
5412 fileObj[2] = PyLong_FromVoidPtr(f3);
5413 if (fileObj[2]) {
5414 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5415 fileObj[2],
5416 procObj);
5420 if (ins_rc[0] < 0 || !fileObj[0] ||
5421 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5422 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5423 /* Something failed - remove any dictionary
5424 * entries that did make it.
5426 if (!ins_rc[0] && fileObj[0]) {
5427 PyDict_DelItem(_PyPopenProcs,
5428 fileObj[0]);
5430 if (!ins_rc[1] && fileObj[1]) {
5431 PyDict_DelItem(_PyPopenProcs,
5432 fileObj[1]);
5434 if (!ins_rc[2] && fileObj[2]) {
5435 PyDict_DelItem(_PyPopenProcs,
5436 fileObj[2]);
5442 * Clean up our localized references for the dictionary keys
5443 * and value since PyDict_SetItem will Py_INCREF any copies
5444 * that got placed in the dictionary.
5446 Py_XDECREF(procObj);
5447 Py_XDECREF(fileObj[0]);
5448 Py_XDECREF(fileObj[1]);
5449 Py_XDECREF(fileObj[2]);
5452 /* Child is launched. Close the parents copy of those pipe
5453 * handles that only the child should have open. You need to
5454 * make sure that no handles to the write end of the output pipe
5455 * are maintained in this process or else the pipe will not close
5456 * when the child process exits and the ReadFile will hang. */
5458 if (!CloseHandle(hChildStdinRd))
5459 return win32_error("CloseHandle", NULL);
5461 if (!CloseHandle(hChildStdoutWr))
5462 return win32_error("CloseHandle", NULL);
5464 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5465 return win32_error("CloseHandle", NULL);
5467 return f;
5471 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5472 * exit code for the child process and return as a result of the close.
5474 * This function uses the _PyPopenProcs dictionary in order to map the
5475 * input file pointer to information about the process that was
5476 * originally created by the popen* call that created the file pointer.
5477 * The dictionary uses the file pointer as a key (with one entry
5478 * inserted for each file returned by the original popen* call) and a
5479 * single list object as the value for all files from a single call.
5480 * The list object contains the Win32 process handle at [0], and a file
5481 * count at [1], which is initialized to the total number of file
5482 * handles using that list.
5484 * This function closes whichever handle it is passed, and decrements
5485 * the file count in the dictionary for the process handle pointed to
5486 * by this file. On the last close (when the file count reaches zero),
5487 * this function will wait for the child process and then return its
5488 * exit code as the result of the close() operation. This permits the
5489 * files to be closed in any order - it is always the close() of the
5490 * final handle that will return the exit code.
5492 * NOTE: This function is currently called with the GIL released.
5493 * hence we use the GILState API to manage our state.
5496 static int _PyPclose(FILE *file)
5498 int result;
5499 DWORD exit_code;
5500 HANDLE hProcess;
5501 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5502 long file_count;
5503 #ifdef WITH_THREAD
5504 PyGILState_STATE state;
5505 #endif
5507 /* Close the file handle first, to ensure it can't block the
5508 * child from exiting if it's the last handle.
5510 result = fclose(file);
5511 #ifdef WITH_THREAD
5512 state = PyGILState_Ensure();
5513 #endif
5514 if (_PyPopenProcs) {
5515 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5516 (procObj = PyDict_GetItem(_PyPopenProcs,
5517 fileObj)) != NULL &&
5518 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5519 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5521 hProcess = PyLong_AsVoidPtr(hProcessObj);
5522 file_count = PyInt_AsLong(intObj);
5524 if (file_count > 1) {
5525 /* Still other files referencing process */
5526 file_count--;
5527 PyList_SetItem(procObj,1,
5528 PyInt_FromLong(file_count));
5529 } else {
5530 /* Last file for this process */
5531 if (result != EOF &&
5532 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5533 GetExitCodeProcess(hProcess, &exit_code)) {
5534 /* Possible truncation here in 16-bit environments, but
5535 * real exit codes are just the lower byte in any event.
5537 result = exit_code;
5538 } else {
5539 /* Indicate failure - this will cause the file object
5540 * to raise an I/O error and translate the last Win32
5541 * error code from errno. We do have a problem with
5542 * last errors that overlap the normal errno table,
5543 * but that's a consistent problem with the file object.
5545 if (result != EOF) {
5546 /* If the error wasn't from the fclose(), then
5547 * set errno for the file object error handling.
5549 errno = GetLastError();
5551 result = -1;
5554 /* Free up the native handle at this point */
5555 CloseHandle(hProcess);
5558 /* Remove this file pointer from dictionary */
5559 PyDict_DelItem(_PyPopenProcs, fileObj);
5561 if (PyDict_Size(_PyPopenProcs) == 0) {
5562 Py_DECREF(_PyPopenProcs);
5563 _PyPopenProcs = NULL;
5566 } /* if object retrieval ok */
5568 Py_XDECREF(fileObj);
5569 } /* if _PyPopenProcs */
5571 #ifdef WITH_THREAD
5572 PyGILState_Release(state);
5573 #endif
5574 return result;
5577 #else /* which OS? */
5578 static PyObject *
5579 posix_popen(PyObject *self, PyObject *args)
5581 char *name;
5582 char *mode = "r";
5583 int bufsize = -1;
5584 FILE *fp;
5585 PyObject *f;
5586 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5587 return NULL;
5588 /* Strip mode of binary or text modifiers */
5589 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5590 mode = "r";
5591 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5592 mode = "w";
5593 Py_BEGIN_ALLOW_THREADS
5594 fp = popen(name, mode);
5595 Py_END_ALLOW_THREADS
5596 if (fp == NULL)
5597 return posix_error();
5598 f = PyFile_FromFile(fp, name, mode, pclose);
5599 if (f != NULL)
5600 PyFile_SetBufSize(f, bufsize);
5601 return f;
5604 #endif /* PYOS_??? */
5605 #endif /* HAVE_POPEN */
5608 #ifdef HAVE_SETUID
5609 PyDoc_STRVAR(posix_setuid__doc__,
5610 "setuid(uid)\n\n\
5611 Set the current process's user id.");
5613 static PyObject *
5614 posix_setuid(PyObject *self, PyObject *args)
5616 long uid_arg;
5617 uid_t uid;
5618 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5619 return NULL;
5620 uid = uid_arg;
5621 if (uid != uid_arg) {
5622 PyErr_SetString(PyExc_OverflowError, "user id too big");
5623 return NULL;
5625 if (setuid(uid) < 0)
5626 return posix_error();
5627 Py_INCREF(Py_None);
5628 return Py_None;
5630 #endif /* HAVE_SETUID */
5633 #ifdef HAVE_SETEUID
5634 PyDoc_STRVAR(posix_seteuid__doc__,
5635 "seteuid(uid)\n\n\
5636 Set the current process's effective user id.");
5638 static PyObject *
5639 posix_seteuid (PyObject *self, PyObject *args)
5641 long euid_arg;
5642 uid_t euid;
5643 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5644 return NULL;
5645 euid = euid_arg;
5646 if (euid != euid_arg) {
5647 PyErr_SetString(PyExc_OverflowError, "user id too big");
5648 return NULL;
5650 if (seteuid(euid) < 0) {
5651 return posix_error();
5652 } else {
5653 Py_INCREF(Py_None);
5654 return Py_None;
5657 #endif /* HAVE_SETEUID */
5659 #ifdef HAVE_SETEGID
5660 PyDoc_STRVAR(posix_setegid__doc__,
5661 "setegid(gid)\n\n\
5662 Set the current process's effective group id.");
5664 static PyObject *
5665 posix_setegid (PyObject *self, PyObject *args)
5667 long egid_arg;
5668 gid_t egid;
5669 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5670 return NULL;
5671 egid = egid_arg;
5672 if (egid != egid_arg) {
5673 PyErr_SetString(PyExc_OverflowError, "group id too big");
5674 return NULL;
5676 if (setegid(egid) < 0) {
5677 return posix_error();
5678 } else {
5679 Py_INCREF(Py_None);
5680 return Py_None;
5683 #endif /* HAVE_SETEGID */
5685 #ifdef HAVE_SETREUID
5686 PyDoc_STRVAR(posix_setreuid__doc__,
5687 "setreuid(ruid, euid)\n\n\
5688 Set the current process's real and effective user ids.");
5690 static PyObject *
5691 posix_setreuid (PyObject *self, PyObject *args)
5693 long ruid_arg, euid_arg;
5694 uid_t ruid, euid;
5695 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5696 return NULL;
5697 ruid = ruid_arg;
5698 euid = euid_arg;
5699 if (euid != euid_arg || ruid != ruid_arg) {
5700 PyErr_SetString(PyExc_OverflowError, "user id too big");
5701 return NULL;
5703 if (setreuid(ruid, euid) < 0) {
5704 return posix_error();
5705 } else {
5706 Py_INCREF(Py_None);
5707 return Py_None;
5710 #endif /* HAVE_SETREUID */
5712 #ifdef HAVE_SETREGID
5713 PyDoc_STRVAR(posix_setregid__doc__,
5714 "setregid(rgid, egid)\n\n\
5715 Set the current process's real and effective group ids.");
5717 static PyObject *
5718 posix_setregid (PyObject *self, PyObject *args)
5720 long rgid_arg, egid_arg;
5721 gid_t rgid, egid;
5722 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5723 return NULL;
5724 rgid = rgid_arg;
5725 egid = egid_arg;
5726 if (egid != egid_arg || rgid != rgid_arg) {
5727 PyErr_SetString(PyExc_OverflowError, "group id too big");
5728 return NULL;
5730 if (setregid(rgid, egid) < 0) {
5731 return posix_error();
5732 } else {
5733 Py_INCREF(Py_None);
5734 return Py_None;
5737 #endif /* HAVE_SETREGID */
5739 #ifdef HAVE_SETGID
5740 PyDoc_STRVAR(posix_setgid__doc__,
5741 "setgid(gid)\n\n\
5742 Set the current process's group id.");
5744 static PyObject *
5745 posix_setgid(PyObject *self, PyObject *args)
5747 long gid_arg;
5748 gid_t gid;
5749 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
5750 return NULL;
5751 gid = gid_arg;
5752 if (gid != gid_arg) {
5753 PyErr_SetString(PyExc_OverflowError, "group id too big");
5754 return NULL;
5756 if (setgid(gid) < 0)
5757 return posix_error();
5758 Py_INCREF(Py_None);
5759 return Py_None;
5761 #endif /* HAVE_SETGID */
5763 #ifdef HAVE_SETGROUPS
5764 PyDoc_STRVAR(posix_setgroups__doc__,
5765 "setgroups(list)\n\n\
5766 Set the groups of the current process to list.");
5768 static PyObject *
5769 posix_setgroups(PyObject *self, PyObject *groups)
5771 int i, len;
5772 gid_t grouplist[MAX_GROUPS];
5774 if (!PySequence_Check(groups)) {
5775 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5776 return NULL;
5778 len = PySequence_Size(groups);
5779 if (len > MAX_GROUPS) {
5780 PyErr_SetString(PyExc_ValueError, "too many groups");
5781 return NULL;
5783 for(i = 0; i < len; i++) {
5784 PyObject *elem;
5785 elem = PySequence_GetItem(groups, i);
5786 if (!elem)
5787 return NULL;
5788 if (!PyInt_Check(elem)) {
5789 if (!PyLong_Check(elem)) {
5790 PyErr_SetString(PyExc_TypeError,
5791 "groups must be integers");
5792 Py_DECREF(elem);
5793 return NULL;
5794 } else {
5795 unsigned long x = PyLong_AsUnsignedLong(elem);
5796 if (PyErr_Occurred()) {
5797 PyErr_SetString(PyExc_TypeError,
5798 "group id too big");
5799 Py_DECREF(elem);
5800 return NULL;
5802 grouplist[i] = x;
5803 /* read back to see if it fits in gid_t */
5804 if (grouplist[i] != x) {
5805 PyErr_SetString(PyExc_TypeError,
5806 "group id too big");
5807 Py_DECREF(elem);
5808 return NULL;
5811 } else {
5812 long x = PyInt_AsLong(elem);
5813 grouplist[i] = x;
5814 if (grouplist[i] != x) {
5815 PyErr_SetString(PyExc_TypeError,
5816 "group id too big");
5817 Py_DECREF(elem);
5818 return NULL;
5821 Py_DECREF(elem);
5824 if (setgroups(len, grouplist) < 0)
5825 return posix_error();
5826 Py_INCREF(Py_None);
5827 return Py_None;
5829 #endif /* HAVE_SETGROUPS */
5831 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5832 static PyObject *
5833 wait_helper(pid_t pid, int status, struct rusage *ru)
5835 PyObject *result;
5836 static PyObject *struct_rusage;
5838 if (pid == -1)
5839 return posix_error();
5841 if (struct_rusage == NULL) {
5842 PyObject *m = PyImport_ImportModuleNoBlock("resource");
5843 if (m == NULL)
5844 return NULL;
5845 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5846 Py_DECREF(m);
5847 if (struct_rusage == NULL)
5848 return NULL;
5851 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5852 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5853 if (!result)
5854 return NULL;
5856 #ifndef doubletime
5857 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5858 #endif
5860 PyStructSequence_SET_ITEM(result, 0,
5861 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5862 PyStructSequence_SET_ITEM(result, 1,
5863 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5864 #define SET_INT(result, index, value)\
5865 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5866 SET_INT(result, 2, ru->ru_maxrss);
5867 SET_INT(result, 3, ru->ru_ixrss);
5868 SET_INT(result, 4, ru->ru_idrss);
5869 SET_INT(result, 5, ru->ru_isrss);
5870 SET_INT(result, 6, ru->ru_minflt);
5871 SET_INT(result, 7, ru->ru_majflt);
5872 SET_INT(result, 8, ru->ru_nswap);
5873 SET_INT(result, 9, ru->ru_inblock);
5874 SET_INT(result, 10, ru->ru_oublock);
5875 SET_INT(result, 11, ru->ru_msgsnd);
5876 SET_INT(result, 12, ru->ru_msgrcv);
5877 SET_INT(result, 13, ru->ru_nsignals);
5878 SET_INT(result, 14, ru->ru_nvcsw);
5879 SET_INT(result, 15, ru->ru_nivcsw);
5880 #undef SET_INT
5882 if (PyErr_Occurred()) {
5883 Py_DECREF(result);
5884 return NULL;
5887 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
5889 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5891 #ifdef HAVE_WAIT3
5892 PyDoc_STRVAR(posix_wait3__doc__,
5893 "wait3(options) -> (pid, status, rusage)\n\n\
5894 Wait for completion of a child process.");
5896 static PyObject *
5897 posix_wait3(PyObject *self, PyObject *args)
5899 pid_t pid;
5900 int options;
5901 struct rusage ru;
5902 WAIT_TYPE status;
5903 WAIT_STATUS_INT(status) = 0;
5905 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5906 return NULL;
5908 Py_BEGIN_ALLOW_THREADS
5909 pid = wait3(&status, options, &ru);
5910 Py_END_ALLOW_THREADS
5912 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5914 #endif /* HAVE_WAIT3 */
5916 #ifdef HAVE_WAIT4
5917 PyDoc_STRVAR(posix_wait4__doc__,
5918 "wait4(pid, options) -> (pid, status, rusage)\n\n\
5919 Wait for completion of a given child process.");
5921 static PyObject *
5922 posix_wait4(PyObject *self, PyObject *args)
5924 pid_t pid;
5925 int options;
5926 struct rusage ru;
5927 WAIT_TYPE status;
5928 WAIT_STATUS_INT(status) = 0;
5930 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
5931 return NULL;
5933 Py_BEGIN_ALLOW_THREADS
5934 pid = wait4(pid, &status, options, &ru);
5935 Py_END_ALLOW_THREADS
5937 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5939 #endif /* HAVE_WAIT4 */
5941 #ifdef HAVE_WAITPID
5942 PyDoc_STRVAR(posix_waitpid__doc__,
5943 "waitpid(pid, options) -> (pid, status)\n\n\
5944 Wait for completion of a given child process.");
5946 static PyObject *
5947 posix_waitpid(PyObject *self, PyObject *args)
5949 pid_t pid;
5950 int options;
5951 WAIT_TYPE status;
5952 WAIT_STATUS_INT(status) = 0;
5954 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
5955 return NULL;
5956 Py_BEGIN_ALLOW_THREADS
5957 pid = waitpid(pid, &status, options);
5958 Py_END_ALLOW_THREADS
5959 if (pid == -1)
5960 return posix_error();
5962 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
5965 #elif defined(HAVE_CWAIT)
5967 /* MS C has a variant of waitpid() that's usable for most purposes. */
5968 PyDoc_STRVAR(posix_waitpid__doc__,
5969 "waitpid(pid, options) -> (pid, status << 8)\n\n"
5970 "Wait for completion of a given process. options is ignored on Windows.");
5972 static PyObject *
5973 posix_waitpid(PyObject *self, PyObject *args)
5975 Py_intptr_t pid;
5976 int status, options;
5978 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
5979 return NULL;
5980 Py_BEGIN_ALLOW_THREADS
5981 pid = _cwait(&status, pid, options);
5982 Py_END_ALLOW_THREADS
5983 if (pid == -1)
5984 return posix_error();
5986 /* shift the status left a byte so this is more like the POSIX waitpid */
5987 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
5989 #endif /* HAVE_WAITPID || HAVE_CWAIT */
5991 #ifdef HAVE_WAIT
5992 PyDoc_STRVAR(posix_wait__doc__,
5993 "wait() -> (pid, status)\n\n\
5994 Wait for completion of a child process.");
5996 static PyObject *
5997 posix_wait(PyObject *self, PyObject *noargs)
5999 pid_t pid;
6000 WAIT_TYPE status;
6001 WAIT_STATUS_INT(status) = 0;
6003 Py_BEGIN_ALLOW_THREADS
6004 pid = wait(&status);
6005 Py_END_ALLOW_THREADS
6006 if (pid == -1)
6007 return posix_error();
6009 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
6011 #endif
6014 PyDoc_STRVAR(posix_lstat__doc__,
6015 "lstat(path) -> stat result\n\n\
6016 Like stat(path), but do not follow symbolic links.");
6018 static PyObject *
6019 posix_lstat(PyObject *self, PyObject *args)
6021 #ifdef HAVE_LSTAT
6022 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
6023 #else /* !HAVE_LSTAT */
6024 #ifdef MS_WINDOWS
6025 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
6026 #else
6027 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
6028 #endif
6029 #endif /* !HAVE_LSTAT */
6033 #ifdef HAVE_READLINK
6034 PyDoc_STRVAR(posix_readlink__doc__,
6035 "readlink(path) -> path\n\n\
6036 Return a string representing the path to which the symbolic link points.");
6038 static PyObject *
6039 posix_readlink(PyObject *self, PyObject *args)
6041 PyObject* v;
6042 char buf[MAXPATHLEN];
6043 char *path;
6044 int n;
6045 #ifdef Py_USING_UNICODE
6046 int arg_is_unicode = 0;
6047 #endif
6049 if (!PyArg_ParseTuple(args, "et:readlink",
6050 Py_FileSystemDefaultEncoding, &path))
6051 return NULL;
6052 #ifdef Py_USING_UNICODE
6053 v = PySequence_GetItem(args, 0);
6054 if (v == NULL) {
6055 PyMem_Free(path);
6056 return NULL;
6059 if (PyUnicode_Check(v)) {
6060 arg_is_unicode = 1;
6062 Py_DECREF(v);
6063 #endif
6065 Py_BEGIN_ALLOW_THREADS
6066 n = readlink(path, buf, (int) sizeof buf);
6067 Py_END_ALLOW_THREADS
6068 if (n < 0)
6069 return posix_error_with_allocated_filename(path);
6071 PyMem_Free(path);
6072 v = PyString_FromStringAndSize(buf, n);
6073 #ifdef Py_USING_UNICODE
6074 if (arg_is_unicode) {
6075 PyObject *w;
6077 w = PyUnicode_FromEncodedObject(v,
6078 Py_FileSystemDefaultEncoding,
6079 "strict");
6080 if (w != NULL) {
6081 Py_DECREF(v);
6082 v = w;
6084 else {
6085 /* fall back to the original byte string, as
6086 discussed in patch #683592 */
6087 PyErr_Clear();
6090 #endif
6091 return v;
6093 #endif /* HAVE_READLINK */
6096 #ifdef HAVE_SYMLINK
6097 PyDoc_STRVAR(posix_symlink__doc__,
6098 "symlink(src, dst)\n\n\
6099 Create a symbolic link pointing to src named dst.");
6101 static PyObject *
6102 posix_symlink(PyObject *self, PyObject *args)
6104 return posix_2str(args, "etet:symlink", symlink);
6106 #endif /* HAVE_SYMLINK */
6109 #ifdef HAVE_TIMES
6110 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
6111 static long
6112 system_uptime(void)
6114 ULONG value = 0;
6116 Py_BEGIN_ALLOW_THREADS
6117 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6118 Py_END_ALLOW_THREADS
6120 return value;
6123 static PyObject *
6124 posix_times(PyObject *self, PyObject *noargs)
6126 /* Currently Only Uptime is Provided -- Others Later */
6127 return Py_BuildValue("ddddd",
6128 (double)0 /* t.tms_utime / HZ */,
6129 (double)0 /* t.tms_stime / HZ */,
6130 (double)0 /* t.tms_cutime / HZ */,
6131 (double)0 /* t.tms_cstime / HZ */,
6132 (double)system_uptime() / 1000);
6134 #else /* not OS2 */
6135 #define NEED_TICKS_PER_SECOND
6136 static long ticks_per_second = -1;
6137 static PyObject *
6138 posix_times(PyObject *self, PyObject *noargs)
6140 struct tms t;
6141 clock_t c;
6142 errno = 0;
6143 c = times(&t);
6144 if (c == (clock_t) -1)
6145 return posix_error();
6146 return Py_BuildValue("ddddd",
6147 (double)t.tms_utime / ticks_per_second,
6148 (double)t.tms_stime / ticks_per_second,
6149 (double)t.tms_cutime / ticks_per_second,
6150 (double)t.tms_cstime / ticks_per_second,
6151 (double)c / ticks_per_second);
6153 #endif /* not OS2 */
6154 #endif /* HAVE_TIMES */
6157 #ifdef MS_WINDOWS
6158 #define HAVE_TIMES /* so the method table will pick it up */
6159 static PyObject *
6160 posix_times(PyObject *self, PyObject *noargs)
6162 FILETIME create, exit, kernel, user;
6163 HANDLE hProc;
6164 hProc = GetCurrentProcess();
6165 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6166 /* The fields of a FILETIME structure are the hi and lo part
6167 of a 64-bit value expressed in 100 nanosecond units.
6168 1e7 is one second in such units; 1e-7 the inverse.
6169 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6171 return Py_BuildValue(
6172 "ddddd",
6173 (double)(user.dwHighDateTime*429.4967296 +
6174 user.dwLowDateTime*1e-7),
6175 (double)(kernel.dwHighDateTime*429.4967296 +
6176 kernel.dwLowDateTime*1e-7),
6177 (double)0,
6178 (double)0,
6179 (double)0);
6181 #endif /* MS_WINDOWS */
6183 #ifdef HAVE_TIMES
6184 PyDoc_STRVAR(posix_times__doc__,
6185 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
6186 Return a tuple of floating point numbers indicating process times.");
6187 #endif
6190 #ifdef HAVE_GETSID
6191 PyDoc_STRVAR(posix_getsid__doc__,
6192 "getsid(pid) -> sid\n\n\
6193 Call the system call getsid().");
6195 static PyObject *
6196 posix_getsid(PyObject *self, PyObject *args)
6198 pid_t pid;
6199 int sid;
6200 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6201 return NULL;
6202 sid = getsid(pid);
6203 if (sid < 0)
6204 return posix_error();
6205 return PyInt_FromLong((long)sid);
6207 #endif /* HAVE_GETSID */
6210 #ifdef HAVE_SETSID
6211 PyDoc_STRVAR(posix_setsid__doc__,
6212 "setsid()\n\n\
6213 Call the system call setsid().");
6215 static PyObject *
6216 posix_setsid(PyObject *self, PyObject *noargs)
6218 if (setsid() < 0)
6219 return posix_error();
6220 Py_INCREF(Py_None);
6221 return Py_None;
6223 #endif /* HAVE_SETSID */
6225 #ifdef HAVE_SETPGID
6226 PyDoc_STRVAR(posix_setpgid__doc__,
6227 "setpgid(pid, pgrp)\n\n\
6228 Call the system call setpgid().");
6230 static PyObject *
6231 posix_setpgid(PyObject *self, PyObject *args)
6233 pid_t pid;
6234 int pgrp;
6235 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6236 return NULL;
6237 if (setpgid(pid, pgrp) < 0)
6238 return posix_error();
6239 Py_INCREF(Py_None);
6240 return Py_None;
6242 #endif /* HAVE_SETPGID */
6245 #ifdef HAVE_TCGETPGRP
6246 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
6247 "tcgetpgrp(fd) -> pgid\n\n\
6248 Return the process group associated with the terminal given by a fd.");
6250 static PyObject *
6251 posix_tcgetpgrp(PyObject *self, PyObject *args)
6253 int fd;
6254 pid_t pgid;
6255 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6256 return NULL;
6257 pgid = tcgetpgrp(fd);
6258 if (pgid < 0)
6259 return posix_error();
6260 return PyLong_FromPid(pgid);
6262 #endif /* HAVE_TCGETPGRP */
6265 #ifdef HAVE_TCSETPGRP
6266 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
6267 "tcsetpgrp(fd, pgid)\n\n\
6268 Set the process group associated with the terminal given by a fd.");
6270 static PyObject *
6271 posix_tcsetpgrp(PyObject *self, PyObject *args)
6273 int fd;
6274 pid_t pgid;
6275 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6276 return NULL;
6277 if (tcsetpgrp(fd, pgid) < 0)
6278 return posix_error();
6279 Py_INCREF(Py_None);
6280 return Py_None;
6282 #endif /* HAVE_TCSETPGRP */
6284 /* Functions acting on file descriptors */
6286 PyDoc_STRVAR(posix_open__doc__,
6287 "open(filename, flag [, mode=0777]) -> fd\n\n\
6288 Open a file (for low level IO).");
6290 static PyObject *
6291 posix_open(PyObject *self, PyObject *args)
6293 char *file = NULL;
6294 int flag;
6295 int mode = 0777;
6296 int fd;
6298 #ifdef MS_WINDOWS
6299 if (unicode_file_names()) {
6300 PyUnicodeObject *po;
6301 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6302 Py_BEGIN_ALLOW_THREADS
6303 /* PyUnicode_AS_UNICODE OK without thread
6304 lock as it is a simple dereference. */
6305 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6306 Py_END_ALLOW_THREADS
6307 if (fd < 0)
6308 return posix_error();
6309 return PyInt_FromLong((long)fd);
6311 /* Drop the argument parsing error as narrow strings
6312 are also valid. */
6313 PyErr_Clear();
6315 #endif
6317 if (!PyArg_ParseTuple(args, "eti|i",
6318 Py_FileSystemDefaultEncoding, &file,
6319 &flag, &mode))
6320 return NULL;
6322 Py_BEGIN_ALLOW_THREADS
6323 fd = open(file, flag, mode);
6324 Py_END_ALLOW_THREADS
6325 if (fd < 0)
6326 return posix_error_with_allocated_filename(file);
6327 PyMem_Free(file);
6328 return PyInt_FromLong((long)fd);
6332 PyDoc_STRVAR(posix_close__doc__,
6333 "close(fd)\n\n\
6334 Close a file descriptor (for low level IO).");
6336 static PyObject *
6337 posix_close(PyObject *self, PyObject *args)
6339 int fd, res;
6340 if (!PyArg_ParseTuple(args, "i:close", &fd))
6341 return NULL;
6342 if (!_PyVerify_fd(fd))
6343 return posix_error();
6344 Py_BEGIN_ALLOW_THREADS
6345 res = close(fd);
6346 Py_END_ALLOW_THREADS
6347 if (res < 0)
6348 return posix_error();
6349 Py_INCREF(Py_None);
6350 return Py_None;
6354 PyDoc_STRVAR(posix_closerange__doc__,
6355 "closerange(fd_low, fd_high)\n\n\
6356 Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6358 static PyObject *
6359 posix_closerange(PyObject *self, PyObject *args)
6361 int fd_from, fd_to, i;
6362 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6363 return NULL;
6364 Py_BEGIN_ALLOW_THREADS
6365 for (i = fd_from; i < fd_to; i++)
6366 if (_PyVerify_fd(i))
6367 close(i);
6368 Py_END_ALLOW_THREADS
6369 Py_RETURN_NONE;
6373 PyDoc_STRVAR(posix_dup__doc__,
6374 "dup(fd) -> fd2\n\n\
6375 Return a duplicate of a file descriptor.");
6377 static PyObject *
6378 posix_dup(PyObject *self, PyObject *args)
6380 int fd;
6381 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6382 return NULL;
6383 if (!_PyVerify_fd(fd))
6384 return posix_error();
6385 Py_BEGIN_ALLOW_THREADS
6386 fd = dup(fd);
6387 Py_END_ALLOW_THREADS
6388 if (fd < 0)
6389 return posix_error();
6390 return PyInt_FromLong((long)fd);
6394 PyDoc_STRVAR(posix_dup2__doc__,
6395 "dup2(old_fd, new_fd)\n\n\
6396 Duplicate file descriptor.");
6398 static PyObject *
6399 posix_dup2(PyObject *self, PyObject *args)
6401 int fd, fd2, res;
6402 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6403 return NULL;
6404 if (!_PyVerify_fd_dup2(fd, fd2))
6405 return posix_error();
6406 Py_BEGIN_ALLOW_THREADS
6407 res = dup2(fd, fd2);
6408 Py_END_ALLOW_THREADS
6409 if (res < 0)
6410 return posix_error();
6411 Py_INCREF(Py_None);
6412 return Py_None;
6416 PyDoc_STRVAR(posix_lseek__doc__,
6417 "lseek(fd, pos, how) -> newpos\n\n\
6418 Set the current position of a file descriptor.");
6420 static PyObject *
6421 posix_lseek(PyObject *self, PyObject *args)
6423 int fd, how;
6424 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6425 PY_LONG_LONG pos, res;
6426 #else
6427 off_t pos, res;
6428 #endif
6429 PyObject *posobj;
6430 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6431 return NULL;
6432 #ifdef SEEK_SET
6433 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6434 switch (how) {
6435 case 0: how = SEEK_SET; break;
6436 case 1: how = SEEK_CUR; break;
6437 case 2: how = SEEK_END; break;
6439 #endif /* SEEK_END */
6441 #if !defined(HAVE_LARGEFILE_SUPPORT)
6442 pos = PyInt_AsLong(posobj);
6443 #else
6444 pos = PyLong_Check(posobj) ?
6445 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6446 #endif
6447 if (PyErr_Occurred())
6448 return NULL;
6450 if (!_PyVerify_fd(fd))
6451 return posix_error();
6452 Py_BEGIN_ALLOW_THREADS
6453 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6454 res = _lseeki64(fd, pos, how);
6455 #else
6456 res = lseek(fd, pos, how);
6457 #endif
6458 Py_END_ALLOW_THREADS
6459 if (res < 0)
6460 return posix_error();
6462 #if !defined(HAVE_LARGEFILE_SUPPORT)
6463 return PyInt_FromLong(res);
6464 #else
6465 return PyLong_FromLongLong(res);
6466 #endif
6470 PyDoc_STRVAR(posix_read__doc__,
6471 "read(fd, buffersize) -> string\n\n\
6472 Read a file descriptor.");
6474 static PyObject *
6475 posix_read(PyObject *self, PyObject *args)
6477 int fd, size, n;
6478 PyObject *buffer;
6479 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6480 return NULL;
6481 if (size < 0) {
6482 errno = EINVAL;
6483 return posix_error();
6485 buffer = PyString_FromStringAndSize((char *)NULL, size);
6486 if (buffer == NULL)
6487 return NULL;
6488 if (!_PyVerify_fd(fd))
6489 return posix_error();
6490 Py_BEGIN_ALLOW_THREADS
6491 n = read(fd, PyString_AsString(buffer), size);
6492 Py_END_ALLOW_THREADS
6493 if (n < 0) {
6494 Py_DECREF(buffer);
6495 return posix_error();
6497 if (n != size)
6498 _PyString_Resize(&buffer, n);
6499 return buffer;
6503 PyDoc_STRVAR(posix_write__doc__,
6504 "write(fd, string) -> byteswritten\n\n\
6505 Write a string to a file descriptor.");
6507 static PyObject *
6508 posix_write(PyObject *self, PyObject *args)
6510 Py_buffer pbuf;
6511 int fd;
6512 Py_ssize_t size;
6514 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6515 return NULL;
6516 if (!_PyVerify_fd(fd))
6517 return posix_error();
6518 Py_BEGIN_ALLOW_THREADS
6519 size = write(fd, pbuf.buf, (size_t)pbuf.len);
6520 Py_END_ALLOW_THREADS
6521 PyBuffer_Release(&pbuf);
6522 if (size < 0)
6523 return posix_error();
6524 return PyInt_FromSsize_t(size);
6528 PyDoc_STRVAR(posix_fstat__doc__,
6529 "fstat(fd) -> stat result\n\n\
6530 Like stat(), but for an open file descriptor.");
6532 static PyObject *
6533 posix_fstat(PyObject *self, PyObject *args)
6535 int fd;
6536 STRUCT_STAT st;
6537 int res;
6538 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6539 return NULL;
6540 #ifdef __VMS
6541 /* on OpenVMS we must ensure that all bytes are written to the file */
6542 fsync(fd);
6543 #endif
6544 if (!_PyVerify_fd(fd))
6545 return posix_error();
6546 Py_BEGIN_ALLOW_THREADS
6547 res = FSTAT(fd, &st);
6548 Py_END_ALLOW_THREADS
6549 if (res != 0) {
6550 #ifdef MS_WINDOWS
6551 return win32_error("fstat", NULL);
6552 #else
6553 return posix_error();
6554 #endif
6557 return _pystat_fromstructstat(&st);
6561 PyDoc_STRVAR(posix_fdopen__doc__,
6562 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
6563 Return an open file object connected to a file descriptor.");
6565 static PyObject *
6566 posix_fdopen(PyObject *self, PyObject *args)
6568 int fd;
6569 char *orgmode = "r";
6570 int bufsize = -1;
6571 FILE *fp;
6572 PyObject *f;
6573 char *mode;
6574 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6575 return NULL;
6577 /* Sanitize mode. See fileobject.c */
6578 mode = PyMem_MALLOC(strlen(orgmode)+3);
6579 if (!mode) {
6580 PyErr_NoMemory();
6581 return NULL;
6583 strcpy(mode, orgmode);
6584 if (_PyFile_SanitizeMode(mode)) {
6585 PyMem_FREE(mode);
6586 return NULL;
6588 if (!_PyVerify_fd(fd))
6589 return posix_error();
6590 Py_BEGIN_ALLOW_THREADS
6591 #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6592 if (mode[0] == 'a') {
6593 /* try to make sure the O_APPEND flag is set */
6594 int flags;
6595 flags = fcntl(fd, F_GETFL);
6596 if (flags != -1)
6597 fcntl(fd, F_SETFL, flags | O_APPEND);
6598 fp = fdopen(fd, mode);
6599 if (fp == NULL && flags != -1)
6600 /* restore old mode if fdopen failed */
6601 fcntl(fd, F_SETFL, flags);
6602 } else {
6603 fp = fdopen(fd, mode);
6605 #else
6606 fp = fdopen(fd, mode);
6607 #endif
6608 Py_END_ALLOW_THREADS
6609 PyMem_FREE(mode);
6610 if (fp == NULL)
6611 return posix_error();
6612 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
6613 if (f != NULL)
6614 PyFile_SetBufSize(f, bufsize);
6615 return f;
6618 PyDoc_STRVAR(posix_isatty__doc__,
6619 "isatty(fd) -> bool\n\n\
6620 Return True if the file descriptor 'fd' is an open file descriptor\n\
6621 connected to the slave end of a terminal.");
6623 static PyObject *
6624 posix_isatty(PyObject *self, PyObject *args)
6626 int fd;
6627 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6628 return NULL;
6629 if (!_PyVerify_fd(fd))
6630 return PyBool_FromLong(0);
6631 return PyBool_FromLong(isatty(fd));
6634 #ifdef HAVE_PIPE
6635 PyDoc_STRVAR(posix_pipe__doc__,
6636 "pipe() -> (read_end, write_end)\n\n\
6637 Create a pipe.");
6639 static PyObject *
6640 posix_pipe(PyObject *self, PyObject *noargs)
6642 #if defined(PYOS_OS2)
6643 HFILE read, write;
6644 APIRET rc;
6646 Py_BEGIN_ALLOW_THREADS
6647 rc = DosCreatePipe( &read, &write, 4096);
6648 Py_END_ALLOW_THREADS
6649 if (rc != NO_ERROR)
6650 return os2_error(rc);
6652 return Py_BuildValue("(ii)", read, write);
6653 #else
6654 #if !defined(MS_WINDOWS)
6655 int fds[2];
6656 int res;
6657 Py_BEGIN_ALLOW_THREADS
6658 res = pipe(fds);
6659 Py_END_ALLOW_THREADS
6660 if (res != 0)
6661 return posix_error();
6662 return Py_BuildValue("(ii)", fds[0], fds[1]);
6663 #else /* MS_WINDOWS */
6664 HANDLE read, write;
6665 int read_fd, write_fd;
6666 BOOL ok;
6667 Py_BEGIN_ALLOW_THREADS
6668 ok = CreatePipe(&read, &write, NULL, 0);
6669 Py_END_ALLOW_THREADS
6670 if (!ok)
6671 return win32_error("CreatePipe", NULL);
6672 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6673 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6674 return Py_BuildValue("(ii)", read_fd, write_fd);
6675 #endif /* MS_WINDOWS */
6676 #endif
6678 #endif /* HAVE_PIPE */
6681 #ifdef HAVE_MKFIFO
6682 PyDoc_STRVAR(posix_mkfifo__doc__,
6683 "mkfifo(filename [, mode=0666])\n\n\
6684 Create a FIFO (a POSIX named pipe).");
6686 static PyObject *
6687 posix_mkfifo(PyObject *self, PyObject *args)
6689 char *filename;
6690 int mode = 0666;
6691 int res;
6692 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6693 return NULL;
6694 Py_BEGIN_ALLOW_THREADS
6695 res = mkfifo(filename, mode);
6696 Py_END_ALLOW_THREADS
6697 if (res < 0)
6698 return posix_error();
6699 Py_INCREF(Py_None);
6700 return Py_None;
6702 #endif
6705 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
6706 PyDoc_STRVAR(posix_mknod__doc__,
6707 "mknod(filename [, mode=0600, device])\n\n\
6708 Create a filesystem node (file, device special file or named pipe)\n\
6709 named filename. mode specifies both the permissions to use and the\n\
6710 type of node to be created, being combined (bitwise OR) with one of\n\
6711 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
6712 device defines the newly created device special file (probably using\n\
6713 os.makedev()), otherwise it is ignored.");
6716 static PyObject *
6717 posix_mknod(PyObject *self, PyObject *args)
6719 char *filename;
6720 int mode = 0600;
6721 int device = 0;
6722 int res;
6723 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6724 return NULL;
6725 Py_BEGIN_ALLOW_THREADS
6726 res = mknod(filename, mode, device);
6727 Py_END_ALLOW_THREADS
6728 if (res < 0)
6729 return posix_error();
6730 Py_INCREF(Py_None);
6731 return Py_None;
6733 #endif
6735 #ifdef HAVE_DEVICE_MACROS
6736 PyDoc_STRVAR(posix_major__doc__,
6737 "major(device) -> major number\n\
6738 Extracts a device major number from a raw device number.");
6740 static PyObject *
6741 posix_major(PyObject *self, PyObject *args)
6743 int device;
6744 if (!PyArg_ParseTuple(args, "i:major", &device))
6745 return NULL;
6746 return PyInt_FromLong((long)major(device));
6749 PyDoc_STRVAR(posix_minor__doc__,
6750 "minor(device) -> minor number\n\
6751 Extracts a device minor number from a raw device number.");
6753 static PyObject *
6754 posix_minor(PyObject *self, PyObject *args)
6756 int device;
6757 if (!PyArg_ParseTuple(args, "i:minor", &device))
6758 return NULL;
6759 return PyInt_FromLong((long)minor(device));
6762 PyDoc_STRVAR(posix_makedev__doc__,
6763 "makedev(major, minor) -> device number\n\
6764 Composes a raw device number from the major and minor device numbers.");
6766 static PyObject *
6767 posix_makedev(PyObject *self, PyObject *args)
6769 int major, minor;
6770 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6771 return NULL;
6772 return PyInt_FromLong((long)makedev(major, minor));
6774 #endif /* device macros */
6777 #ifdef HAVE_FTRUNCATE
6778 PyDoc_STRVAR(posix_ftruncate__doc__,
6779 "ftruncate(fd, length)\n\n\
6780 Truncate a file to a specified length.");
6782 static PyObject *
6783 posix_ftruncate(PyObject *self, PyObject *args)
6785 int fd;
6786 off_t length;
6787 int res;
6788 PyObject *lenobj;
6790 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6791 return NULL;
6793 #if !defined(HAVE_LARGEFILE_SUPPORT)
6794 length = PyInt_AsLong(lenobj);
6795 #else
6796 length = PyLong_Check(lenobj) ?
6797 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6798 #endif
6799 if (PyErr_Occurred())
6800 return NULL;
6802 Py_BEGIN_ALLOW_THREADS
6803 res = ftruncate(fd, length);
6804 Py_END_ALLOW_THREADS
6805 if (res < 0)
6806 return posix_error();
6807 Py_INCREF(Py_None);
6808 return Py_None;
6810 #endif
6812 #ifdef HAVE_PUTENV
6813 PyDoc_STRVAR(posix_putenv__doc__,
6814 "putenv(key, value)\n\n\
6815 Change or add an environment variable.");
6817 /* Save putenv() parameters as values here, so we can collect them when they
6818 * get re-set with another call for the same key. */
6819 static PyObject *posix_putenv_garbage;
6821 static PyObject *
6822 posix_putenv(PyObject *self, PyObject *args)
6824 char *s1, *s2;
6825 char *newenv;
6826 PyObject *newstr;
6827 size_t len;
6829 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6830 return NULL;
6832 #if defined(PYOS_OS2)
6833 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6834 APIRET rc;
6836 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6837 if (rc != NO_ERROR)
6838 return os2_error(rc);
6840 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6841 APIRET rc;
6843 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6844 if (rc != NO_ERROR)
6845 return os2_error(rc);
6846 } else {
6847 #endif
6849 /* XXX This can leak memory -- not easy to fix :-( */
6850 len = strlen(s1) + strlen(s2) + 2;
6851 /* len includes space for a trailing \0; the size arg to
6852 PyString_FromStringAndSize does not count that */
6853 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
6854 if (newstr == NULL)
6855 return PyErr_NoMemory();
6856 newenv = PyString_AS_STRING(newstr);
6857 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6858 if (putenv(newenv)) {
6859 Py_DECREF(newstr);
6860 posix_error();
6861 return NULL;
6863 /* Install the first arg and newstr in posix_putenv_garbage;
6864 * this will cause previous value to be collected. This has to
6865 * happen after the real putenv() call because the old value
6866 * was still accessible until then. */
6867 if (PyDict_SetItem(posix_putenv_garbage,
6868 PyTuple_GET_ITEM(args, 0), newstr)) {
6869 /* really not much we can do; just leak */
6870 PyErr_Clear();
6872 else {
6873 Py_DECREF(newstr);
6876 #if defined(PYOS_OS2)
6878 #endif
6879 Py_INCREF(Py_None);
6880 return Py_None;
6882 #endif /* putenv */
6884 #ifdef HAVE_UNSETENV
6885 PyDoc_STRVAR(posix_unsetenv__doc__,
6886 "unsetenv(key)\n\n\
6887 Delete an environment variable.");
6889 static PyObject *
6890 posix_unsetenv(PyObject *self, PyObject *args)
6892 char *s1;
6894 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6895 return NULL;
6897 unsetenv(s1);
6899 /* Remove the key from posix_putenv_garbage;
6900 * this will cause it to be collected. This has to
6901 * happen after the real unsetenv() call because the
6902 * old value was still accessible until then.
6904 if (PyDict_DelItem(posix_putenv_garbage,
6905 PyTuple_GET_ITEM(args, 0))) {
6906 /* really not much we can do; just leak */
6907 PyErr_Clear();
6910 Py_INCREF(Py_None);
6911 return Py_None;
6913 #endif /* unsetenv */
6915 PyDoc_STRVAR(posix_strerror__doc__,
6916 "strerror(code) -> string\n\n\
6917 Translate an error code to a message string.");
6919 static PyObject *
6920 posix_strerror(PyObject *self, PyObject *args)
6922 int code;
6923 char *message;
6924 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6925 return NULL;
6926 message = strerror(code);
6927 if (message == NULL) {
6928 PyErr_SetString(PyExc_ValueError,
6929 "strerror() argument out of range");
6930 return NULL;
6932 return PyString_FromString(message);
6936 #ifdef HAVE_SYS_WAIT_H
6938 #ifdef WCOREDUMP
6939 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
6940 "WCOREDUMP(status) -> bool\n\n\
6941 Return True if the process returning 'status' was dumped to a core file.");
6943 static PyObject *
6944 posix_WCOREDUMP(PyObject *self, PyObject *args)
6946 WAIT_TYPE status;
6947 WAIT_STATUS_INT(status) = 0;
6949 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6950 return NULL;
6952 return PyBool_FromLong(WCOREDUMP(status));
6954 #endif /* WCOREDUMP */
6956 #ifdef WIFCONTINUED
6957 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
6958 "WIFCONTINUED(status) -> bool\n\n\
6959 Return True if the process returning 'status' was continued from a\n\
6960 job control stop.");
6962 static PyObject *
6963 posix_WIFCONTINUED(PyObject *self, PyObject *args)
6965 WAIT_TYPE status;
6966 WAIT_STATUS_INT(status) = 0;
6968 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6969 return NULL;
6971 return PyBool_FromLong(WIFCONTINUED(status));
6973 #endif /* WIFCONTINUED */
6975 #ifdef WIFSTOPPED
6976 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
6977 "WIFSTOPPED(status) -> bool\n\n\
6978 Return True if the process returning 'status' was stopped.");
6980 static PyObject *
6981 posix_WIFSTOPPED(PyObject *self, PyObject *args)
6983 WAIT_TYPE status;
6984 WAIT_STATUS_INT(status) = 0;
6986 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6987 return NULL;
6989 return PyBool_FromLong(WIFSTOPPED(status));
6991 #endif /* WIFSTOPPED */
6993 #ifdef WIFSIGNALED
6994 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
6995 "WIFSIGNALED(status) -> bool\n\n\
6996 Return True if the process returning 'status' was terminated by a signal.");
6998 static PyObject *
6999 posix_WIFSIGNALED(PyObject *self, PyObject *args)
7001 WAIT_TYPE status;
7002 WAIT_STATUS_INT(status) = 0;
7004 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7005 return NULL;
7007 return PyBool_FromLong(WIFSIGNALED(status));
7009 #endif /* WIFSIGNALED */
7011 #ifdef WIFEXITED
7012 PyDoc_STRVAR(posix_WIFEXITED__doc__,
7013 "WIFEXITED(status) -> bool\n\n\
7014 Return true if the process returning 'status' exited using the exit()\n\
7015 system call.");
7017 static PyObject *
7018 posix_WIFEXITED(PyObject *self, PyObject *args)
7020 WAIT_TYPE status;
7021 WAIT_STATUS_INT(status) = 0;
7023 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7024 return NULL;
7026 return PyBool_FromLong(WIFEXITED(status));
7028 #endif /* WIFEXITED */
7030 #ifdef WEXITSTATUS
7031 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
7032 "WEXITSTATUS(status) -> integer\n\n\
7033 Return the process return code from 'status'.");
7035 static PyObject *
7036 posix_WEXITSTATUS(PyObject *self, PyObject *args)
7038 WAIT_TYPE status;
7039 WAIT_STATUS_INT(status) = 0;
7041 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7042 return NULL;
7044 return Py_BuildValue("i", WEXITSTATUS(status));
7046 #endif /* WEXITSTATUS */
7048 #ifdef WTERMSIG
7049 PyDoc_STRVAR(posix_WTERMSIG__doc__,
7050 "WTERMSIG(status) -> integer\n\n\
7051 Return the signal that terminated the process that provided the 'status'\n\
7052 value.");
7054 static PyObject *
7055 posix_WTERMSIG(PyObject *self, PyObject *args)
7057 WAIT_TYPE status;
7058 WAIT_STATUS_INT(status) = 0;
7060 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7061 return NULL;
7063 return Py_BuildValue("i", WTERMSIG(status));
7065 #endif /* WTERMSIG */
7067 #ifdef WSTOPSIG
7068 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
7069 "WSTOPSIG(status) -> integer\n\n\
7070 Return the signal that stopped the process that provided\n\
7071 the 'status' value.");
7073 static PyObject *
7074 posix_WSTOPSIG(PyObject *self, PyObject *args)
7076 WAIT_TYPE status;
7077 WAIT_STATUS_INT(status) = 0;
7079 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7080 return NULL;
7082 return Py_BuildValue("i", WSTOPSIG(status));
7084 #endif /* WSTOPSIG */
7086 #endif /* HAVE_SYS_WAIT_H */
7089 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
7090 #ifdef _SCO_DS
7091 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7092 needed definitions in sys/statvfs.h */
7093 #define _SVID3
7094 #endif
7095 #include <sys/statvfs.h>
7097 static PyObject*
7098 _pystatvfs_fromstructstatvfs(struct statvfs st) {
7099 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7100 if (v == NULL)
7101 return NULL;
7103 #if !defined(HAVE_LARGEFILE_SUPPORT)
7104 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7105 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7106 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7107 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7108 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7109 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7110 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7111 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((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 #else
7115 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7116 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7117 PyStructSequence_SET_ITEM(v, 2,
7118 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7119 PyStructSequence_SET_ITEM(v, 3,
7120 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7121 PyStructSequence_SET_ITEM(v, 4,
7122 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7123 PyStructSequence_SET_ITEM(v, 5,
7124 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7125 PyStructSequence_SET_ITEM(v, 6,
7126 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7127 PyStructSequence_SET_ITEM(v, 7,
7128 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7129 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7130 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
7131 #endif
7133 return v;
7136 PyDoc_STRVAR(posix_fstatvfs__doc__,
7137 "fstatvfs(fd) -> statvfs result\n\n\
7138 Perform an fstatvfs system call on the given fd.");
7140 static PyObject *
7141 posix_fstatvfs(PyObject *self, PyObject *args)
7143 int fd, res;
7144 struct statvfs st;
7146 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7147 return NULL;
7148 Py_BEGIN_ALLOW_THREADS
7149 res = fstatvfs(fd, &st);
7150 Py_END_ALLOW_THREADS
7151 if (res != 0)
7152 return posix_error();
7154 return _pystatvfs_fromstructstatvfs(st);
7156 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
7159 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
7160 #include <sys/statvfs.h>
7162 PyDoc_STRVAR(posix_statvfs__doc__,
7163 "statvfs(path) -> statvfs result\n\n\
7164 Perform a statvfs system call on the given path.");
7166 static PyObject *
7167 posix_statvfs(PyObject *self, PyObject *args)
7169 char *path;
7170 int res;
7171 struct statvfs st;
7172 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7173 return NULL;
7174 Py_BEGIN_ALLOW_THREADS
7175 res = statvfs(path, &st);
7176 Py_END_ALLOW_THREADS
7177 if (res != 0)
7178 return posix_error_with_filename(path);
7180 return _pystatvfs_fromstructstatvfs(st);
7182 #endif /* HAVE_STATVFS */
7185 #ifdef HAVE_TEMPNAM
7186 PyDoc_STRVAR(posix_tempnam__doc__,
7187 "tempnam([dir[, prefix]]) -> string\n\n\
7188 Return a unique name for a temporary file.\n\
7189 The directory and a prefix may be specified as strings; they may be omitted\n\
7190 or None if not needed.");
7192 static PyObject *
7193 posix_tempnam(PyObject *self, PyObject *args)
7195 PyObject *result = NULL;
7196 char *dir = NULL;
7197 char *pfx = NULL;
7198 char *name;
7200 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7201 return NULL;
7203 if (PyErr_Warn(PyExc_RuntimeWarning,
7204 "tempnam is a potential security risk to your program") < 0)
7205 return NULL;
7207 #ifdef MS_WINDOWS
7208 name = _tempnam(dir, pfx);
7209 #else
7210 name = tempnam(dir, pfx);
7211 #endif
7212 if (name == NULL)
7213 return PyErr_NoMemory();
7214 result = PyString_FromString(name);
7215 free(name);
7216 return result;
7218 #endif
7221 #ifdef HAVE_TMPFILE
7222 PyDoc_STRVAR(posix_tmpfile__doc__,
7223 "tmpfile() -> file object\n\n\
7224 Create a temporary file with no directory entries.");
7226 static PyObject *
7227 posix_tmpfile(PyObject *self, PyObject *noargs)
7229 FILE *fp;
7231 fp = tmpfile();
7232 if (fp == NULL)
7233 return posix_error();
7234 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
7236 #endif
7239 #ifdef HAVE_TMPNAM
7240 PyDoc_STRVAR(posix_tmpnam__doc__,
7241 "tmpnam() -> string\n\n\
7242 Return a unique name for a temporary file.");
7244 static PyObject *
7245 posix_tmpnam(PyObject *self, PyObject *noargs)
7247 char buffer[L_tmpnam];
7248 char *name;
7250 if (PyErr_Warn(PyExc_RuntimeWarning,
7251 "tmpnam is a potential security risk to your program") < 0)
7252 return NULL;
7254 #ifdef USE_TMPNAM_R
7255 name = tmpnam_r(buffer);
7256 #else
7257 name = tmpnam(buffer);
7258 #endif
7259 if (name == NULL) {
7260 PyObject *err = Py_BuildValue("is", 0,
7261 #ifdef USE_TMPNAM_R
7262 "unexpected NULL from tmpnam_r"
7263 #else
7264 "unexpected NULL from tmpnam"
7265 #endif
7267 PyErr_SetObject(PyExc_OSError, err);
7268 Py_XDECREF(err);
7269 return NULL;
7271 return PyString_FromString(buffer);
7273 #endif
7276 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7277 * It maps strings representing configuration variable names to
7278 * integer values, allowing those functions to be called with the
7279 * magic names instead of polluting the module's namespace with tons of
7280 * rarely-used constants. There are three separate tables that use
7281 * these definitions.
7283 * This code is always included, even if none of the interfaces that
7284 * need it are included. The #if hackery needed to avoid it would be
7285 * sufficiently pervasive that it's not worth the loss of readability.
7287 struct constdef {
7288 char *name;
7289 long value;
7292 static int
7293 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7294 size_t tablesize)
7296 if (PyInt_Check(arg)) {
7297 *valuep = PyInt_AS_LONG(arg);
7298 return 1;
7300 if (PyString_Check(arg)) {
7301 /* look up the value in the table using a binary search */
7302 size_t lo = 0;
7303 size_t mid;
7304 size_t hi = tablesize;
7305 int cmp;
7306 char *confname = PyString_AS_STRING(arg);
7307 while (lo < hi) {
7308 mid = (lo + hi) / 2;
7309 cmp = strcmp(confname, table[mid].name);
7310 if (cmp < 0)
7311 hi = mid;
7312 else if (cmp > 0)
7313 lo = mid + 1;
7314 else {
7315 *valuep = table[mid].value;
7316 return 1;
7319 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7321 else
7322 PyErr_SetString(PyExc_TypeError,
7323 "configuration names must be strings or integers");
7324 return 0;
7328 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7329 static struct constdef posix_constants_pathconf[] = {
7330 #ifdef _PC_ABI_AIO_XFER_MAX
7331 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7332 #endif
7333 #ifdef _PC_ABI_ASYNC_IO
7334 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7335 #endif
7336 #ifdef _PC_ASYNC_IO
7337 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7338 #endif
7339 #ifdef _PC_CHOWN_RESTRICTED
7340 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7341 #endif
7342 #ifdef _PC_FILESIZEBITS
7343 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7344 #endif
7345 #ifdef _PC_LAST
7346 {"PC_LAST", _PC_LAST},
7347 #endif
7348 #ifdef _PC_LINK_MAX
7349 {"PC_LINK_MAX", _PC_LINK_MAX},
7350 #endif
7351 #ifdef _PC_MAX_CANON
7352 {"PC_MAX_CANON", _PC_MAX_CANON},
7353 #endif
7354 #ifdef _PC_MAX_INPUT
7355 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7356 #endif
7357 #ifdef _PC_NAME_MAX
7358 {"PC_NAME_MAX", _PC_NAME_MAX},
7359 #endif
7360 #ifdef _PC_NO_TRUNC
7361 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7362 #endif
7363 #ifdef _PC_PATH_MAX
7364 {"PC_PATH_MAX", _PC_PATH_MAX},
7365 #endif
7366 #ifdef _PC_PIPE_BUF
7367 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7368 #endif
7369 #ifdef _PC_PRIO_IO
7370 {"PC_PRIO_IO", _PC_PRIO_IO},
7371 #endif
7372 #ifdef _PC_SOCK_MAXBUF
7373 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7374 #endif
7375 #ifdef _PC_SYNC_IO
7376 {"PC_SYNC_IO", _PC_SYNC_IO},
7377 #endif
7378 #ifdef _PC_VDISABLE
7379 {"PC_VDISABLE", _PC_VDISABLE},
7380 #endif
7383 static int
7384 conv_path_confname(PyObject *arg, int *valuep)
7386 return conv_confname(arg, valuep, posix_constants_pathconf,
7387 sizeof(posix_constants_pathconf)
7388 / sizeof(struct constdef));
7390 #endif
7392 #ifdef HAVE_FPATHCONF
7393 PyDoc_STRVAR(posix_fpathconf__doc__,
7394 "fpathconf(fd, name) -> integer\n\n\
7395 Return the configuration limit name for the file descriptor fd.\n\
7396 If there is no limit, return -1.");
7398 static PyObject *
7399 posix_fpathconf(PyObject *self, PyObject *args)
7401 PyObject *result = NULL;
7402 int name, fd;
7404 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7405 conv_path_confname, &name)) {
7406 long limit;
7408 errno = 0;
7409 limit = fpathconf(fd, name);
7410 if (limit == -1 && errno != 0)
7411 posix_error();
7412 else
7413 result = PyInt_FromLong(limit);
7415 return result;
7417 #endif
7420 #ifdef HAVE_PATHCONF
7421 PyDoc_STRVAR(posix_pathconf__doc__,
7422 "pathconf(path, name) -> integer\n\n\
7423 Return the configuration limit name for the file or directory path.\n\
7424 If there is no limit, return -1.");
7426 static PyObject *
7427 posix_pathconf(PyObject *self, PyObject *args)
7429 PyObject *result = NULL;
7430 int name;
7431 char *path;
7433 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7434 conv_path_confname, &name)) {
7435 long limit;
7437 errno = 0;
7438 limit = pathconf(path, name);
7439 if (limit == -1 && errno != 0) {
7440 if (errno == EINVAL)
7441 /* could be a path or name problem */
7442 posix_error();
7443 else
7444 posix_error_with_filename(path);
7446 else
7447 result = PyInt_FromLong(limit);
7449 return result;
7451 #endif
7453 #ifdef HAVE_CONFSTR
7454 static struct constdef posix_constants_confstr[] = {
7455 #ifdef _CS_ARCHITECTURE
7456 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7457 #endif
7458 #ifdef _CS_HOSTNAME
7459 {"CS_HOSTNAME", _CS_HOSTNAME},
7460 #endif
7461 #ifdef _CS_HW_PROVIDER
7462 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7463 #endif
7464 #ifdef _CS_HW_SERIAL
7465 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7466 #endif
7467 #ifdef _CS_INITTAB_NAME
7468 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7469 #endif
7470 #ifdef _CS_LFS64_CFLAGS
7471 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7472 #endif
7473 #ifdef _CS_LFS64_LDFLAGS
7474 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7475 #endif
7476 #ifdef _CS_LFS64_LIBS
7477 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7478 #endif
7479 #ifdef _CS_LFS64_LINTFLAGS
7480 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7481 #endif
7482 #ifdef _CS_LFS_CFLAGS
7483 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7484 #endif
7485 #ifdef _CS_LFS_LDFLAGS
7486 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7487 #endif
7488 #ifdef _CS_LFS_LIBS
7489 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7490 #endif
7491 #ifdef _CS_LFS_LINTFLAGS
7492 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7493 #endif
7494 #ifdef _CS_MACHINE
7495 {"CS_MACHINE", _CS_MACHINE},
7496 #endif
7497 #ifdef _CS_PATH
7498 {"CS_PATH", _CS_PATH},
7499 #endif
7500 #ifdef _CS_RELEASE
7501 {"CS_RELEASE", _CS_RELEASE},
7502 #endif
7503 #ifdef _CS_SRPC_DOMAIN
7504 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7505 #endif
7506 #ifdef _CS_SYSNAME
7507 {"CS_SYSNAME", _CS_SYSNAME},
7508 #endif
7509 #ifdef _CS_VERSION
7510 {"CS_VERSION", _CS_VERSION},
7511 #endif
7512 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7513 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7514 #endif
7515 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7516 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7517 #endif
7518 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
7519 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7520 #endif
7521 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7522 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7523 #endif
7524 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7525 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7526 #endif
7527 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7528 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7529 #endif
7530 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7531 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7532 #endif
7533 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7534 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7535 #endif
7536 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7537 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7538 #endif
7539 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7540 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7541 #endif
7542 #ifdef _CS_XBS5_LP64_OFF64_LIBS
7543 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7544 #endif
7545 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7546 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7547 #endif
7548 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7549 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7550 #endif
7551 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7552 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7553 #endif
7554 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7555 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7556 #endif
7557 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7558 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7559 #endif
7560 #ifdef _MIPS_CS_AVAIL_PROCESSORS
7561 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7562 #endif
7563 #ifdef _MIPS_CS_BASE
7564 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7565 #endif
7566 #ifdef _MIPS_CS_HOSTID
7567 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7568 #endif
7569 #ifdef _MIPS_CS_HW_NAME
7570 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7571 #endif
7572 #ifdef _MIPS_CS_NUM_PROCESSORS
7573 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7574 #endif
7575 #ifdef _MIPS_CS_OSREL_MAJ
7576 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7577 #endif
7578 #ifdef _MIPS_CS_OSREL_MIN
7579 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7580 #endif
7581 #ifdef _MIPS_CS_OSREL_PATCH
7582 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7583 #endif
7584 #ifdef _MIPS_CS_OS_NAME
7585 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7586 #endif
7587 #ifdef _MIPS_CS_OS_PROVIDER
7588 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7589 #endif
7590 #ifdef _MIPS_CS_PROCESSORS
7591 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7592 #endif
7593 #ifdef _MIPS_CS_SERIAL
7594 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7595 #endif
7596 #ifdef _MIPS_CS_VENDOR
7597 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7598 #endif
7601 static int
7602 conv_confstr_confname(PyObject *arg, int *valuep)
7604 return conv_confname(arg, valuep, posix_constants_confstr,
7605 sizeof(posix_constants_confstr)
7606 / sizeof(struct constdef));
7609 PyDoc_STRVAR(posix_confstr__doc__,
7610 "confstr(name) -> string\n\n\
7611 Return a string-valued system configuration variable.");
7613 static PyObject *
7614 posix_confstr(PyObject *self, PyObject *args)
7616 PyObject *result = NULL;
7617 int name;
7618 char buffer[256];
7620 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
7621 int len;
7623 errno = 0;
7624 len = confstr(name, buffer, sizeof(buffer));
7625 if (len == 0) {
7626 if (errno) {
7627 posix_error();
7629 else {
7630 result = Py_None;
7631 Py_INCREF(Py_None);
7634 else {
7635 if ((unsigned int)len >= sizeof(buffer)) {
7636 result = PyString_FromStringAndSize(NULL, len-1);
7637 if (result != NULL)
7638 confstr(name, PyString_AS_STRING(result), len);
7640 else
7641 result = PyString_FromStringAndSize(buffer, len-1);
7644 return result;
7646 #endif
7649 #ifdef HAVE_SYSCONF
7650 static struct constdef posix_constants_sysconf[] = {
7651 #ifdef _SC_2_CHAR_TERM
7652 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7653 #endif
7654 #ifdef _SC_2_C_BIND
7655 {"SC_2_C_BIND", _SC_2_C_BIND},
7656 #endif
7657 #ifdef _SC_2_C_DEV
7658 {"SC_2_C_DEV", _SC_2_C_DEV},
7659 #endif
7660 #ifdef _SC_2_C_VERSION
7661 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7662 #endif
7663 #ifdef _SC_2_FORT_DEV
7664 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7665 #endif
7666 #ifdef _SC_2_FORT_RUN
7667 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7668 #endif
7669 #ifdef _SC_2_LOCALEDEF
7670 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7671 #endif
7672 #ifdef _SC_2_SW_DEV
7673 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7674 #endif
7675 #ifdef _SC_2_UPE
7676 {"SC_2_UPE", _SC_2_UPE},
7677 #endif
7678 #ifdef _SC_2_VERSION
7679 {"SC_2_VERSION", _SC_2_VERSION},
7680 #endif
7681 #ifdef _SC_ABI_ASYNCHRONOUS_IO
7682 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7683 #endif
7684 #ifdef _SC_ACL
7685 {"SC_ACL", _SC_ACL},
7686 #endif
7687 #ifdef _SC_AIO_LISTIO_MAX
7688 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7689 #endif
7690 #ifdef _SC_AIO_MAX
7691 {"SC_AIO_MAX", _SC_AIO_MAX},
7692 #endif
7693 #ifdef _SC_AIO_PRIO_DELTA_MAX
7694 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7695 #endif
7696 #ifdef _SC_ARG_MAX
7697 {"SC_ARG_MAX", _SC_ARG_MAX},
7698 #endif
7699 #ifdef _SC_ASYNCHRONOUS_IO
7700 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7701 #endif
7702 #ifdef _SC_ATEXIT_MAX
7703 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7704 #endif
7705 #ifdef _SC_AUDIT
7706 {"SC_AUDIT", _SC_AUDIT},
7707 #endif
7708 #ifdef _SC_AVPHYS_PAGES
7709 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7710 #endif
7711 #ifdef _SC_BC_BASE_MAX
7712 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7713 #endif
7714 #ifdef _SC_BC_DIM_MAX
7715 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7716 #endif
7717 #ifdef _SC_BC_SCALE_MAX
7718 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7719 #endif
7720 #ifdef _SC_BC_STRING_MAX
7721 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7722 #endif
7723 #ifdef _SC_CAP
7724 {"SC_CAP", _SC_CAP},
7725 #endif
7726 #ifdef _SC_CHARCLASS_NAME_MAX
7727 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7728 #endif
7729 #ifdef _SC_CHAR_BIT
7730 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7731 #endif
7732 #ifdef _SC_CHAR_MAX
7733 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7734 #endif
7735 #ifdef _SC_CHAR_MIN
7736 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7737 #endif
7738 #ifdef _SC_CHILD_MAX
7739 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7740 #endif
7741 #ifdef _SC_CLK_TCK
7742 {"SC_CLK_TCK", _SC_CLK_TCK},
7743 #endif
7744 #ifdef _SC_COHER_BLKSZ
7745 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7746 #endif
7747 #ifdef _SC_COLL_WEIGHTS_MAX
7748 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7749 #endif
7750 #ifdef _SC_DCACHE_ASSOC
7751 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7752 #endif
7753 #ifdef _SC_DCACHE_BLKSZ
7754 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7755 #endif
7756 #ifdef _SC_DCACHE_LINESZ
7757 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7758 #endif
7759 #ifdef _SC_DCACHE_SZ
7760 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7761 #endif
7762 #ifdef _SC_DCACHE_TBLKSZ
7763 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7764 #endif
7765 #ifdef _SC_DELAYTIMER_MAX
7766 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7767 #endif
7768 #ifdef _SC_EQUIV_CLASS_MAX
7769 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7770 #endif
7771 #ifdef _SC_EXPR_NEST_MAX
7772 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7773 #endif
7774 #ifdef _SC_FSYNC
7775 {"SC_FSYNC", _SC_FSYNC},
7776 #endif
7777 #ifdef _SC_GETGR_R_SIZE_MAX
7778 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7779 #endif
7780 #ifdef _SC_GETPW_R_SIZE_MAX
7781 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7782 #endif
7783 #ifdef _SC_ICACHE_ASSOC
7784 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7785 #endif
7786 #ifdef _SC_ICACHE_BLKSZ
7787 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7788 #endif
7789 #ifdef _SC_ICACHE_LINESZ
7790 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7791 #endif
7792 #ifdef _SC_ICACHE_SZ
7793 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7794 #endif
7795 #ifdef _SC_INF
7796 {"SC_INF", _SC_INF},
7797 #endif
7798 #ifdef _SC_INT_MAX
7799 {"SC_INT_MAX", _SC_INT_MAX},
7800 #endif
7801 #ifdef _SC_INT_MIN
7802 {"SC_INT_MIN", _SC_INT_MIN},
7803 #endif
7804 #ifdef _SC_IOV_MAX
7805 {"SC_IOV_MAX", _SC_IOV_MAX},
7806 #endif
7807 #ifdef _SC_IP_SECOPTS
7808 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7809 #endif
7810 #ifdef _SC_JOB_CONTROL
7811 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7812 #endif
7813 #ifdef _SC_KERN_POINTERS
7814 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7815 #endif
7816 #ifdef _SC_KERN_SIM
7817 {"SC_KERN_SIM", _SC_KERN_SIM},
7818 #endif
7819 #ifdef _SC_LINE_MAX
7820 {"SC_LINE_MAX", _SC_LINE_MAX},
7821 #endif
7822 #ifdef _SC_LOGIN_NAME_MAX
7823 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7824 #endif
7825 #ifdef _SC_LOGNAME_MAX
7826 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7827 #endif
7828 #ifdef _SC_LONG_BIT
7829 {"SC_LONG_BIT", _SC_LONG_BIT},
7830 #endif
7831 #ifdef _SC_MAC
7832 {"SC_MAC", _SC_MAC},
7833 #endif
7834 #ifdef _SC_MAPPED_FILES
7835 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7836 #endif
7837 #ifdef _SC_MAXPID
7838 {"SC_MAXPID", _SC_MAXPID},
7839 #endif
7840 #ifdef _SC_MB_LEN_MAX
7841 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7842 #endif
7843 #ifdef _SC_MEMLOCK
7844 {"SC_MEMLOCK", _SC_MEMLOCK},
7845 #endif
7846 #ifdef _SC_MEMLOCK_RANGE
7847 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7848 #endif
7849 #ifdef _SC_MEMORY_PROTECTION
7850 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7851 #endif
7852 #ifdef _SC_MESSAGE_PASSING
7853 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7854 #endif
7855 #ifdef _SC_MMAP_FIXED_ALIGNMENT
7856 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7857 #endif
7858 #ifdef _SC_MQ_OPEN_MAX
7859 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7860 #endif
7861 #ifdef _SC_MQ_PRIO_MAX
7862 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7863 #endif
7864 #ifdef _SC_NACLS_MAX
7865 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7866 #endif
7867 #ifdef _SC_NGROUPS_MAX
7868 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7869 #endif
7870 #ifdef _SC_NL_ARGMAX
7871 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7872 #endif
7873 #ifdef _SC_NL_LANGMAX
7874 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7875 #endif
7876 #ifdef _SC_NL_MSGMAX
7877 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7878 #endif
7879 #ifdef _SC_NL_NMAX
7880 {"SC_NL_NMAX", _SC_NL_NMAX},
7881 #endif
7882 #ifdef _SC_NL_SETMAX
7883 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7884 #endif
7885 #ifdef _SC_NL_TEXTMAX
7886 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7887 #endif
7888 #ifdef _SC_NPROCESSORS_CONF
7889 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7890 #endif
7891 #ifdef _SC_NPROCESSORS_ONLN
7892 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7893 #endif
7894 #ifdef _SC_NPROC_CONF
7895 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7896 #endif
7897 #ifdef _SC_NPROC_ONLN
7898 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7899 #endif
7900 #ifdef _SC_NZERO
7901 {"SC_NZERO", _SC_NZERO},
7902 #endif
7903 #ifdef _SC_OPEN_MAX
7904 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7905 #endif
7906 #ifdef _SC_PAGESIZE
7907 {"SC_PAGESIZE", _SC_PAGESIZE},
7908 #endif
7909 #ifdef _SC_PAGE_SIZE
7910 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7911 #endif
7912 #ifdef _SC_PASS_MAX
7913 {"SC_PASS_MAX", _SC_PASS_MAX},
7914 #endif
7915 #ifdef _SC_PHYS_PAGES
7916 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7917 #endif
7918 #ifdef _SC_PII
7919 {"SC_PII", _SC_PII},
7920 #endif
7921 #ifdef _SC_PII_INTERNET
7922 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7923 #endif
7924 #ifdef _SC_PII_INTERNET_DGRAM
7925 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7926 #endif
7927 #ifdef _SC_PII_INTERNET_STREAM
7928 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7929 #endif
7930 #ifdef _SC_PII_OSI
7931 {"SC_PII_OSI", _SC_PII_OSI},
7932 #endif
7933 #ifdef _SC_PII_OSI_CLTS
7934 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7935 #endif
7936 #ifdef _SC_PII_OSI_COTS
7937 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7938 #endif
7939 #ifdef _SC_PII_OSI_M
7940 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7941 #endif
7942 #ifdef _SC_PII_SOCKET
7943 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7944 #endif
7945 #ifdef _SC_PII_XTI
7946 {"SC_PII_XTI", _SC_PII_XTI},
7947 #endif
7948 #ifdef _SC_POLL
7949 {"SC_POLL", _SC_POLL},
7950 #endif
7951 #ifdef _SC_PRIORITIZED_IO
7952 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7953 #endif
7954 #ifdef _SC_PRIORITY_SCHEDULING
7955 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7956 #endif
7957 #ifdef _SC_REALTIME_SIGNALS
7958 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7959 #endif
7960 #ifdef _SC_RE_DUP_MAX
7961 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7962 #endif
7963 #ifdef _SC_RTSIG_MAX
7964 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7965 #endif
7966 #ifdef _SC_SAVED_IDS
7967 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7968 #endif
7969 #ifdef _SC_SCHAR_MAX
7970 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7971 #endif
7972 #ifdef _SC_SCHAR_MIN
7973 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7974 #endif
7975 #ifdef _SC_SELECT
7976 {"SC_SELECT", _SC_SELECT},
7977 #endif
7978 #ifdef _SC_SEMAPHORES
7979 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7980 #endif
7981 #ifdef _SC_SEM_NSEMS_MAX
7982 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7983 #endif
7984 #ifdef _SC_SEM_VALUE_MAX
7985 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7986 #endif
7987 #ifdef _SC_SHARED_MEMORY_OBJECTS
7988 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7989 #endif
7990 #ifdef _SC_SHRT_MAX
7991 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7992 #endif
7993 #ifdef _SC_SHRT_MIN
7994 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7995 #endif
7996 #ifdef _SC_SIGQUEUE_MAX
7997 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7998 #endif
7999 #ifdef _SC_SIGRT_MAX
8000 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
8001 #endif
8002 #ifdef _SC_SIGRT_MIN
8003 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
8004 #endif
8005 #ifdef _SC_SOFTPOWER
8006 {"SC_SOFTPOWER", _SC_SOFTPOWER},
8007 #endif
8008 #ifdef _SC_SPLIT_CACHE
8009 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
8010 #endif
8011 #ifdef _SC_SSIZE_MAX
8012 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
8013 #endif
8014 #ifdef _SC_STACK_PROT
8015 {"SC_STACK_PROT", _SC_STACK_PROT},
8016 #endif
8017 #ifdef _SC_STREAM_MAX
8018 {"SC_STREAM_MAX", _SC_STREAM_MAX},
8019 #endif
8020 #ifdef _SC_SYNCHRONIZED_IO
8021 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
8022 #endif
8023 #ifdef _SC_THREADS
8024 {"SC_THREADS", _SC_THREADS},
8025 #endif
8026 #ifdef _SC_THREAD_ATTR_STACKADDR
8027 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
8028 #endif
8029 #ifdef _SC_THREAD_ATTR_STACKSIZE
8030 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
8031 #endif
8032 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
8033 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
8034 #endif
8035 #ifdef _SC_THREAD_KEYS_MAX
8036 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
8037 #endif
8038 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
8039 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
8040 #endif
8041 #ifdef _SC_THREAD_PRIO_INHERIT
8042 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
8043 #endif
8044 #ifdef _SC_THREAD_PRIO_PROTECT
8045 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
8046 #endif
8047 #ifdef _SC_THREAD_PROCESS_SHARED
8048 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
8049 #endif
8050 #ifdef _SC_THREAD_SAFE_FUNCTIONS
8051 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
8052 #endif
8053 #ifdef _SC_THREAD_STACK_MIN
8054 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
8055 #endif
8056 #ifdef _SC_THREAD_THREADS_MAX
8057 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
8058 #endif
8059 #ifdef _SC_TIMERS
8060 {"SC_TIMERS", _SC_TIMERS},
8061 #endif
8062 #ifdef _SC_TIMER_MAX
8063 {"SC_TIMER_MAX", _SC_TIMER_MAX},
8064 #endif
8065 #ifdef _SC_TTY_NAME_MAX
8066 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
8067 #endif
8068 #ifdef _SC_TZNAME_MAX
8069 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
8070 #endif
8071 #ifdef _SC_T_IOV_MAX
8072 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
8073 #endif
8074 #ifdef _SC_UCHAR_MAX
8075 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
8076 #endif
8077 #ifdef _SC_UINT_MAX
8078 {"SC_UINT_MAX", _SC_UINT_MAX},
8079 #endif
8080 #ifdef _SC_UIO_MAXIOV
8081 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
8082 #endif
8083 #ifdef _SC_ULONG_MAX
8084 {"SC_ULONG_MAX", _SC_ULONG_MAX},
8085 #endif
8086 #ifdef _SC_USHRT_MAX
8087 {"SC_USHRT_MAX", _SC_USHRT_MAX},
8088 #endif
8089 #ifdef _SC_VERSION
8090 {"SC_VERSION", _SC_VERSION},
8091 #endif
8092 #ifdef _SC_WORD_BIT
8093 {"SC_WORD_BIT", _SC_WORD_BIT},
8094 #endif
8095 #ifdef _SC_XBS5_ILP32_OFF32
8096 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
8097 #endif
8098 #ifdef _SC_XBS5_ILP32_OFFBIG
8099 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
8100 #endif
8101 #ifdef _SC_XBS5_LP64_OFF64
8102 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
8103 #endif
8104 #ifdef _SC_XBS5_LPBIG_OFFBIG
8105 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
8106 #endif
8107 #ifdef _SC_XOPEN_CRYPT
8108 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
8109 #endif
8110 #ifdef _SC_XOPEN_ENH_I18N
8111 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
8112 #endif
8113 #ifdef _SC_XOPEN_LEGACY
8114 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
8115 #endif
8116 #ifdef _SC_XOPEN_REALTIME
8117 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
8118 #endif
8119 #ifdef _SC_XOPEN_REALTIME_THREADS
8120 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
8121 #endif
8122 #ifdef _SC_XOPEN_SHM
8123 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
8124 #endif
8125 #ifdef _SC_XOPEN_UNIX
8126 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
8127 #endif
8128 #ifdef _SC_XOPEN_VERSION
8129 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
8130 #endif
8131 #ifdef _SC_XOPEN_XCU_VERSION
8132 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
8133 #endif
8134 #ifdef _SC_XOPEN_XPG2
8135 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
8136 #endif
8137 #ifdef _SC_XOPEN_XPG3
8138 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
8139 #endif
8140 #ifdef _SC_XOPEN_XPG4
8141 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
8142 #endif
8145 static int
8146 conv_sysconf_confname(PyObject *arg, int *valuep)
8148 return conv_confname(arg, valuep, posix_constants_sysconf,
8149 sizeof(posix_constants_sysconf)
8150 / sizeof(struct constdef));
8153 PyDoc_STRVAR(posix_sysconf__doc__,
8154 "sysconf(name) -> integer\n\n\
8155 Return an integer-valued system configuration variable.");
8157 static PyObject *
8158 posix_sysconf(PyObject *self, PyObject *args)
8160 PyObject *result = NULL;
8161 int name;
8163 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
8164 int value;
8166 errno = 0;
8167 value = sysconf(name);
8168 if (value == -1 && errno != 0)
8169 posix_error();
8170 else
8171 result = PyInt_FromLong(value);
8173 return result;
8175 #endif
8178 /* This code is used to ensure that the tables of configuration value names
8179 * are in sorted order as required by conv_confname(), and also to build the
8180 * the exported dictionaries that are used to publish information about the
8181 * names available on the host platform.
8183 * Sorting the table at runtime ensures that the table is properly ordered
8184 * when used, even for platforms we're not able to test on. It also makes
8185 * it easier to add additional entries to the tables.
8188 static int
8189 cmp_constdefs(const void *v1, const void *v2)
8191 const struct constdef *c1 =
8192 (const struct constdef *) v1;
8193 const struct constdef *c2 =
8194 (const struct constdef *) v2;
8196 return strcmp(c1->name, c2->name);
8199 static int
8200 setup_confname_table(struct constdef *table, size_t tablesize,
8201 char *tablename, PyObject *module)
8203 PyObject *d = NULL;
8204 size_t i;
8206 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8207 d = PyDict_New();
8208 if (d == NULL)
8209 return -1;
8211 for (i=0; i < tablesize; ++i) {
8212 PyObject *o = PyInt_FromLong(table[i].value);
8213 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8214 Py_XDECREF(o);
8215 Py_DECREF(d);
8216 return -1;
8218 Py_DECREF(o);
8220 return PyModule_AddObject(module, tablename, d);
8223 /* Return -1 on failure, 0 on success. */
8224 static int
8225 setup_confname_tables(PyObject *module)
8227 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8228 if (setup_confname_table(posix_constants_pathconf,
8229 sizeof(posix_constants_pathconf)
8230 / sizeof(struct constdef),
8231 "pathconf_names", module))
8232 return -1;
8233 #endif
8234 #ifdef HAVE_CONFSTR
8235 if (setup_confname_table(posix_constants_confstr,
8236 sizeof(posix_constants_confstr)
8237 / sizeof(struct constdef),
8238 "confstr_names", module))
8239 return -1;
8240 #endif
8241 #ifdef HAVE_SYSCONF
8242 if (setup_confname_table(posix_constants_sysconf,
8243 sizeof(posix_constants_sysconf)
8244 / sizeof(struct constdef),
8245 "sysconf_names", module))
8246 return -1;
8247 #endif
8248 return 0;
8252 PyDoc_STRVAR(posix_abort__doc__,
8253 "abort() -> does not return!\n\n\
8254 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
8255 in the hardest way possible on the hosting operating system.");
8257 static PyObject *
8258 posix_abort(PyObject *self, PyObject *noargs)
8260 abort();
8261 /*NOTREACHED*/
8262 Py_FatalError("abort() called from Python code didn't abort!");
8263 return NULL;
8266 #ifdef MS_WINDOWS
8267 PyDoc_STRVAR(win32_startfile__doc__,
8268 "startfile(filepath [, operation]) - Start a file with its associated\n\
8269 application.\n\
8271 When \"operation\" is not specified or \"open\", this acts like\n\
8272 double-clicking the file in Explorer, or giving the file name as an\n\
8273 argument to the DOS \"start\" command: the file is opened with whatever\n\
8274 application (if any) its extension is associated.\n\
8275 When another \"operation\" is given, it specifies what should be done with\n\
8276 the file. A typical operation is \"print\".\n\
8278 startfile returns as soon as the associated application is launched.\n\
8279 There is no option to wait for the application to close, and no way\n\
8280 to retrieve the application's exit status.\n\
8282 The filepath is relative to the current directory. If you want to use\n\
8283 an absolute path, make sure the first character is not a slash (\"/\");\n\
8284 the underlying Win32 ShellExecute function doesn't work if it is.");
8286 static PyObject *
8287 win32_startfile(PyObject *self, PyObject *args)
8289 char *filepath;
8290 char *operation = NULL;
8291 HINSTANCE rc;
8293 if (unicode_file_names()) {
8294 PyObject *unipath, *woperation = NULL;
8295 if (!PyArg_ParseTuple(args, "U|s:startfile",
8296 &unipath, &operation)) {
8297 PyErr_Clear();
8298 goto normal;
8302 if (operation) {
8303 woperation = PyUnicode_DecodeASCII(operation,
8304 strlen(operation), NULL);
8305 if (!woperation) {
8306 PyErr_Clear();
8307 operation = NULL;
8308 goto normal;
8312 Py_BEGIN_ALLOW_THREADS
8313 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8314 PyUnicode_AS_UNICODE(unipath),
8315 NULL, NULL, SW_SHOWNORMAL);
8316 Py_END_ALLOW_THREADS
8318 Py_XDECREF(woperation);
8319 if (rc <= (HINSTANCE)32) {
8320 PyObject *errval = win32_error_unicode("startfile",
8321 PyUnicode_AS_UNICODE(unipath));
8322 return errval;
8324 Py_INCREF(Py_None);
8325 return Py_None;
8328 normal:
8329 if (!PyArg_ParseTuple(args, "et|s:startfile",
8330 Py_FileSystemDefaultEncoding, &filepath,
8331 &operation))
8332 return NULL;
8333 Py_BEGIN_ALLOW_THREADS
8334 rc = ShellExecute((HWND)0, operation, filepath,
8335 NULL, NULL, SW_SHOWNORMAL);
8336 Py_END_ALLOW_THREADS
8337 if (rc <= (HINSTANCE)32) {
8338 PyObject *errval = win32_error("startfile", filepath);
8339 PyMem_Free(filepath);
8340 return errval;
8342 PyMem_Free(filepath);
8343 Py_INCREF(Py_None);
8344 return Py_None;
8346 #endif /* MS_WINDOWS */
8348 #ifdef HAVE_GETLOADAVG
8349 PyDoc_STRVAR(posix_getloadavg__doc__,
8350 "getloadavg() -> (float, float, float)\n\n\
8351 Return the number of processes in the system run queue averaged over\n\
8352 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8353 was unobtainable");
8355 static PyObject *
8356 posix_getloadavg(PyObject *self, PyObject *noargs)
8358 double loadavg[3];
8359 if (getloadavg(loadavg, 3)!=3) {
8360 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8361 return NULL;
8362 } else
8363 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8365 #endif
8367 #ifdef MS_WINDOWS
8369 PyDoc_STRVAR(win32_urandom__doc__,
8370 "urandom(n) -> str\n\n\
8371 Return a string of n random bytes suitable for cryptographic use.");
8373 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8374 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8375 DWORD dwFlags );
8376 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8377 BYTE *pbBuffer );
8379 static CRYPTGENRANDOM pCryptGenRandom = NULL;
8380 /* This handle is never explicitly released. Instead, the operating
8381 system will release it when the process terminates. */
8382 static HCRYPTPROV hCryptProv = 0;
8384 static PyObject*
8385 win32_urandom(PyObject *self, PyObject *args)
8387 int howMany;
8388 PyObject* result;
8390 /* Read arguments */
8391 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8392 return NULL;
8393 if (howMany < 0)
8394 return PyErr_Format(PyExc_ValueError,
8395 "negative argument not allowed");
8397 if (hCryptProv == 0) {
8398 HINSTANCE hAdvAPI32 = NULL;
8399 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
8401 /* Obtain handle to the DLL containing CryptoAPI
8402 This should not fail */
8403 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8404 if(hAdvAPI32 == NULL)
8405 return win32_error("GetModuleHandle", NULL);
8407 /* Obtain pointers to the CryptoAPI functions
8408 This will fail on some early versions of Win95 */
8409 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8410 hAdvAPI32,
8411 "CryptAcquireContextA");
8412 if (pCryptAcquireContext == NULL)
8413 return PyErr_Format(PyExc_NotImplementedError,
8414 "CryptAcquireContextA not found");
8416 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8417 hAdvAPI32, "CryptGenRandom");
8418 if (pCryptGenRandom == NULL)
8419 return PyErr_Format(PyExc_NotImplementedError,
8420 "CryptGenRandom not found");
8422 /* Acquire context */
8423 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8424 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8425 return win32_error("CryptAcquireContext", NULL);
8428 /* Allocate bytes */
8429 result = PyString_FromStringAndSize(NULL, howMany);
8430 if (result != NULL) {
8431 /* Get random data */
8432 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
8433 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8434 PyString_AS_STRING(result))) {
8435 Py_DECREF(result);
8436 return win32_error("CryptGenRandom", NULL);
8439 return result;
8441 #endif
8443 #ifdef __VMS
8444 /* Use openssl random routine */
8445 #include <openssl/rand.h>
8446 PyDoc_STRVAR(vms_urandom__doc__,
8447 "urandom(n) -> str\n\n\
8448 Return a string of n random bytes suitable for cryptographic use.");
8450 static PyObject*
8451 vms_urandom(PyObject *self, PyObject *args)
8453 int howMany;
8454 PyObject* result;
8456 /* Read arguments */
8457 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8458 return NULL;
8459 if (howMany < 0)
8460 return PyErr_Format(PyExc_ValueError,
8461 "negative argument not allowed");
8463 /* Allocate bytes */
8464 result = PyString_FromStringAndSize(NULL, howMany);
8465 if (result != NULL) {
8466 /* Get random data */
8467 if (RAND_pseudo_bytes((unsigned char*)
8468 PyString_AS_STRING(result),
8469 howMany) < 0) {
8470 Py_DECREF(result);
8471 return PyErr_Format(PyExc_ValueError,
8472 "RAND_pseudo_bytes");
8475 return result;
8477 #endif
8479 static PyMethodDef posix_methods[] = {
8480 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8481 #ifdef HAVE_TTYNAME
8482 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8483 #endif
8484 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
8485 #ifdef HAVE_CHFLAGS
8486 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8487 #endif /* HAVE_CHFLAGS */
8488 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
8489 #ifdef HAVE_FCHMOD
8490 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8491 #endif /* HAVE_FCHMOD */
8492 #ifdef HAVE_CHOWN
8493 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
8494 #endif /* HAVE_CHOWN */
8495 #ifdef HAVE_LCHMOD
8496 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8497 #endif /* HAVE_LCHMOD */
8498 #ifdef HAVE_FCHOWN
8499 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8500 #endif /* HAVE_FCHOWN */
8501 #ifdef HAVE_LCHFLAGS
8502 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8503 #endif /* HAVE_LCHFLAGS */
8504 #ifdef HAVE_LCHOWN
8505 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8506 #endif /* HAVE_LCHOWN */
8507 #ifdef HAVE_CHROOT
8508 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8509 #endif
8510 #ifdef HAVE_CTERMID
8511 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
8512 #endif
8513 #ifdef HAVE_GETCWD
8514 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
8515 #ifdef Py_USING_UNICODE
8516 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
8517 #endif
8518 #endif
8519 #ifdef HAVE_LINK
8520 {"link", posix_link, METH_VARARGS, posix_link__doc__},
8521 #endif /* HAVE_LINK */
8522 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8523 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8524 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
8525 #ifdef HAVE_NICE
8526 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
8527 #endif /* HAVE_NICE */
8528 #ifdef HAVE_READLINK
8529 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
8530 #endif /* HAVE_READLINK */
8531 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8532 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8533 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8534 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
8535 #ifdef HAVE_SYMLINK
8536 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
8537 #endif /* HAVE_SYMLINK */
8538 #ifdef HAVE_SYSTEM
8539 {"system", posix_system, METH_VARARGS, posix_system__doc__},
8540 #endif
8541 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
8542 #ifdef HAVE_UNAME
8543 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
8544 #endif /* HAVE_UNAME */
8545 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8546 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8547 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
8548 #ifdef HAVE_TIMES
8549 {"times", posix_times, METH_NOARGS, posix_times__doc__},
8550 #endif /* HAVE_TIMES */
8551 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
8552 #ifdef HAVE_EXECV
8553 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8554 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
8555 #endif /* HAVE_EXECV */
8556 #ifdef HAVE_SPAWNV
8557 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8558 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
8559 #if defined(PYOS_OS2)
8560 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8561 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8562 #endif /* PYOS_OS2 */
8563 #endif /* HAVE_SPAWNV */
8564 #ifdef HAVE_FORK1
8565 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
8566 #endif /* HAVE_FORK1 */
8567 #ifdef HAVE_FORK
8568 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
8569 #endif /* HAVE_FORK */
8570 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
8571 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
8572 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
8573 #ifdef HAVE_FORKPTY
8574 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
8575 #endif /* HAVE_FORKPTY */
8576 #ifdef HAVE_GETEGID
8577 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
8578 #endif /* HAVE_GETEGID */
8579 #ifdef HAVE_GETEUID
8580 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
8581 #endif /* HAVE_GETEUID */
8582 #ifdef HAVE_GETGID
8583 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
8584 #endif /* HAVE_GETGID */
8585 #ifdef HAVE_GETGROUPS
8586 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
8587 #endif
8588 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
8589 #ifdef HAVE_GETPGRP
8590 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
8591 #endif /* HAVE_GETPGRP */
8592 #ifdef HAVE_GETPPID
8593 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
8594 #endif /* HAVE_GETPPID */
8595 #ifdef HAVE_GETUID
8596 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
8597 #endif /* HAVE_GETUID */
8598 #ifdef HAVE_GETLOGIN
8599 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
8600 #endif
8601 #ifdef HAVE_KILL
8602 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
8603 #endif /* HAVE_KILL */
8604 #ifdef HAVE_KILLPG
8605 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8606 #endif /* HAVE_KILLPG */
8607 #ifdef HAVE_PLOCK
8608 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
8609 #endif /* HAVE_PLOCK */
8610 #ifdef HAVE_POPEN
8611 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
8612 #ifdef MS_WINDOWS
8613 {"popen2", win32_popen2, METH_VARARGS},
8614 {"popen3", win32_popen3, METH_VARARGS},
8615 {"popen4", win32_popen4, METH_VARARGS},
8616 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8617 #else
8618 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8619 {"popen2", os2emx_popen2, METH_VARARGS},
8620 {"popen3", os2emx_popen3, METH_VARARGS},
8621 {"popen4", os2emx_popen4, METH_VARARGS},
8622 #endif
8623 #endif
8624 #endif /* HAVE_POPEN */
8625 #ifdef HAVE_SETUID
8626 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
8627 #endif /* HAVE_SETUID */
8628 #ifdef HAVE_SETEUID
8629 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8630 #endif /* HAVE_SETEUID */
8631 #ifdef HAVE_SETEGID
8632 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8633 #endif /* HAVE_SETEGID */
8634 #ifdef HAVE_SETREUID
8635 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8636 #endif /* HAVE_SETREUID */
8637 #ifdef HAVE_SETREGID
8638 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8639 #endif /* HAVE_SETREGID */
8640 #ifdef HAVE_SETGID
8641 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
8642 #endif /* HAVE_SETGID */
8643 #ifdef HAVE_SETGROUPS
8644 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
8645 #endif /* HAVE_SETGROUPS */
8646 #ifdef HAVE_GETPGID
8647 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8648 #endif /* HAVE_GETPGID */
8649 #ifdef HAVE_SETPGRP
8650 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
8651 #endif /* HAVE_SETPGRP */
8652 #ifdef HAVE_WAIT
8653 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
8654 #endif /* HAVE_WAIT */
8655 #ifdef HAVE_WAIT3
8656 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8657 #endif /* HAVE_WAIT3 */
8658 #ifdef HAVE_WAIT4
8659 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8660 #endif /* HAVE_WAIT4 */
8661 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
8662 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
8663 #endif /* HAVE_WAITPID */
8664 #ifdef HAVE_GETSID
8665 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8666 #endif /* HAVE_GETSID */
8667 #ifdef HAVE_SETSID
8668 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
8669 #endif /* HAVE_SETSID */
8670 #ifdef HAVE_SETPGID
8671 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
8672 #endif /* HAVE_SETPGID */
8673 #ifdef HAVE_TCGETPGRP
8674 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
8675 #endif /* HAVE_TCGETPGRP */
8676 #ifdef HAVE_TCSETPGRP
8677 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
8678 #endif /* HAVE_TCSETPGRP */
8679 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8680 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8681 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8682 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8683 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8684 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8685 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8686 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8687 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8688 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8689 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
8690 #ifdef HAVE_PIPE
8691 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
8692 #endif
8693 #ifdef HAVE_MKFIFO
8694 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
8695 #endif
8696 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8697 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8698 #endif
8699 #ifdef HAVE_DEVICE_MACROS
8700 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8701 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8702 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8703 #endif
8704 #ifdef HAVE_FTRUNCATE
8705 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
8706 #endif
8707 #ifdef HAVE_PUTENV
8708 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
8709 #endif
8710 #ifdef HAVE_UNSETENV
8711 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8712 #endif
8713 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
8714 #ifdef HAVE_FCHDIR
8715 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8716 #endif
8717 #ifdef HAVE_FSYNC
8718 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
8719 #endif
8720 #ifdef HAVE_FDATASYNC
8721 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
8722 #endif
8723 #ifdef HAVE_SYS_WAIT_H
8724 #ifdef WCOREDUMP
8725 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8726 #endif /* WCOREDUMP */
8727 #ifdef WIFCONTINUED
8728 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8729 #endif /* WIFCONTINUED */
8730 #ifdef WIFSTOPPED
8731 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
8732 #endif /* WIFSTOPPED */
8733 #ifdef WIFSIGNALED
8734 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
8735 #endif /* WIFSIGNALED */
8736 #ifdef WIFEXITED
8737 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
8738 #endif /* WIFEXITED */
8739 #ifdef WEXITSTATUS
8740 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
8741 #endif /* WEXITSTATUS */
8742 #ifdef WTERMSIG
8743 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
8744 #endif /* WTERMSIG */
8745 #ifdef WSTOPSIG
8746 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
8747 #endif /* WSTOPSIG */
8748 #endif /* HAVE_SYS_WAIT_H */
8749 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
8750 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
8751 #endif
8752 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
8753 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
8754 #endif
8755 #ifdef HAVE_TMPFILE
8756 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
8757 #endif
8758 #ifdef HAVE_TEMPNAM
8759 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8760 #endif
8761 #ifdef HAVE_TMPNAM
8762 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
8763 #endif
8764 #ifdef HAVE_CONFSTR
8765 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8766 #endif
8767 #ifdef HAVE_SYSCONF
8768 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8769 #endif
8770 #ifdef HAVE_FPATHCONF
8771 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8772 #endif
8773 #ifdef HAVE_PATHCONF
8774 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8775 #endif
8776 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
8777 #ifdef MS_WINDOWS
8778 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8779 #endif
8780 #ifdef HAVE_GETLOADAVG
8781 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
8782 #endif
8783 #ifdef MS_WINDOWS
8784 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8785 #endif
8786 #ifdef __VMS
8787 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8788 #endif
8789 {NULL, NULL} /* Sentinel */
8793 static int
8794 ins(PyObject *module, char *symbol, long value)
8796 return PyModule_AddIntConstant(module, symbol, value);
8799 #if defined(PYOS_OS2)
8800 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
8801 static int insertvalues(PyObject *module)
8803 APIRET rc;
8804 ULONG values[QSV_MAX+1];
8805 PyObject *v;
8806 char *ver, tmp[50];
8808 Py_BEGIN_ALLOW_THREADS
8809 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
8810 Py_END_ALLOW_THREADS
8812 if (rc != NO_ERROR) {
8813 os2_error(rc);
8814 return -1;
8817 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8818 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8819 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8820 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8821 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8822 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8823 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
8825 switch (values[QSV_VERSION_MINOR]) {
8826 case 0: ver = "2.00"; break;
8827 case 10: ver = "2.10"; break;
8828 case 11: ver = "2.11"; break;
8829 case 30: ver = "3.00"; break;
8830 case 40: ver = "4.00"; break;
8831 case 50: ver = "5.00"; break;
8832 default:
8833 PyOS_snprintf(tmp, sizeof(tmp),
8834 "%d-%d", values[QSV_VERSION_MAJOR],
8835 values[QSV_VERSION_MINOR]);
8836 ver = &tmp[0];
8839 /* Add Indicator of the Version of the Operating System */
8840 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
8841 return -1;
8843 /* Add Indicator of Which Drive was Used to Boot the System */
8844 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8845 tmp[1] = ':';
8846 tmp[2] = '\0';
8848 return PyModule_AddStringConstant(module, "bootdrive", tmp);
8850 #endif
8852 static int
8853 all_ins(PyObject *d)
8855 #ifdef F_OK
8856 if (ins(d, "F_OK", (long)F_OK)) return -1;
8857 #endif
8858 #ifdef R_OK
8859 if (ins(d, "R_OK", (long)R_OK)) return -1;
8860 #endif
8861 #ifdef W_OK
8862 if (ins(d, "W_OK", (long)W_OK)) return -1;
8863 #endif
8864 #ifdef X_OK
8865 if (ins(d, "X_OK", (long)X_OK)) return -1;
8866 #endif
8867 #ifdef NGROUPS_MAX
8868 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8869 #endif
8870 #ifdef TMP_MAX
8871 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8872 #endif
8873 #ifdef WCONTINUED
8874 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8875 #endif
8876 #ifdef WNOHANG
8877 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
8878 #endif
8879 #ifdef WUNTRACED
8880 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8881 #endif
8882 #ifdef O_RDONLY
8883 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8884 #endif
8885 #ifdef O_WRONLY
8886 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8887 #endif
8888 #ifdef O_RDWR
8889 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8890 #endif
8891 #ifdef O_NDELAY
8892 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8893 #endif
8894 #ifdef O_NONBLOCK
8895 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8896 #endif
8897 #ifdef O_APPEND
8898 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8899 #endif
8900 #ifdef O_DSYNC
8901 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8902 #endif
8903 #ifdef O_RSYNC
8904 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8905 #endif
8906 #ifdef O_SYNC
8907 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8908 #endif
8909 #ifdef O_NOCTTY
8910 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8911 #endif
8912 #ifdef O_CREAT
8913 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8914 #endif
8915 #ifdef O_EXCL
8916 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8917 #endif
8918 #ifdef O_TRUNC
8919 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8920 #endif
8921 #ifdef O_BINARY
8922 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8923 #endif
8924 #ifdef O_TEXT
8925 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8926 #endif
8927 #ifdef O_LARGEFILE
8928 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8929 #endif
8930 #ifdef O_SHLOCK
8931 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8932 #endif
8933 #ifdef O_EXLOCK
8934 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8935 #endif
8937 /* MS Windows */
8938 #ifdef O_NOINHERIT
8939 /* Don't inherit in child processes. */
8940 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8941 #endif
8942 #ifdef _O_SHORT_LIVED
8943 /* Optimize for short life (keep in memory). */
8944 /* MS forgot to define this one with a non-underscore form too. */
8945 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8946 #endif
8947 #ifdef O_TEMPORARY
8948 /* Automatically delete when last handle is closed. */
8949 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8950 #endif
8951 #ifdef O_RANDOM
8952 /* Optimize for random access. */
8953 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8954 #endif
8955 #ifdef O_SEQUENTIAL
8956 /* Optimize for sequential access. */
8957 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8958 #endif
8960 /* GNU extensions. */
8961 #ifdef O_ASYNC
8962 /* Send a SIGIO signal whenever input or output
8963 becomes available on file descriptor */
8964 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8965 #endif
8966 #ifdef O_DIRECT
8967 /* Direct disk access. */
8968 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8969 #endif
8970 #ifdef O_DIRECTORY
8971 /* Must be a directory. */
8972 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8973 #endif
8974 #ifdef O_NOFOLLOW
8975 /* Do not follow links. */
8976 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8977 #endif
8978 #ifdef O_NOATIME
8979 /* Do not update the access time. */
8980 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8981 #endif
8983 /* These come from sysexits.h */
8984 #ifdef EX_OK
8985 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
8986 #endif /* EX_OK */
8987 #ifdef EX_USAGE
8988 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
8989 #endif /* EX_USAGE */
8990 #ifdef EX_DATAERR
8991 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
8992 #endif /* EX_DATAERR */
8993 #ifdef EX_NOINPUT
8994 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
8995 #endif /* EX_NOINPUT */
8996 #ifdef EX_NOUSER
8997 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
8998 #endif /* EX_NOUSER */
8999 #ifdef EX_NOHOST
9000 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
9001 #endif /* EX_NOHOST */
9002 #ifdef EX_UNAVAILABLE
9003 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
9004 #endif /* EX_UNAVAILABLE */
9005 #ifdef EX_SOFTWARE
9006 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
9007 #endif /* EX_SOFTWARE */
9008 #ifdef EX_OSERR
9009 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
9010 #endif /* EX_OSERR */
9011 #ifdef EX_OSFILE
9012 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
9013 #endif /* EX_OSFILE */
9014 #ifdef EX_CANTCREAT
9015 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
9016 #endif /* EX_CANTCREAT */
9017 #ifdef EX_IOERR
9018 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
9019 #endif /* EX_IOERR */
9020 #ifdef EX_TEMPFAIL
9021 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
9022 #endif /* EX_TEMPFAIL */
9023 #ifdef EX_PROTOCOL
9024 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
9025 #endif /* EX_PROTOCOL */
9026 #ifdef EX_NOPERM
9027 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
9028 #endif /* EX_NOPERM */
9029 #ifdef EX_CONFIG
9030 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
9031 #endif /* EX_CONFIG */
9032 #ifdef EX_NOTFOUND
9033 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
9034 #endif /* EX_NOTFOUND */
9036 #ifdef HAVE_SPAWNV
9037 #if defined(PYOS_OS2) && defined(PYCC_GCC)
9038 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9039 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9040 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9041 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9042 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9043 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9044 if (ins(d, "P_PM", (long)P_PM)) return -1;
9045 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9046 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9047 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9048 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9049 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9050 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9051 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9052 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9053 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9054 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9055 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9056 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9057 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
9058 #else
9059 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9060 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9061 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9062 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9063 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
9064 #endif
9065 #endif
9067 #if defined(PYOS_OS2)
9068 if (insertvalues(d)) return -1;
9069 #endif
9070 return 0;
9074 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
9075 #define INITFUNC initnt
9076 #define MODNAME "nt"
9078 #elif defined(PYOS_OS2)
9079 #define INITFUNC initos2
9080 #define MODNAME "os2"
9082 #else
9083 #define INITFUNC initposix
9084 #define MODNAME "posix"
9085 #endif
9087 PyMODINIT_FUNC
9088 INITFUNC(void)
9090 PyObject *m, *v;
9092 m = Py_InitModule3(MODNAME,
9093 posix_methods,
9094 posix__doc__);
9095 if (m == NULL)
9096 return;
9098 /* Initialize environ dictionary */
9099 v = convertenviron();
9100 Py_XINCREF(v);
9101 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9102 return;
9103 Py_DECREF(v);
9105 if (all_ins(m))
9106 return;
9108 if (setup_confname_tables(m))
9109 return;
9111 Py_INCREF(PyExc_OSError);
9112 PyModule_AddObject(m, "error", PyExc_OSError);
9114 #ifdef HAVE_PUTENV
9115 if (posix_putenv_garbage == NULL)
9116 posix_putenv_garbage = PyDict_New();
9117 #endif
9119 if (!initialized) {
9120 stat_result_desc.name = MODNAME ".stat_result";
9121 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9122 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9123 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9124 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9125 structseq_new = StatResultType.tp_new;
9126 StatResultType.tp_new = statresult_new;
9128 statvfs_result_desc.name = MODNAME ".statvfs_result";
9129 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
9130 #ifdef NEED_TICKS_PER_SECOND
9131 # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
9132 ticks_per_second = sysconf(_SC_CLK_TCK);
9133 # elif defined(HZ)
9134 ticks_per_second = HZ;
9135 # else
9136 ticks_per_second = 60; /* magic fallback value; may be bogus */
9137 # endif
9138 #endif
9140 Py_INCREF((PyObject*) &StatResultType);
9141 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9142 Py_INCREF((PyObject*) &StatVFSResultType);
9143 PyModule_AddObject(m, "statvfs_result",
9144 (PyObject*) &StatVFSResultType);
9145 initialized = 1;
9147 #ifdef __APPLE__
9149 * Step 2 of weak-linking support on Mac OS X.
9151 * The code below removes functions that are not available on the
9152 * currently active platform.
9154 * This block allow one to use a python binary that was build on
9155 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9156 * OSX 10.4.
9158 #ifdef HAVE_FSTATVFS
9159 if (fstatvfs == NULL) {
9160 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9161 return;
9164 #endif /* HAVE_FSTATVFS */
9166 #ifdef HAVE_STATVFS
9167 if (statvfs == NULL) {
9168 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9169 return;
9172 #endif /* HAVE_STATVFS */
9174 # ifdef HAVE_LCHOWN
9175 if (lchown == NULL) {
9176 if (PyObject_DelAttrString(m, "lchown") == -1) {
9177 return;
9180 #endif /* HAVE_LCHOWN */
9183 #endif /* __APPLE__ */
9187 #ifdef __cplusplus
9189 #endif