only use -fno-strict-aliasing when needed by compiler
[python/dscho.git] / Modules / posixmodule.c
blob65a0a5e916dd24beada2ddfaeaf65abd7bf6f11c
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.");
48 #if defined(PYOS_OS2)
49 #define INCL_DOS
50 #define INCL_DOSERRORS
51 #define INCL_DOSPROCESS
52 #define INCL_NOPMAPI
53 #include <os2.h>
54 #if defined(PYCC_GCC)
55 #include <ctype.h>
56 #include <io.h>
57 #include <stdio.h>
58 #include <process.h>
59 #endif
60 #include "osdefs.h"
61 #endif
63 #ifdef HAVE_SYS_TYPES_H
64 #include <sys/types.h>
65 #endif /* HAVE_SYS_TYPES_H */
67 #ifdef HAVE_SYS_STAT_H
68 #include <sys/stat.h>
69 #endif /* HAVE_SYS_STAT_H */
71 #ifdef HAVE_SYS_WAIT_H
72 #include <sys/wait.h> /* For WNOHANG */
73 #endif
75 #ifdef HAVE_SIGNAL_H
76 #include <signal.h>
77 #endif
79 #ifdef HAVE_FCNTL_H
80 #include <fcntl.h>
81 #endif /* HAVE_FCNTL_H */
83 #ifdef HAVE_GRP_H
84 #include <grp.h>
85 #endif
87 #ifdef HAVE_SYSEXITS_H
88 #include <sysexits.h>
89 #endif /* HAVE_SYSEXITS_H */
91 #ifdef HAVE_SYS_LOADAVG_H
92 #include <sys/loadavg.h>
93 #endif
95 #ifdef HAVE_LANGINFO_H
96 #include <langinfo.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_SYSTEM 1
120 #define HAVE_WAIT 1
121 #else
122 #ifdef _MSC_VER /* Microsoft compiler */
123 #define HAVE_GETCWD 1
124 #define HAVE_SPAWNV 1
125 #define HAVE_EXECV 1
126 #define HAVE_PIPE 1
127 #define HAVE_SYSTEM 1
128 #define HAVE_CWAIT 1
129 #define HAVE_FSYNC 1
130 #define fsync _commit
131 #else
132 #if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
133 /* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
134 #else /* all other compilers */
135 /* Unix functions that the configure script doesn't check for */
136 #define HAVE_EXECV 1
137 #define HAVE_FORK 1
138 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
139 #define HAVE_FORK1 1
140 #endif
141 #define HAVE_GETCWD 1
142 #define HAVE_GETEGID 1
143 #define HAVE_GETEUID 1
144 #define HAVE_GETGID 1
145 #define HAVE_GETPPID 1
146 #define HAVE_GETUID 1
147 #define HAVE_KILL 1
148 #define HAVE_OPENDIR 1
149 #define HAVE_PIPE 1
150 #define HAVE_SYSTEM 1
151 #define HAVE_WAIT 1
152 #define HAVE_TTYNAME 1
153 #endif /* PYOS_OS2 && PYCC_GCC && __VMS */
154 #endif /* _MSC_VER */
155 #endif /* __BORLANDC__ */
156 #endif /* ! __WATCOMC__ || __QNX__ */
157 #endif /* ! __IBMC__ */
159 #ifndef _MSC_VER
161 #if defined(__sgi)&&_COMPILER_VERSION>=700
162 /* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
163 (default) */
164 extern char *ctermid_r(char *);
165 #endif
167 #ifndef HAVE_UNISTD_H
168 #if defined(PYCC_VACPP)
169 extern int mkdir(char *);
170 #else
171 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
172 extern int mkdir(const char *);
173 #else
174 extern int mkdir(const char *, mode_t);
175 #endif
176 #endif
177 #if defined(__IBMC__) || defined(__IBMCPP__)
178 extern int chdir(char *);
179 extern int rmdir(char *);
180 #else
181 extern int chdir(const char *);
182 extern int rmdir(const char *);
183 #endif
184 #ifdef __BORLANDC__
185 extern int chmod(const char *, int);
186 #else
187 extern int chmod(const char *, mode_t);
188 #endif
189 /*#ifdef HAVE_FCHMOD
190 extern int fchmod(int, mode_t);
191 #endif*/
192 /*#ifdef HAVE_LCHMOD
193 extern int lchmod(const char *, mode_t);
194 #endif*/
195 extern int chown(const char *, uid_t, gid_t);
196 extern char *getcwd(char *, int);
197 extern char *strerror(int);
198 extern int link(const char *, const char *);
199 extern int rename(const char *, const char *);
200 extern int stat(const char *, struct stat *);
201 extern int unlink(const char *);
202 #ifdef HAVE_SYMLINK
203 extern int symlink(const char *, const char *);
204 #endif /* HAVE_SYMLINK */
205 #ifdef HAVE_LSTAT
206 extern int lstat(const char *, struct stat *);
207 #endif /* HAVE_LSTAT */
208 #endif /* !HAVE_UNISTD_H */
210 #endif /* !_MSC_VER */
212 #ifdef HAVE_UTIME_H
213 #include <utime.h>
214 #endif /* HAVE_UTIME_H */
216 #ifdef HAVE_SYS_UTIME_H
217 #include <sys/utime.h>
218 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
219 #endif /* HAVE_SYS_UTIME_H */
221 #ifdef HAVE_SYS_TIMES_H
222 #include <sys/times.h>
223 #endif /* HAVE_SYS_TIMES_H */
225 #ifdef HAVE_SYS_PARAM_H
226 #include <sys/param.h>
227 #endif /* HAVE_SYS_PARAM_H */
229 #ifdef HAVE_SYS_UTSNAME_H
230 #include <sys/utsname.h>
231 #endif /* HAVE_SYS_UTSNAME_H */
233 #ifdef HAVE_DIRENT_H
234 #include <dirent.h>
235 #define NAMLEN(dirent) strlen((dirent)->d_name)
236 #else
237 #if defined(__WATCOMC__) && !defined(__QNX__)
238 #include <direct.h>
239 #define NAMLEN(dirent) strlen((dirent)->d_name)
240 #else
241 #define dirent direct
242 #define NAMLEN(dirent) (dirent)->d_namlen
243 #endif
244 #ifdef HAVE_SYS_NDIR_H
245 #include <sys/ndir.h>
246 #endif
247 #ifdef HAVE_SYS_DIR_H
248 #include <sys/dir.h>
249 #endif
250 #ifdef HAVE_NDIR_H
251 #include <ndir.h>
252 #endif
253 #endif
255 #ifdef _MSC_VER
256 #ifdef HAVE_DIRECT_H
257 #include <direct.h>
258 #endif
259 #ifdef HAVE_IO_H
260 #include <io.h>
261 #endif
262 #ifdef HAVE_PROCESS_H
263 #include <process.h>
264 #endif
265 #include "osdefs.h"
266 #include <malloc.h>
267 #include <windows.h>
268 #include <shellapi.h> /* for ShellExecute() */
269 #endif /* _MSC_VER */
271 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
272 #include <io.h>
273 #endif /* OS2 */
275 #ifndef MAXPATHLEN
276 #if defined(PATH_MAX) && PATH_MAX > 1024
277 #define MAXPATHLEN PATH_MAX
278 #else
279 #define MAXPATHLEN 1024
280 #endif
281 #endif /* MAXPATHLEN */
283 #ifdef UNION_WAIT
284 /* Emulate some macros on systems that have a union instead of macros */
286 #ifndef WIFEXITED
287 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
288 #endif
290 #ifndef WEXITSTATUS
291 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
292 #endif
294 #ifndef WTERMSIG
295 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
296 #endif
298 #define WAIT_TYPE union wait
299 #define WAIT_STATUS_INT(s) (s.w_status)
301 #else /* !UNION_WAIT */
302 #define WAIT_TYPE int
303 #define WAIT_STATUS_INT(s) (s)
304 #endif /* UNION_WAIT */
306 /* Issue #1983: pid_t can be longer than a C long on some systems */
307 #if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
308 #define PARSE_PID "i"
309 #define PyLong_FromPid PyLong_FromLong
310 #define PyLong_AsPid PyLong_AsLong
311 #elif SIZEOF_PID_T == SIZEOF_LONG
312 #define PARSE_PID "l"
313 #define PyLong_FromPid PyLong_FromLong
314 #define PyLong_AsPid PyLong_AsLong
315 #elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
316 #define PARSE_PID "L"
317 #define PyLong_FromPid PyLong_FromLongLong
318 #define PyLong_AsPid PyLong_AsLongLong
319 #else
320 #error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
321 #endif /* SIZEOF_PID_T */
323 /* Don't use the "_r" form if we don't need it (also, won't have a
324 prototype for it, at least on Solaris -- maybe others as well?). */
325 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
326 #define USE_CTERMID_R
327 #endif
329 /* choose the appropriate stat and fstat functions and return structs */
330 #undef STAT
331 #if defined(MS_WIN64) || defined(MS_WINDOWS)
332 # define STAT win32_stat
333 # define FSTAT win32_fstat
334 # define STRUCT_STAT struct win32_stat
335 #else
336 # define STAT stat
337 # define FSTAT fstat
338 # define STRUCT_STAT struct stat
339 #endif
341 #if defined(MAJOR_IN_MKDEV)
342 #include <sys/mkdev.h>
343 #else
344 #if defined(MAJOR_IN_SYSMACROS)
345 #include <sys/sysmacros.h>
346 #endif
347 #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
348 #include <sys/mkdev.h>
349 #endif
350 #endif
352 #if defined _MSC_VER && _MSC_VER >= 1400
353 /* Microsoft CRT in VS2005 and higher will verify that a filehandle is
354 * valid and throw an assertion if it isn't.
355 * Normally, an invalid fd is likely to be a C program error and therefore
356 * an assertion can be useful, but it does contradict the POSIX standard
357 * which for write(2) states:
358 * "Otherwise, -1 shall be returned and errno set to indicate the error."
359 * "[EBADF] The fildes argument is not a valid file descriptor open for
360 * writing."
361 * Furthermore, python allows the user to enter any old integer
362 * as a fd and should merely raise a python exception on error.
363 * The Microsoft CRT doesn't provide an official way to check for the
364 * validity of a file descriptor, but we can emulate its internal behaviour
365 * by using the exported __pinfo data member and knowledge of the
366 * internal structures involved.
367 * The structures below must be updated for each version of visual studio
368 * according to the file internal.h in the CRT source, until MS comes
369 * up with a less hacky way to do this.
370 * (all of this is to avoid globally modifying the CRT behaviour using
371 * _set_invalid_parameter_handler() and _CrtSetReportMode())
373 /* The actual size of the structure is determined at runtime.
374 * Only the first items must be present.
376 typedef struct {
377 intptr_t osfhnd;
378 char osfile;
379 } my_ioinfo;
381 extern __declspec(dllimport) char * __pioinfo[];
382 #define IOINFO_L2E 5
383 #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
384 #define IOINFO_ARRAYS 64
385 #define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
386 #define FOPEN 0x01
387 #define _NO_CONSOLE_FILENO (intptr_t)-2
389 /* This function emulates what the windows CRT does to validate file handles */
391 _PyVerify_fd(int fd)
393 const int i1 = fd >> IOINFO_L2E;
394 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
396 static int sizeof_ioinfo = 0;
398 /* Determine the actual size of the ioinfo structure,
399 * as used by the CRT loaded in memory
401 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
402 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
404 if (sizeof_ioinfo == 0) {
405 /* This should not happen... */
406 goto fail;
409 /* See that it isn't a special CLEAR fileno */
410 if (fd != _NO_CONSOLE_FILENO) {
411 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
412 * we check pointer validity and other info
414 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
415 /* finally, check that the file is open */
416 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
417 if (info->osfile & FOPEN) {
418 return 1;
422 fail:
423 errno = EBADF;
424 return 0;
427 /* the special case of checking dup2. The target fd must be in a sensible range */
428 static int
429 _PyVerify_fd_dup2(int fd1, int fd2)
431 if (!_PyVerify_fd(fd1))
432 return 0;
433 if (fd2 == _NO_CONSOLE_FILENO)
434 return 0;
435 if ((unsigned)fd2 < _NHANDLE_)
436 return 1;
437 else
438 return 0;
440 #else
441 /* dummy version. _PyVerify_fd() is already defined in fileobject.h */
442 #define _PyVerify_fd_dup2(A, B) (1)
443 #endif
445 /* Return a dictionary corresponding to the POSIX environment table */
446 #ifdef WITH_NEXT_FRAMEWORK
447 /* On Darwin/MacOSX a shared library or framework has no access to
448 ** environ directly, we must obtain it with _NSGetEnviron().
450 #include <crt_externs.h>
451 static char **environ;
452 #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
453 extern char **environ;
454 #endif /* !_MSC_VER */
456 static PyObject *
457 convertenviron(void)
459 PyObject *d;
460 #ifdef MS_WINDOWS
461 wchar_t **e;
462 #else
463 char **e;
464 #endif
465 #if defined(PYOS_OS2)
466 APIRET rc;
467 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
468 #endif
470 d = PyDict_New();
471 if (d == NULL)
472 return NULL;
473 #ifdef WITH_NEXT_FRAMEWORK
474 if (environ == NULL)
475 environ = *_NSGetEnviron();
476 #endif
477 #ifdef MS_WINDOWS
478 /* _wenviron must be initialized in this way if the program is started
479 through main() instead of wmain(). */
480 _wgetenv(L"");
481 if (_wenviron == NULL)
482 return d;
483 /* This part ignores errors */
484 for (e = _wenviron; *e != NULL; e++) {
485 PyObject *k;
486 PyObject *v;
487 wchar_t *p = wcschr(*e, L'=');
488 if (p == NULL)
489 continue;
490 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
491 if (k == NULL) {
492 PyErr_Clear();
493 continue;
495 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
496 if (v == NULL) {
497 PyErr_Clear();
498 Py_DECREF(k);
499 continue;
501 if (PyDict_GetItem(d, k) == NULL) {
502 if (PyDict_SetItem(d, k, v) != 0)
503 PyErr_Clear();
505 Py_DECREF(k);
506 Py_DECREF(v);
508 #else
509 if (environ == NULL)
510 return d;
511 /* This part ignores errors */
512 for (e = environ; *e != NULL; e++) {
513 PyObject *k;
514 PyObject *v;
515 char *p = strchr(*e, '=');
516 if (p == NULL)
517 continue;
518 k = PyUnicode_Decode(*e, (int)(p-*e),
519 Py_FileSystemDefaultEncoding, "surrogateescape");
520 if (k == NULL) {
521 PyErr_Clear();
522 continue;
524 v = PyUnicode_Decode(p+1, strlen(p+1),
525 Py_FileSystemDefaultEncoding, "surrogateescape");
526 if (v == NULL) {
527 PyErr_Clear();
528 Py_DECREF(k);
529 continue;
531 if (PyDict_GetItem(d, k) == NULL) {
532 if (PyDict_SetItem(d, k, v) != 0)
533 PyErr_Clear();
535 Py_DECREF(k);
536 Py_DECREF(v);
538 #endif
539 #if defined(PYOS_OS2)
540 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
541 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
542 PyObject *v = PyBytes_FromString(buffer);
543 PyDict_SetItemString(d, "BEGINLIBPATH", v);
544 Py_DECREF(v);
546 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
547 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
548 PyObject *v = PyBytes_FromString(buffer);
549 PyDict_SetItemString(d, "ENDLIBPATH", v);
550 Py_DECREF(v);
552 #endif
553 return d;
556 /* Convert a bytes object to a char*. Optionally lock the buffer if it is a
557 bytes array. */
559 static char*
560 bytes2str(PyObject* o, int lock)
562 if(PyBytes_Check(o))
563 return PyBytes_AsString(o);
564 else if(PyByteArray_Check(o)) {
565 if (lock && PyObject_GetBuffer(o, NULL, 0) < 0)
566 /* On a bytearray, this should not fail. */
567 PyErr_BadInternalCall();
568 return PyByteArray_AsString(o);
569 } else {
570 /* The FS converter should have verified that this
571 is either bytes or bytearray. */
572 Py_FatalError("bad object passed to bytes2str");
573 /* not reached. */
574 return "";
578 /* Release the lock, decref the object. */
579 static void
580 release_bytes(PyObject* o)
582 if (PyByteArray_Check(o))
583 o->ob_type->tp_as_buffer->bf_releasebuffer(o, 0);
584 Py_DECREF(o);
588 /* Set a POSIX-specific error from errno, and return NULL */
590 static PyObject *
591 posix_error(void)
593 return PyErr_SetFromErrno(PyExc_OSError);
595 static PyObject *
596 posix_error_with_filename(char* name)
598 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
601 #ifdef MS_WINDOWS
602 static PyObject *
603 posix_error_with_unicode_filename(Py_UNICODE* name)
605 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
607 #endif /* MS_WINDOWS */
610 static PyObject *
611 posix_error_with_allocated_filename(PyObject* name)
613 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError,
614 bytes2str(name, 0));
615 release_bytes(name);
616 return rc;
619 #ifdef MS_WINDOWS
620 static PyObject *
621 win32_error(char* function, char* filename)
623 /* XXX We should pass the function name along in the future.
624 (winreg.c also wants to pass the function name.)
625 This would however require an additional param to the
626 Windows error object, which is non-trivial.
628 errno = GetLastError();
629 if (filename)
630 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
631 else
632 return PyErr_SetFromWindowsErr(errno);
635 static PyObject *
636 win32_error_unicode(char* function, Py_UNICODE* filename)
638 /* XXX - see win32_error for comments on 'function' */
639 errno = GetLastError();
640 if (filename)
641 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
642 else
643 return PyErr_SetFromWindowsErr(errno);
646 static int
647 convert_to_unicode(PyObject **param)
649 if (PyUnicode_CheckExact(*param))
650 Py_INCREF(*param);
651 else if (PyUnicode_Check(*param))
652 /* For a Unicode subtype that's not a Unicode object,
653 return a true Unicode object with the same data. */
654 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
655 PyUnicode_GET_SIZE(*param));
656 else
657 *param = PyUnicode_FromEncodedObject(*param,
658 Py_FileSystemDefaultEncoding,
659 "strict");
660 return (*param) != NULL;
663 #endif /* MS_WINDOWS */
665 #if defined(PYOS_OS2)
666 /**********************************************************************
667 * Helper Function to Trim and Format OS/2 Messages
668 **********************************************************************/
669 static void
670 os2_formatmsg(char *msgbuf, int msglen, char *reason)
672 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
674 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
675 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
677 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
678 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
681 /* Add Optional Reason Text */
682 if (reason) {
683 strcat(msgbuf, " : ");
684 strcat(msgbuf, reason);
688 /**********************************************************************
689 * Decode an OS/2 Operating System Error Code
691 * A convenience function to lookup an OS/2 error code and return a
692 * text message we can use to raise a Python exception.
694 * Notes:
695 * The messages for errors returned from the OS/2 kernel reside in
696 * the file OSO001.MSG in the \OS2 directory hierarchy.
698 **********************************************************************/
699 static char *
700 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
702 APIRET rc;
703 ULONG msglen;
705 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
706 Py_BEGIN_ALLOW_THREADS
707 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
708 errorcode, "oso001.msg", &msglen);
709 Py_END_ALLOW_THREADS
711 if (rc == NO_ERROR)
712 os2_formatmsg(msgbuf, msglen, reason);
713 else
714 PyOS_snprintf(msgbuf, msgbuflen,
715 "unknown OS error #%d", errorcode);
717 return msgbuf;
720 /* Set an OS/2-specific error and return NULL. OS/2 kernel
721 errors are not in a global variable e.g. 'errno' nor are
722 they congruent with posix error numbers. */
724 static PyObject *
725 os2_error(int code)
727 char text[1024];
728 PyObject *v;
730 os2_strerror(text, sizeof(text), code, "");
732 v = Py_BuildValue("(is)", code, text);
733 if (v != NULL) {
734 PyErr_SetObject(PyExc_OSError, v);
735 Py_DECREF(v);
737 return NULL; /* Signal to Python that an Exception is Pending */
740 #endif /* OS2 */
742 /* POSIX generic methods */
744 static PyObject *
745 posix_fildes(PyObject *fdobj, int (*func)(int))
747 int fd;
748 int res;
749 fd = PyObject_AsFileDescriptor(fdobj);
750 if (fd < 0)
751 return NULL;
752 if (!_PyVerify_fd(fd))
753 return posix_error();
754 Py_BEGIN_ALLOW_THREADS
755 res = (*func)(fd);
756 Py_END_ALLOW_THREADS
757 if (res < 0)
758 return posix_error();
759 Py_INCREF(Py_None);
760 return Py_None;
763 #ifdef MS_WINDOWS
764 static int
765 unicode_file_names(void)
767 static int canusewide = -1;
768 if (canusewide == -1) {
769 /* As per doc for ::GetVersion(), this is the correct test for
770 the Windows NT family. */
771 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
773 return canusewide;
775 #endif
777 static PyObject *
778 posix_1str(PyObject *args, char *format, int (*func)(const char*))
780 PyObject *opath1 = NULL;
781 char *path1;
782 int res;
783 if (!PyArg_ParseTuple(args, format,
784 PyUnicode_FSConverter, &opath1))
785 return NULL;
786 path1 = bytes2str(opath1, 1);
787 Py_BEGIN_ALLOW_THREADS
788 res = (*func)(path1);
789 Py_END_ALLOW_THREADS
790 if (res < 0)
791 return posix_error_with_allocated_filename(opath1);
792 release_bytes(opath1);
793 Py_INCREF(Py_None);
794 return Py_None;
797 static PyObject *
798 posix_2str(PyObject *args,
799 char *format,
800 int (*func)(const char *, const char *))
802 PyObject *opath1 = NULL, *opath2 = NULL;
803 char *path1, *path2;
804 int res;
805 if (!PyArg_ParseTuple(args, format,
806 PyUnicode_FSConverter, &opath1,
807 PyUnicode_FSConverter, &opath2)) {
808 return NULL;
810 path1 = bytes2str(opath1, 1);
811 path2 = bytes2str(opath2, 1);
812 Py_BEGIN_ALLOW_THREADS
813 res = (*func)(path1, path2);
814 Py_END_ALLOW_THREADS
815 release_bytes(opath1);
816 release_bytes(opath2);
817 if (res != 0)
818 /* XXX how to report both path1 and path2??? */
819 return posix_error();
820 Py_INCREF(Py_None);
821 return Py_None;
824 #ifdef MS_WINDOWS
825 static PyObject*
826 win32_1str(PyObject* args, char* func,
827 char* format, BOOL (__stdcall *funcA)(LPCSTR),
828 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
830 PyObject *uni;
831 char *ansi;
832 BOOL result;
833 if (unicode_file_names()) {
834 if (!PyArg_ParseTuple(args, wformat, &uni))
835 PyErr_Clear();
836 else {
837 Py_BEGIN_ALLOW_THREADS
838 result = funcW(PyUnicode_AsUnicode(uni));
839 Py_END_ALLOW_THREADS
840 if (!result)
841 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
842 Py_INCREF(Py_None);
843 return Py_None;
846 if (!PyArg_ParseTuple(args, format, &ansi))
847 return NULL;
848 Py_BEGIN_ALLOW_THREADS
849 result = funcA(ansi);
850 Py_END_ALLOW_THREADS
851 if (!result)
852 return win32_error(func, ansi);
853 Py_INCREF(Py_None);
854 return Py_None;
858 /* This is a reimplementation of the C library's chdir function,
859 but one that produces Win32 errors instead of DOS error codes.
860 chdir is essentially a wrapper around SetCurrentDirectory; however,
861 it also needs to set "magic" environment variables indicating
862 the per-drive current directory, which are of the form =<drive>: */
863 static BOOL __stdcall
864 win32_chdir(LPCSTR path)
866 char new_path[MAX_PATH+1];
867 int result;
868 char env[4] = "=x:";
870 if(!SetCurrentDirectoryA(path))
871 return FALSE;
872 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
873 if (!result)
874 return FALSE;
875 /* In the ANSI API, there should not be any paths longer
876 than MAX_PATH. */
877 assert(result <= MAX_PATH+1);
878 if (strncmp(new_path, "\\\\", 2) == 0 ||
879 strncmp(new_path, "//", 2) == 0)
880 /* UNC path, nothing to do. */
881 return TRUE;
882 env[1] = new_path[0];
883 return SetEnvironmentVariableA(env, new_path);
886 /* The Unicode version differs from the ANSI version
887 since the current directory might exceed MAX_PATH characters */
888 static BOOL __stdcall
889 win32_wchdir(LPCWSTR path)
891 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
892 int result;
893 wchar_t env[4] = L"=x:";
895 if(!SetCurrentDirectoryW(path))
896 return FALSE;
897 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
898 if (!result)
899 return FALSE;
900 if (result > MAX_PATH+1) {
901 new_path = malloc(result * sizeof(wchar_t));
902 if (!new_path) {
903 SetLastError(ERROR_OUTOFMEMORY);
904 return FALSE;
906 result = GetCurrentDirectoryW(result, new_path);
907 if (!result) {
908 free(new_path);
909 return FALSE;
912 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
913 wcsncmp(new_path, L"//", 2) == 0)
914 /* UNC path, nothing to do. */
915 return TRUE;
916 env[1] = new_path[0];
917 result = SetEnvironmentVariableW(env, new_path);
918 if (new_path != _new_path)
919 free(new_path);
920 return result;
922 #endif
924 #ifdef MS_WINDOWS
925 /* The CRT of Windows has a number of flaws wrt. its stat() implementation:
926 - time stamps are restricted to second resolution
927 - file modification times suffer from forth-and-back conversions between
928 UTC and local time
929 Therefore, we implement our own stat, based on the Win32 API directly.
931 #define HAVE_STAT_NSEC 1
933 struct win32_stat{
934 int st_dev;
935 __int64 st_ino;
936 unsigned short st_mode;
937 int st_nlink;
938 int st_uid;
939 int st_gid;
940 int st_rdev;
941 __int64 st_size;
942 int st_atime;
943 int st_atime_nsec;
944 int st_mtime;
945 int st_mtime_nsec;
946 int st_ctime;
947 int st_ctime_nsec;
950 static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
952 static void
953 FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
955 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
956 /* Cannot simply cast and dereference in_ptr,
957 since it might not be aligned properly */
958 __int64 in;
959 memcpy(&in, in_ptr, sizeof(in));
960 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
961 /* XXX Win32 supports time stamps past 2038; we currently don't */
962 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
965 static void
966 time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
968 /* XXX endianness */
969 __int64 out;
970 out = time_in + secs_between_epochs;
971 out = out * 10000000 + nsec_in / 100;
972 memcpy(out_ptr, &out, sizeof(out));
975 /* Below, we *know* that ugo+r is 0444 */
976 #if _S_IREAD != 0400
977 #error Unsupported C library
978 #endif
979 static int
980 attributes_to_mode(DWORD attr)
982 int m = 0;
983 if (attr & FILE_ATTRIBUTE_DIRECTORY)
984 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
985 else
986 m |= _S_IFREG;
987 if (attr & FILE_ATTRIBUTE_READONLY)
988 m |= 0444;
989 else
990 m |= 0666;
991 return m;
994 static int
995 attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
997 memset(result, 0, sizeof(*result));
998 result->st_mode = attributes_to_mode(info->dwFileAttributes);
999 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1000 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1001 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1002 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1004 return 0;
1007 /* Emulate GetFileAttributesEx[AW] on Windows 95 */
1008 static int checked = 0;
1009 static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
1010 static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
1011 static void
1012 check_gfax()
1014 HINSTANCE hKernel32;
1015 if (checked)
1016 return;
1017 checked = 1;
1018 hKernel32 = GetModuleHandle("KERNEL32");
1019 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
1020 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
1023 static BOOL
1024 attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1026 HANDLE hFindFile;
1027 WIN32_FIND_DATAA FileData;
1028 hFindFile = FindFirstFileA(pszFile, &FileData);
1029 if (hFindFile == INVALID_HANDLE_VALUE)
1030 return FALSE;
1031 FindClose(hFindFile);
1032 pfad->dwFileAttributes = FileData.dwFileAttributes;
1033 pfad->ftCreationTime = FileData.ftCreationTime;
1034 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1035 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1036 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1037 pfad->nFileSizeLow = FileData.nFileSizeLow;
1038 return TRUE;
1041 static BOOL
1042 attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1044 HANDLE hFindFile;
1045 WIN32_FIND_DATAW FileData;
1046 hFindFile = FindFirstFileW(pszFile, &FileData);
1047 if (hFindFile == INVALID_HANDLE_VALUE)
1048 return FALSE;
1049 FindClose(hFindFile);
1050 pfad->dwFileAttributes = FileData.dwFileAttributes;
1051 pfad->ftCreationTime = FileData.ftCreationTime;
1052 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1053 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1054 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1055 pfad->nFileSizeLow = FileData.nFileSizeLow;
1056 return TRUE;
1059 static BOOL WINAPI
1060 Py_GetFileAttributesExA(LPCSTR pszFile,
1061 GET_FILEEX_INFO_LEVELS level,
1062 LPVOID pv)
1064 BOOL result;
1065 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1066 /* First try to use the system's implementation, if that is
1067 available and either succeeds to gives an error other than
1068 that it isn't implemented. */
1069 check_gfax();
1070 if (gfaxa) {
1071 result = gfaxa(pszFile, level, pv);
1072 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1073 return result;
1075 /* It's either not present, or not implemented.
1076 Emulate using FindFirstFile. */
1077 if (level != GetFileExInfoStandard) {
1078 SetLastError(ERROR_INVALID_PARAMETER);
1079 return FALSE;
1081 /* Use GetFileAttributes to validate that the file name
1082 does not contain wildcards (which FindFirstFile would
1083 accept). */
1084 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
1085 return FALSE;
1086 return attributes_from_dir(pszFile, pfad);
1089 static BOOL WINAPI
1090 Py_GetFileAttributesExW(LPCWSTR pszFile,
1091 GET_FILEEX_INFO_LEVELS level,
1092 LPVOID pv)
1094 BOOL result;
1095 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
1096 /* First try to use the system's implementation, if that is
1097 available and either succeeds to gives an error other than
1098 that it isn't implemented. */
1099 check_gfax();
1100 if (gfaxa) {
1101 result = gfaxw(pszFile, level, pv);
1102 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
1103 return result;
1105 /* It's either not present, or not implemented.
1106 Emulate using FindFirstFile. */
1107 if (level != GetFileExInfoStandard) {
1108 SetLastError(ERROR_INVALID_PARAMETER);
1109 return FALSE;
1111 /* Use GetFileAttributes to validate that the file name
1112 does not contain wildcards (which FindFirstFile would
1113 accept). */
1114 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
1115 return FALSE;
1116 return attributes_from_dir_w(pszFile, pfad);
1119 static int
1120 win32_stat(const char* path, struct win32_stat *result)
1122 WIN32_FILE_ATTRIBUTE_DATA info;
1123 int code;
1124 char *dot;
1125 /* XXX not supported on Win95 and NT 3.x */
1126 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1127 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1128 /* Protocol violation: we explicitly clear errno, instead of
1129 setting it to a POSIX error. Callers should use GetLastError. */
1130 errno = 0;
1131 return -1;
1132 } else {
1133 /* Could not get attributes on open file. Fall back to
1134 reading the directory. */
1135 if (!attributes_from_dir(path, &info)) {
1136 /* Very strange. This should not fail now */
1137 errno = 0;
1138 return -1;
1142 code = attribute_data_to_stat(&info, result);
1143 if (code != 0)
1144 return code;
1145 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1146 dot = strrchr(path, '.');
1147 if (dot) {
1148 if (stricmp(dot, ".bat") == 0 ||
1149 stricmp(dot, ".cmd") == 0 ||
1150 stricmp(dot, ".exe") == 0 ||
1151 stricmp(dot, ".com") == 0)
1152 result->st_mode |= 0111;
1154 return code;
1157 static int
1158 win32_wstat(const wchar_t* path, struct win32_stat *result)
1160 int code;
1161 const wchar_t *dot;
1162 WIN32_FILE_ATTRIBUTE_DATA info;
1163 /* XXX not supported on Win95 and NT 3.x */
1164 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1165 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1166 /* Protocol violation: we explicitly clear errno, instead of
1167 setting it to a POSIX error. Callers should use GetLastError. */
1168 errno = 0;
1169 return -1;
1170 } else {
1171 /* Could not get attributes on open file. Fall back to
1172 reading the directory. */
1173 if (!attributes_from_dir_w(path, &info)) {
1174 /* Very strange. This should not fail now */
1175 errno = 0;
1176 return -1;
1180 code = attribute_data_to_stat(&info, result);
1181 if (code < 0)
1182 return code;
1183 /* Set IFEXEC if it is an .exe, .bat, ... */
1184 dot = wcsrchr(path, '.');
1185 if (dot) {
1186 if (_wcsicmp(dot, L".bat") == 0 ||
1187 _wcsicmp(dot, L".cmd") == 0 ||
1188 _wcsicmp(dot, L".exe") == 0 ||
1189 _wcsicmp(dot, L".com") == 0)
1190 result->st_mode |= 0111;
1192 return code;
1195 static int
1196 win32_fstat(int file_number, struct win32_stat *result)
1198 BY_HANDLE_FILE_INFORMATION info;
1199 HANDLE h;
1200 int type;
1202 h = (HANDLE)_get_osfhandle(file_number);
1204 /* Protocol violation: we explicitly clear errno, instead of
1205 setting it to a POSIX error. Callers should use GetLastError. */
1206 errno = 0;
1208 if (h == INVALID_HANDLE_VALUE) {
1209 /* This is really a C library error (invalid file handle).
1210 We set the Win32 error to the closes one matching. */
1211 SetLastError(ERROR_INVALID_HANDLE);
1212 return -1;
1214 memset(result, 0, sizeof(*result));
1216 type = GetFileType(h);
1217 if (type == FILE_TYPE_UNKNOWN) {
1218 DWORD error = GetLastError();
1219 if (error != 0) {
1220 return -1;
1222 /* else: valid but unknown file */
1225 if (type != FILE_TYPE_DISK) {
1226 if (type == FILE_TYPE_CHAR)
1227 result->st_mode = _S_IFCHR;
1228 else if (type == FILE_TYPE_PIPE)
1229 result->st_mode = _S_IFIFO;
1230 return 0;
1233 if (!GetFileInformationByHandle(h, &info)) {
1234 return -1;
1237 /* similar to stat() */
1238 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1239 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1240 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1241 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1242 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1243 /* specific to fstat() */
1244 result->st_nlink = info.nNumberOfLinks;
1245 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1246 return 0;
1249 #endif /* MS_WINDOWS */
1251 PyDoc_STRVAR(stat_result__doc__,
1252 "stat_result: Result from stat or lstat.\n\n\
1253 This object may be accessed either as a tuple of\n\
1254 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
1255 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1257 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1258 or st_flags, they are available as attributes only.\n\
1260 See os.stat for more information.");
1262 static PyStructSequence_Field stat_result_fields[] = {
1263 {"st_mode", "protection bits"},
1264 {"st_ino", "inode"},
1265 {"st_dev", "device"},
1266 {"st_nlink", "number of hard links"},
1267 {"st_uid", "user ID of owner"},
1268 {"st_gid", "group ID of owner"},
1269 {"st_size", "total size, in bytes"},
1270 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1271 {NULL, "integer time of last access"},
1272 {NULL, "integer time of last modification"},
1273 {NULL, "integer time of last change"},
1274 {"st_atime", "time of last access"},
1275 {"st_mtime", "time of last modification"},
1276 {"st_ctime", "time of last change"},
1277 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1278 {"st_blksize", "blocksize for filesystem I/O"},
1279 #endif
1280 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1281 {"st_blocks", "number of blocks allocated"},
1282 #endif
1283 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1284 {"st_rdev", "device type (if inode device)"},
1285 #endif
1286 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1287 {"st_flags", "user defined flags for file"},
1288 #endif
1289 #ifdef HAVE_STRUCT_STAT_ST_GEN
1290 {"st_gen", "generation number"},
1291 #endif
1292 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1293 {"st_birthtime", "time of creation"},
1294 #endif
1298 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1299 #define ST_BLKSIZE_IDX 13
1300 #else
1301 #define ST_BLKSIZE_IDX 12
1302 #endif
1304 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1305 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1306 #else
1307 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1308 #endif
1310 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1311 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1312 #else
1313 #define ST_RDEV_IDX ST_BLOCKS_IDX
1314 #endif
1316 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1317 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1318 #else
1319 #define ST_FLAGS_IDX ST_RDEV_IDX
1320 #endif
1322 #ifdef HAVE_STRUCT_STAT_ST_GEN
1323 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
1324 #else
1325 #define ST_GEN_IDX ST_FLAGS_IDX
1326 #endif
1328 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1329 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1330 #else
1331 #define ST_BIRTHTIME_IDX ST_GEN_IDX
1332 #endif
1334 static PyStructSequence_Desc stat_result_desc = {
1335 "stat_result", /* name */
1336 stat_result__doc__, /* doc */
1337 stat_result_fields,
1341 PyDoc_STRVAR(statvfs_result__doc__,
1342 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
1343 This object may be accessed either as a tuple of\n\
1344 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
1345 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
1347 See os.statvfs for more information.");
1349 static PyStructSequence_Field statvfs_result_fields[] = {
1350 {"f_bsize", },
1351 {"f_frsize", },
1352 {"f_blocks", },
1353 {"f_bfree", },
1354 {"f_bavail", },
1355 {"f_files", },
1356 {"f_ffree", },
1357 {"f_favail", },
1358 {"f_flag", },
1359 {"f_namemax",},
1363 static PyStructSequence_Desc statvfs_result_desc = {
1364 "statvfs_result", /* name */
1365 statvfs_result__doc__, /* doc */
1366 statvfs_result_fields,
1370 static int initialized;
1371 static PyTypeObject StatResultType;
1372 static PyTypeObject StatVFSResultType;
1373 static newfunc structseq_new;
1375 static PyObject *
1376 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1378 PyStructSequence *result;
1379 int i;
1381 result = (PyStructSequence*)structseq_new(type, args, kwds);
1382 if (!result)
1383 return NULL;
1384 /* If we have been initialized from a tuple,
1385 st_?time might be set to None. Initialize it
1386 from the int slots. */
1387 for (i = 7; i <= 9; i++) {
1388 if (result->ob_item[i+3] == Py_None) {
1389 Py_DECREF(Py_None);
1390 Py_INCREF(result->ob_item[i]);
1391 result->ob_item[i+3] = result->ob_item[i];
1394 return (PyObject*)result;
1399 /* If true, st_?time is float. */
1400 static int _stat_float_times = 1;
1402 PyDoc_STRVAR(stat_float_times__doc__,
1403 "stat_float_times([newval]) -> oldval\n\n\
1404 Determine whether os.[lf]stat represents time stamps as float objects.\n\
1405 If newval is True, future calls to stat() return floats, if it is False,\n\
1406 future calls return ints. \n\
1407 If newval is omitted, return the current setting.\n");
1409 static PyObject*
1410 stat_float_times(PyObject* self, PyObject *args)
1412 int newval = -1;
1413 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1414 return NULL;
1415 if (newval == -1)
1416 /* Return old value */
1417 return PyBool_FromLong(_stat_float_times);
1418 _stat_float_times = newval;
1419 Py_INCREF(Py_None);
1420 return Py_None;
1423 static void
1424 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1426 PyObject *fval,*ival;
1427 #if SIZEOF_TIME_T > SIZEOF_LONG
1428 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
1429 #else
1430 ival = PyLong_FromLong((long)sec);
1431 #endif
1432 if (!ival)
1433 return;
1434 if (_stat_float_times) {
1435 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1436 } else {
1437 fval = ival;
1438 Py_INCREF(fval);
1440 PyStructSequence_SET_ITEM(v, index, ival);
1441 PyStructSequence_SET_ITEM(v, index+3, fval);
1444 /* pack a system stat C structure into the Python stat tuple
1445 (used by posix_stat() and posix_fstat()) */
1446 static PyObject*
1447 _pystat_fromstructstat(STRUCT_STAT *st)
1449 unsigned long ansec, mnsec, cnsec;
1450 PyObject *v = PyStructSequence_New(&StatResultType);
1451 if (v == NULL)
1452 return NULL;
1454 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
1455 #ifdef HAVE_LARGEFILE_SUPPORT
1456 PyStructSequence_SET_ITEM(v, 1,
1457 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
1458 #else
1459 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
1460 #endif
1461 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
1462 PyStructSequence_SET_ITEM(v, 2,
1463 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
1464 #else
1465 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
1466 #endif
1467 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
1468 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
1469 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
1470 #ifdef HAVE_LARGEFILE_SUPPORT
1471 PyStructSequence_SET_ITEM(v, 6,
1472 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
1473 #else
1474 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
1475 #endif
1477 #if defined(HAVE_STAT_TV_NSEC)
1478 ansec = st->st_atim.tv_nsec;
1479 mnsec = st->st_mtim.tv_nsec;
1480 cnsec = st->st_ctim.tv_nsec;
1481 #elif defined(HAVE_STAT_TV_NSEC2)
1482 ansec = st->st_atimespec.tv_nsec;
1483 mnsec = st->st_mtimespec.tv_nsec;
1484 cnsec = st->st_ctimespec.tv_nsec;
1485 #elif defined(HAVE_STAT_NSEC)
1486 ansec = st->st_atime_nsec;
1487 mnsec = st->st_mtime_nsec;
1488 cnsec = st->st_ctime_nsec;
1489 #else
1490 ansec = mnsec = cnsec = 0;
1491 #endif
1492 fill_time(v, 7, st->st_atime, ansec);
1493 fill_time(v, 8, st->st_mtime, mnsec);
1494 fill_time(v, 9, st->st_ctime, cnsec);
1496 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1497 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1498 PyLong_FromLong((long)st->st_blksize));
1499 #endif
1500 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1501 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1502 PyLong_FromLong((long)st->st_blocks));
1503 #endif
1504 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1505 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1506 PyLong_FromLong((long)st->st_rdev));
1507 #endif
1508 #ifdef HAVE_STRUCT_STAT_ST_GEN
1509 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1510 PyLong_FromLong((long)st->st_gen));
1511 #endif
1512 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1514 PyObject *val;
1515 unsigned long bsec,bnsec;
1516 bsec = (long)st->st_birthtime;
1517 #ifdef HAVE_STAT_TV_NSEC2
1518 bnsec = st->st_birthtimespec.tv_nsec;
1519 #else
1520 bnsec = 0;
1521 #endif
1522 if (_stat_float_times) {
1523 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1524 } else {
1525 val = PyLong_FromLong((long)bsec);
1527 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1528 val);
1530 #endif
1531 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1532 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1533 PyLong_FromLong((long)st->st_flags));
1534 #endif
1536 if (PyErr_Occurred()) {
1537 Py_DECREF(v);
1538 return NULL;
1541 return v;
1544 #ifdef MS_WINDOWS
1546 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1547 where / can be used in place of \ and the trailing slash is optional.
1548 Both SERVER and SHARE must have at least one character.
1551 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1552 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1553 #ifndef ARRAYSIZE
1554 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1555 #endif
1557 static BOOL
1558 IsUNCRootA(char *path, int pathlen)
1560 #define ISSLASH ISSLASHA
1562 int i, share;
1564 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1565 /* minimum UNCRoot is \\x\y */
1566 return FALSE;
1567 for (i = 2; i < pathlen ; i++)
1568 if (ISSLASH(path[i])) break;
1569 if (i == 2 || i == pathlen)
1570 /* do not allow \\\SHARE or \\SERVER */
1571 return FALSE;
1572 share = i+1;
1573 for (i = share; i < pathlen; i++)
1574 if (ISSLASH(path[i])) break;
1575 return (i != share && (i == pathlen || i == pathlen-1));
1577 #undef ISSLASH
1580 static BOOL
1581 IsUNCRootW(Py_UNICODE *path, int pathlen)
1583 #define ISSLASH ISSLASHW
1585 int i, share;
1587 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1588 /* minimum UNCRoot is \\x\y */
1589 return FALSE;
1590 for (i = 2; i < pathlen ; i++)
1591 if (ISSLASH(path[i])) break;
1592 if (i == 2 || i == pathlen)
1593 /* do not allow \\\SHARE or \\SERVER */
1594 return FALSE;
1595 share = i+1;
1596 for (i = share; i < pathlen; i++)
1597 if (ISSLASH(path[i])) break;
1598 return (i != share && (i == pathlen || i == pathlen-1));
1600 #undef ISSLASH
1602 #endif /* MS_WINDOWS */
1604 static PyObject *
1605 posix_do_stat(PyObject *self, PyObject *args,
1606 char *format,
1607 #ifdef __VMS
1608 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1609 #else
1610 int (*statfunc)(const char *, STRUCT_STAT *),
1611 #endif
1612 char *wformat,
1613 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
1615 STRUCT_STAT st;
1616 PyObject *opath;
1617 char *path;
1618 int res;
1619 PyObject *result;
1621 #ifdef MS_WINDOWS
1622 /* If on wide-character-capable OS see if argument
1623 is Unicode and if so use wide API. */
1624 if (unicode_file_names()) {
1625 PyUnicodeObject *po;
1626 if (PyArg_ParseTuple(args, wformat, &po)) {
1627 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1629 Py_BEGIN_ALLOW_THREADS
1630 /* PyUnicode_AS_UNICODE result OK without
1631 thread lock as it is a simple dereference. */
1632 res = wstatfunc(wpath, &st);
1633 Py_END_ALLOW_THREADS
1635 if (res != 0)
1636 return win32_error_unicode("stat", wpath);
1637 return _pystat_fromstructstat(&st);
1639 /* Drop the argument parsing error as narrow strings
1640 are also valid. */
1641 PyErr_Clear();
1643 #endif
1645 if (!PyArg_ParseTuple(args, format,
1646 PyUnicode_FSConverter, &opath))
1647 return NULL;
1648 path = bytes2str(opath, 1);
1649 Py_BEGIN_ALLOW_THREADS
1650 res = (*statfunc)(path, &st);
1651 Py_END_ALLOW_THREADS
1653 if (res != 0) {
1654 #ifdef MS_WINDOWS
1655 result = win32_error("stat", path);
1656 #else
1657 result = posix_error_with_filename(path);
1658 #endif
1660 else
1661 result = _pystat_fromstructstat(&st);
1663 release_bytes(opath);
1664 return result;
1667 /* POSIX methods */
1669 PyDoc_STRVAR(posix_access__doc__,
1670 "access(path, mode) -> True if granted, False otherwise\n\n\
1671 Use the real uid/gid to test for access to a path. Note that most\n\
1672 operations will use the effective uid/gid, therefore this routine can\n\
1673 be used in a suid/sgid environment to test if the invoking user has the\n\
1674 specified access to the path. The mode argument can be F_OK to test\n\
1675 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1677 static PyObject *
1678 posix_access(PyObject *self, PyObject *args)
1680 PyObject *opath;
1681 char *path;
1682 int mode;
1684 #ifdef MS_WINDOWS
1685 DWORD attr;
1686 if (unicode_file_names()) {
1687 PyUnicodeObject *po;
1688 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1689 Py_BEGIN_ALLOW_THREADS
1690 /* PyUnicode_AS_UNICODE OK without thread lock as
1691 it is a simple dereference. */
1692 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1693 Py_END_ALLOW_THREADS
1694 goto finish;
1696 /* Drop the argument parsing error as narrow strings
1697 are also valid. */
1698 PyErr_Clear();
1700 if (!PyArg_ParseTuple(args, "O&i:access",
1701 PyUnicode_FSConverter, &opath, &mode))
1702 return 0;
1703 path = bytes2str(opath, 1);
1704 Py_BEGIN_ALLOW_THREADS
1705 attr = GetFileAttributesA(path);
1706 Py_END_ALLOW_THREADS
1707 release_bytes(opath);
1708 finish:
1709 if (attr == 0xFFFFFFFF)
1710 /* File does not exist, or cannot read attributes */
1711 return PyBool_FromLong(0);
1712 /* Access is possible if either write access wasn't requested, or
1713 the file isn't read-only, or if it's a directory, as there are
1714 no read-only directories on Windows. */
1715 return PyBool_FromLong(!(mode & 2)
1716 || !(attr & FILE_ATTRIBUTE_READONLY)
1717 || (attr & FILE_ATTRIBUTE_DIRECTORY));
1718 #else
1719 int res;
1720 if (!PyArg_ParseTuple(args, "O&i:access",
1721 PyUnicode_FSConverter, &opath, &mode))
1722 return NULL;
1723 path = bytes2str(opath, 1);
1724 Py_BEGIN_ALLOW_THREADS
1725 res = access(path, mode);
1726 Py_END_ALLOW_THREADS
1727 release_bytes(opath);
1728 return PyBool_FromLong(res == 0);
1729 #endif
1732 #ifndef F_OK
1733 #define F_OK 0
1734 #endif
1735 #ifndef R_OK
1736 #define R_OK 4
1737 #endif
1738 #ifndef W_OK
1739 #define W_OK 2
1740 #endif
1741 #ifndef X_OK
1742 #define X_OK 1
1743 #endif
1745 #ifdef HAVE_TTYNAME
1746 PyDoc_STRVAR(posix_ttyname__doc__,
1747 "ttyname(fd) -> string\n\n\
1748 Return the name of the terminal device connected to 'fd'.");
1750 static PyObject *
1751 posix_ttyname(PyObject *self, PyObject *args)
1753 int id;
1754 char *ret;
1756 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1757 return NULL;
1759 #if defined(__VMS)
1760 /* file descriptor 0 only, the default input device (stdin) */
1761 if (id == 0) {
1762 ret = ttyname();
1764 else {
1765 ret = NULL;
1767 #else
1768 ret = ttyname(id);
1769 #endif
1770 if (ret == NULL)
1771 return posix_error();
1772 return PyUnicode_FromString(ret);
1774 #endif
1776 #ifdef HAVE_CTERMID
1777 PyDoc_STRVAR(posix_ctermid__doc__,
1778 "ctermid() -> string\n\n\
1779 Return the name of the controlling terminal for this process.");
1781 static PyObject *
1782 posix_ctermid(PyObject *self, PyObject *noargs)
1784 char *ret;
1785 char buffer[L_ctermid];
1787 #ifdef USE_CTERMID_R
1788 ret = ctermid_r(buffer);
1789 #else
1790 ret = ctermid(buffer);
1791 #endif
1792 if (ret == NULL)
1793 return posix_error();
1794 return PyUnicode_FromString(buffer);
1796 #endif
1798 PyDoc_STRVAR(posix_chdir__doc__,
1799 "chdir(path)\n\n\
1800 Change the current working directory to the specified path.");
1802 static PyObject *
1803 posix_chdir(PyObject *self, PyObject *args)
1805 #ifdef MS_WINDOWS
1806 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
1807 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1808 return posix_1str(args, "O&:chdir", _chdir2);
1809 #elif defined(__VMS)
1810 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir);
1811 #else
1812 return posix_1str(args, "O&:chdir", chdir);
1813 #endif
1816 #ifdef HAVE_FCHDIR
1817 PyDoc_STRVAR(posix_fchdir__doc__,
1818 "fchdir(fildes)\n\n\
1819 Change to the directory of the given file descriptor. fildes must be\n\
1820 opened on a directory, not a file.");
1822 static PyObject *
1823 posix_fchdir(PyObject *self, PyObject *fdobj)
1825 return posix_fildes(fdobj, fchdir);
1827 #endif /* HAVE_FCHDIR */
1830 PyDoc_STRVAR(posix_chmod__doc__,
1831 "chmod(path, mode)\n\n\
1832 Change the access permissions of a file.");
1834 static PyObject *
1835 posix_chmod(PyObject *self, PyObject *args)
1837 PyObject *opath = NULL;
1838 char *path = NULL;
1839 int i;
1840 int res;
1841 #ifdef MS_WINDOWS
1842 DWORD attr;
1843 if (unicode_file_names()) {
1844 PyUnicodeObject *po;
1845 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1846 Py_BEGIN_ALLOW_THREADS
1847 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1848 if (attr != 0xFFFFFFFF) {
1849 if (i & _S_IWRITE)
1850 attr &= ~FILE_ATTRIBUTE_READONLY;
1851 else
1852 attr |= FILE_ATTRIBUTE_READONLY;
1853 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1855 else
1856 res = 0;
1857 Py_END_ALLOW_THREADS
1858 if (!res)
1859 return win32_error_unicode("chmod",
1860 PyUnicode_AS_UNICODE(po));
1861 Py_INCREF(Py_None);
1862 return Py_None;
1864 /* Drop the argument parsing error as narrow strings
1865 are also valid. */
1866 PyErr_Clear();
1868 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1869 &opath, &i))
1870 return NULL;
1871 path = bytes2str(opath, 1);
1872 Py_BEGIN_ALLOW_THREADS
1873 attr = GetFileAttributesA(path);
1874 if (attr != 0xFFFFFFFF) {
1875 if (i & _S_IWRITE)
1876 attr &= ~FILE_ATTRIBUTE_READONLY;
1877 else
1878 attr |= FILE_ATTRIBUTE_READONLY;
1879 res = SetFileAttributesA(path, attr);
1881 else
1882 res = 0;
1883 Py_END_ALLOW_THREADS
1884 if (!res) {
1885 win32_error("chmod", path);
1886 release_bytes(opath);
1887 return NULL;
1889 release_bytes(opath);
1890 Py_INCREF(Py_None);
1891 return Py_None;
1892 #else /* MS_WINDOWS */
1893 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter,
1894 &opath, &i))
1895 return NULL;
1896 path = bytes2str(opath, 1);
1897 Py_BEGIN_ALLOW_THREADS
1898 res = chmod(path, i);
1899 Py_END_ALLOW_THREADS
1900 if (res < 0)
1901 return posix_error_with_allocated_filename(opath);
1902 release_bytes(opath);
1903 Py_INCREF(Py_None);
1904 return Py_None;
1905 #endif
1908 #ifdef HAVE_FCHMOD
1909 PyDoc_STRVAR(posix_fchmod__doc__,
1910 "fchmod(fd, mode)\n\n\
1911 Change the access permissions of the file given by file\n\
1912 descriptor fd.");
1914 static PyObject *
1915 posix_fchmod(PyObject *self, PyObject *args)
1917 int fd, mode, res;
1918 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1919 return NULL;
1920 Py_BEGIN_ALLOW_THREADS
1921 res = fchmod(fd, mode);
1922 Py_END_ALLOW_THREADS
1923 if (res < 0)
1924 return posix_error();
1925 Py_RETURN_NONE;
1927 #endif /* HAVE_FCHMOD */
1929 #ifdef HAVE_LCHMOD
1930 PyDoc_STRVAR(posix_lchmod__doc__,
1931 "lchmod(path, mode)\n\n\
1932 Change the access permissions of a file. If path is a symlink, this\n\
1933 affects the link itself rather than the target.");
1935 static PyObject *
1936 posix_lchmod(PyObject *self, PyObject *args)
1938 PyObject *opath;
1939 char *path;
1940 int i;
1941 int res;
1942 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter,
1943 &opath, &i))
1944 return NULL;
1945 path = bytes2str(opath, 1);
1946 Py_BEGIN_ALLOW_THREADS
1947 res = lchmod(path, i);
1948 Py_END_ALLOW_THREADS
1949 if (res < 0)
1950 return posix_error_with_allocated_filename(opath);
1951 release_bytes(opath);
1952 Py_RETURN_NONE;
1954 #endif /* HAVE_LCHMOD */
1957 #ifdef HAVE_CHFLAGS
1958 PyDoc_STRVAR(posix_chflags__doc__,
1959 "chflags(path, flags)\n\n\
1960 Set file flags.");
1962 static PyObject *
1963 posix_chflags(PyObject *self, PyObject *args)
1965 PyObject *opath;
1966 char *path;
1967 unsigned long flags;
1968 int res;
1969 if (!PyArg_ParseTuple(args, "O&k:chflags",
1970 PyUnicode_FSConverter, &opath, &flags))
1971 return NULL;
1972 path = bytes2str(opath, 1);
1973 Py_BEGIN_ALLOW_THREADS
1974 res = chflags(path, flags);
1975 Py_END_ALLOW_THREADS
1976 if (res < 0)
1977 return posix_error_with_allocated_filename(opath);
1978 release_bytes(opath);
1979 Py_INCREF(Py_None);
1980 return Py_None;
1982 #endif /* HAVE_CHFLAGS */
1984 #ifdef HAVE_LCHFLAGS
1985 PyDoc_STRVAR(posix_lchflags__doc__,
1986 "lchflags(path, flags)\n\n\
1987 Set file flags.\n\
1988 This function will not follow symbolic links.");
1990 static PyObject *
1991 posix_lchflags(PyObject *self, PyObject *args)
1993 PyObject *opath;
1994 char *path;
1995 unsigned long flags;
1996 int res;
1997 if (!PyArg_ParseTuple(args, "O&k:lchflags",
1998 PyUnicode_FSConverter, &opath, &flags))
1999 return NULL;
2000 path = bytes2str(opath, 1);
2001 Py_BEGIN_ALLOW_THREADS
2002 res = lchflags(path, flags);
2003 Py_END_ALLOW_THREADS
2004 if (res < 0)
2005 return posix_error_with_allocated_filename(opath);
2006 release_bytes(opath);
2007 Py_INCREF(Py_None);
2008 return Py_None;
2010 #endif /* HAVE_LCHFLAGS */
2012 #ifdef HAVE_CHROOT
2013 PyDoc_STRVAR(posix_chroot__doc__,
2014 "chroot(path)\n\n\
2015 Change root directory to path.");
2017 static PyObject *
2018 posix_chroot(PyObject *self, PyObject *args)
2020 return posix_1str(args, "O&:chroot", chroot);
2022 #endif
2024 #ifdef HAVE_FSYNC
2025 PyDoc_STRVAR(posix_fsync__doc__,
2026 "fsync(fildes)\n\n\
2027 force write of file with filedescriptor to disk.");
2029 static PyObject *
2030 posix_fsync(PyObject *self, PyObject *fdobj)
2032 return posix_fildes(fdobj, fsync);
2034 #endif /* HAVE_FSYNC */
2036 #ifdef HAVE_FDATASYNC
2038 #ifdef __hpux
2039 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2040 #endif
2042 PyDoc_STRVAR(posix_fdatasync__doc__,
2043 "fdatasync(fildes)\n\n\
2044 force write of file with filedescriptor to disk.\n\
2045 does not force update of metadata.");
2047 static PyObject *
2048 posix_fdatasync(PyObject *self, PyObject *fdobj)
2050 return posix_fildes(fdobj, fdatasync);
2052 #endif /* HAVE_FDATASYNC */
2055 #ifdef HAVE_CHOWN
2056 PyDoc_STRVAR(posix_chown__doc__,
2057 "chown(path, uid, gid)\n\n\
2058 Change the owner and group id of path to the numeric uid and gid.");
2060 static PyObject *
2061 posix_chown(PyObject *self, PyObject *args)
2063 PyObject *opath;
2064 char *path;
2065 long uid, gid;
2066 int res;
2067 if (!PyArg_ParseTuple(args, "O&ll:chown",
2068 PyUnicode_FSConverter, &opath,
2069 &uid, &gid))
2070 return NULL;
2071 path = bytes2str(opath, 1);
2072 Py_BEGIN_ALLOW_THREADS
2073 res = chown(path, (uid_t) uid, (gid_t) gid);
2074 Py_END_ALLOW_THREADS
2075 if (res < 0)
2076 return posix_error_with_allocated_filename(opath);
2077 release_bytes(opath);
2078 Py_INCREF(Py_None);
2079 return Py_None;
2081 #endif /* HAVE_CHOWN */
2083 #ifdef HAVE_FCHOWN
2084 PyDoc_STRVAR(posix_fchown__doc__,
2085 "fchown(fd, uid, gid)\n\n\
2086 Change the owner and group id of the file given by file descriptor\n\
2087 fd to the numeric uid and gid.");
2089 static PyObject *
2090 posix_fchown(PyObject *self, PyObject *args)
2092 int fd;
2093 long uid, gid;
2094 int res;
2095 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
2096 return NULL;
2097 Py_BEGIN_ALLOW_THREADS
2098 res = fchown(fd, (uid_t) uid, (gid_t) gid);
2099 Py_END_ALLOW_THREADS
2100 if (res < 0)
2101 return posix_error();
2102 Py_RETURN_NONE;
2104 #endif /* HAVE_FCHOWN */
2106 #ifdef HAVE_LCHOWN
2107 PyDoc_STRVAR(posix_lchown__doc__,
2108 "lchown(path, uid, gid)\n\n\
2109 Change the owner and group id of path to the numeric uid and gid.\n\
2110 This function will not follow symbolic links.");
2112 static PyObject *
2113 posix_lchown(PyObject *self, PyObject *args)
2115 PyObject *opath;
2116 char *path;
2117 long uid, gid;
2118 int res;
2119 if (!PyArg_ParseTuple(args, "O&ll:lchown",
2120 PyUnicode_FSConverter, &opath,
2121 &uid, &gid))
2122 return NULL;
2123 path = bytes2str(opath, 1);
2124 Py_BEGIN_ALLOW_THREADS
2125 res = lchown(path, (uid_t) uid, (gid_t) gid);
2126 Py_END_ALLOW_THREADS
2127 if (res < 0)
2128 return posix_error_with_allocated_filename(opath);
2129 release_bytes(opath);
2130 Py_INCREF(Py_None);
2131 return Py_None;
2133 #endif /* HAVE_LCHOWN */
2136 #ifdef HAVE_GETCWD
2137 static PyObject *
2138 posix_getcwd(int use_bytes)
2140 char buf[1026];
2141 char *res;
2143 #ifdef MS_WINDOWS
2144 if (!use_bytes && unicode_file_names()) {
2145 wchar_t wbuf[1026];
2146 wchar_t *wbuf2 = wbuf;
2147 PyObject *resobj;
2148 DWORD len;
2149 Py_BEGIN_ALLOW_THREADS
2150 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2151 /* If the buffer is large enough, len does not include the
2152 terminating \0. If the buffer is too small, len includes
2153 the space needed for the terminator. */
2154 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2155 wbuf2 = malloc(len * sizeof(wchar_t));
2156 if (wbuf2)
2157 len = GetCurrentDirectoryW(len, wbuf2);
2159 Py_END_ALLOW_THREADS
2160 if (!wbuf2) {
2161 PyErr_NoMemory();
2162 return NULL;
2164 if (!len) {
2165 if (wbuf2 != wbuf) free(wbuf2);
2166 return win32_error("getcwdu", NULL);
2168 resobj = PyUnicode_FromWideChar(wbuf2, len);
2169 if (wbuf2 != wbuf) free(wbuf2);
2170 return resobj;
2172 #endif
2174 Py_BEGIN_ALLOW_THREADS
2175 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2176 res = _getcwd2(buf, sizeof buf);
2177 #else
2178 res = getcwd(buf, sizeof buf);
2179 #endif
2180 Py_END_ALLOW_THREADS
2181 if (res == NULL)
2182 return posix_error();
2183 if (use_bytes)
2184 return PyBytes_FromStringAndSize(buf, strlen(buf));
2185 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"surrogateescape");
2188 PyDoc_STRVAR(posix_getcwd__doc__,
2189 "getcwd() -> path\n\n\
2190 Return a unicode string representing the current working directory.");
2192 static PyObject *
2193 posix_getcwd_unicode(PyObject *self)
2195 return posix_getcwd(0);
2198 PyDoc_STRVAR(posix_getcwdb__doc__,
2199 "getcwdb() -> path\n\n\
2200 Return a bytes string representing the current working directory.");
2202 static PyObject *
2203 posix_getcwd_bytes(PyObject *self)
2205 return posix_getcwd(1);
2207 #endif
2210 #ifdef HAVE_LINK
2211 PyDoc_STRVAR(posix_link__doc__,
2212 "link(src, dst)\n\n\
2213 Create a hard link to a file.");
2215 static PyObject *
2216 posix_link(PyObject *self, PyObject *args)
2218 return posix_2str(args, "O&O&:link", link);
2220 #endif /* HAVE_LINK */
2223 PyDoc_STRVAR(posix_listdir__doc__,
2224 "listdir(path) -> list_of_strings\n\n\
2225 Return a list containing the names of the entries in the directory.\n\
2227 path: path of directory to list\n\
2229 The list is in arbitrary order. It does not include the special\n\
2230 entries '.' and '..' even if they are present in the directory.");
2232 static PyObject *
2233 posix_listdir(PyObject *self, PyObject *args)
2235 /* XXX Should redo this putting the (now four) versions of opendir
2236 in separate files instead of having them all here... */
2237 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
2239 PyObject *d, *v;
2240 HANDLE hFindFile;
2241 BOOL result;
2242 WIN32_FIND_DATA FileData;
2243 PyObject *opath;
2244 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2245 char *bufptr = namebuf;
2246 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
2248 /* If on wide-character-capable OS see if argument
2249 is Unicode and if so use wide API. */
2250 if (unicode_file_names()) {
2251 PyObject *po;
2252 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2253 WIN32_FIND_DATAW wFileData;
2254 Py_UNICODE *wnamebuf;
2255 /* Overallocate for \\*.*\0 */
2256 len = PyUnicode_GET_SIZE(po);
2257 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2258 if (!wnamebuf) {
2259 PyErr_NoMemory();
2260 return NULL;
2262 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2263 if (len > 0) {
2264 Py_UNICODE wch = wnamebuf[len-1];
2265 if (wch != L'/' && wch != L'\\' && wch != L':')
2266 wnamebuf[len++] = L'\\';
2267 wcscpy(wnamebuf + len, L"*.*");
2269 if ((d = PyList_New(0)) == NULL) {
2270 free(wnamebuf);
2271 return NULL;
2273 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2274 if (hFindFile == INVALID_HANDLE_VALUE) {
2275 int error = GetLastError();
2276 if (error == ERROR_FILE_NOT_FOUND) {
2277 free(wnamebuf);
2278 return d;
2280 Py_DECREF(d);
2281 win32_error_unicode("FindFirstFileW", wnamebuf);
2282 free(wnamebuf);
2283 return NULL;
2285 do {
2286 /* Skip over . and .. */
2287 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2288 wcscmp(wFileData.cFileName, L"..") != 0) {
2289 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2290 if (v == NULL) {
2291 Py_DECREF(d);
2292 d = NULL;
2293 break;
2295 if (PyList_Append(d, v) != 0) {
2296 Py_DECREF(v);
2297 Py_DECREF(d);
2298 d = NULL;
2299 break;
2301 Py_DECREF(v);
2303 Py_BEGIN_ALLOW_THREADS
2304 result = FindNextFileW(hFindFile, &wFileData);
2305 Py_END_ALLOW_THREADS
2306 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2307 it got to the end of the directory. */
2308 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2309 Py_DECREF(d);
2310 win32_error_unicode("FindNextFileW", wnamebuf);
2311 FindClose(hFindFile);
2312 free(wnamebuf);
2313 return NULL;
2315 } while (result == TRUE);
2317 if (FindClose(hFindFile) == FALSE) {
2318 Py_DECREF(d);
2319 win32_error_unicode("FindClose", wnamebuf);
2320 free(wnamebuf);
2321 return NULL;
2323 free(wnamebuf);
2324 return d;
2326 /* Drop the argument parsing error as narrow strings
2327 are also valid. */
2328 PyErr_Clear();
2331 if (!PyArg_ParseTuple(args, "O&:listdir",
2332 PyUnicode_FSConverter, &opath))
2333 return NULL;
2334 if (PyObject_Size(opath)+1 > MAX_PATH) {
2335 PyErr_SetString(PyExc_ValueError, "path too long");
2336 Py_DECREF(opath);
2337 return NULL;
2339 strcpy(namebuf, bytes2str(opath, 0));
2340 len = PyObject_Size(opath);
2341 if (len > 0) {
2342 char ch = namebuf[len-1];
2343 if (ch != SEP && ch != ALTSEP && ch != ':')
2344 namebuf[len++] = '/';
2345 strcpy(namebuf + len, "*.*");
2348 if ((d = PyList_New(0)) == NULL)
2349 return NULL;
2351 hFindFile = FindFirstFile(namebuf, &FileData);
2352 if (hFindFile == INVALID_HANDLE_VALUE) {
2353 int error = GetLastError();
2354 if (error == ERROR_FILE_NOT_FOUND)
2355 return d;
2356 Py_DECREF(d);
2357 return win32_error("FindFirstFile", namebuf);
2359 do {
2360 /* Skip over . and .. */
2361 if (strcmp(FileData.cFileName, ".") != 0 &&
2362 strcmp(FileData.cFileName, "..") != 0) {
2363 v = PyBytes_FromString(FileData.cFileName);
2364 if (v == NULL) {
2365 Py_DECREF(d);
2366 d = NULL;
2367 break;
2369 if (PyList_Append(d, v) != 0) {
2370 Py_DECREF(v);
2371 Py_DECREF(d);
2372 d = NULL;
2373 break;
2375 Py_DECREF(v);
2377 Py_BEGIN_ALLOW_THREADS
2378 result = FindNextFile(hFindFile, &FileData);
2379 Py_END_ALLOW_THREADS
2380 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2381 it got to the end of the directory. */
2382 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2383 Py_DECREF(d);
2384 win32_error("FindNextFile", namebuf);
2385 FindClose(hFindFile);
2386 return NULL;
2388 } while (result == TRUE);
2390 if (FindClose(hFindFile) == FALSE) {
2391 Py_DECREF(d);
2392 return win32_error("FindClose", namebuf);
2395 return d;
2397 #elif defined(PYOS_OS2)
2399 #ifndef MAX_PATH
2400 #define MAX_PATH CCHMAXPATH
2401 #endif
2402 PyObject *oname;
2403 char *name, *pt;
2404 Py_ssize_t len;
2405 PyObject *d, *v;
2406 char namebuf[MAX_PATH+5];
2407 HDIR hdir = 1;
2408 ULONG srchcnt = 1;
2409 FILEFINDBUF3 ep;
2410 APIRET rc;
2412 if (!PyArg_ParseTuple(args, "O&:listdir",
2413 PyUnicode_FSConverter, &oname))
2414 return NULL;
2415 name = bytes2str(oname);
2416 len = PyObject_Size(oname);
2417 if (len >= MAX_PATH) {
2418 release_bytes(oname);
2419 PyErr_SetString(PyExc_ValueError, "path too long");
2420 return NULL;
2422 strcpy(namebuf, name);
2423 for (pt = namebuf; *pt; pt++)
2424 if (*pt == ALTSEP)
2425 *pt = SEP;
2426 if (namebuf[len-1] != SEP)
2427 namebuf[len++] = SEP;
2428 strcpy(namebuf + len, "*.*");
2430 if ((d = PyList_New(0)) == NULL) {
2431 release_bytes(oname);
2432 return NULL;
2435 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2436 &hdir, /* Handle to Use While Search Directory */
2437 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
2438 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2439 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2440 FIL_STANDARD); /* Format of Entry (EAs or Not) */
2442 if (rc != NO_ERROR) {
2443 errno = ENOENT;
2444 return posix_error_with_allocated_filename(oname);
2447 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
2448 do {
2449 if (ep.achName[0] == '.'
2450 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
2451 continue; /* Skip Over "." and ".." Names */
2453 strcpy(namebuf, ep.achName);
2455 /* Leave Case of Name Alone -- In Native Form */
2456 /* (Removed Forced Lowercasing Code) */
2458 v = PyBytes_FromString(namebuf);
2459 if (v == NULL) {
2460 Py_DECREF(d);
2461 d = NULL;
2462 break;
2464 if (PyList_Append(d, v) != 0) {
2465 Py_DECREF(v);
2466 Py_DECREF(d);
2467 d = NULL;
2468 break;
2470 Py_DECREF(v);
2471 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2474 release_bytes(oname);
2475 return d;
2476 #else
2477 PyObject *oname;
2478 char *name;
2479 PyObject *d, *v;
2480 DIR *dirp;
2481 struct dirent *ep;
2482 int arg_is_unicode = 1;
2484 errno = 0;
2485 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2486 arg_is_unicode = 0;
2487 PyErr_Clear();
2489 if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname))
2490 return NULL;
2491 name = bytes2str(oname, 1);
2492 if ((dirp = opendir(name)) == NULL) {
2493 return posix_error_with_allocated_filename(oname);
2495 if ((d = PyList_New(0)) == NULL) {
2496 closedir(dirp);
2497 release_bytes(oname);
2498 return NULL;
2500 for (;;) {
2501 errno = 0;
2502 Py_BEGIN_ALLOW_THREADS
2503 ep = readdir(dirp);
2504 Py_END_ALLOW_THREADS
2505 if (ep == NULL) {
2506 if (errno == 0) {
2507 break;
2508 } else {
2509 closedir(dirp);
2510 Py_DECREF(d);
2511 return posix_error_with_allocated_filename(oname);
2514 if (ep->d_name[0] == '.' &&
2515 (NAMLEN(ep) == 1 ||
2516 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2517 continue;
2518 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
2519 if (v == NULL) {
2520 Py_DECREF(d);
2521 d = NULL;
2522 break;
2524 if (arg_is_unicode) {
2525 PyObject *w;
2527 w = PyUnicode_FromEncodedObject(v,
2528 Py_FileSystemDefaultEncoding,
2529 "surrogateescape");
2530 Py_DECREF(v);
2531 if (w != NULL)
2532 v = w;
2533 else {
2534 /* Encoding failed to decode ASCII bytes.
2535 Raise exception. */
2536 Py_DECREF(d);
2537 d = NULL;
2538 break;
2541 if (PyList_Append(d, v) != 0) {
2542 Py_DECREF(v);
2543 Py_DECREF(d);
2544 d = NULL;
2545 break;
2547 Py_DECREF(v);
2549 closedir(dirp);
2550 release_bytes(oname);
2552 return d;
2554 #endif /* which OS */
2555 } /* end of posix_listdir */
2557 #ifdef MS_WINDOWS
2558 /* A helper function for abspath on win32 */
2559 static PyObject *
2560 posix__getfullpathname(PyObject *self, PyObject *args)
2562 PyObject *opath;
2563 char *path;
2564 char outbuf[MAX_PATH*2];
2565 char *temp;
2566 #ifdef MS_WINDOWS
2567 if (unicode_file_names()) {
2568 PyUnicodeObject *po;
2569 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2570 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2571 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2572 Py_UNICODE *wtemp;
2573 DWORD result;
2574 PyObject *v;
2575 result = GetFullPathNameW(wpath,
2576 sizeof(woutbuf)/sizeof(woutbuf[0]),
2577 woutbuf, &wtemp);
2578 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2579 woutbufp = malloc(result * sizeof(Py_UNICODE));
2580 if (!woutbufp)
2581 return PyErr_NoMemory();
2582 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2584 if (result)
2585 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2586 else
2587 v = win32_error_unicode("GetFullPathNameW", wpath);
2588 if (woutbufp != woutbuf)
2589 free(woutbufp);
2590 return v;
2592 /* Drop the argument parsing error as narrow strings
2593 are also valid. */
2594 PyErr_Clear();
2596 #endif
2597 if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
2598 PyUnicode_FSConverter, &opath))
2599 return NULL;
2600 path = bytes2str(opath, 1);
2601 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]),
2602 outbuf, &temp)) {
2603 win32_error("GetFullPathName", path);
2604 release_bytes(opath);
2605 return NULL;
2607 release_bytes(opath);
2608 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2609 return PyUnicode_Decode(outbuf, strlen(outbuf),
2610 Py_FileSystemDefaultEncoding, NULL);
2612 return PyBytes_FromString(outbuf);
2613 } /* end of posix__getfullpathname */
2614 #endif /* MS_WINDOWS */
2616 PyDoc_STRVAR(posix_mkdir__doc__,
2617 "mkdir(path [, mode=0777])\n\n\
2618 Create a directory.");
2620 static PyObject *
2621 posix_mkdir(PyObject *self, PyObject *args)
2623 int res;
2624 PyObject *opath;
2625 char *path;
2626 int mode = 0777;
2628 #ifdef MS_WINDOWS
2629 if (unicode_file_names()) {
2630 PyUnicodeObject *po;
2631 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2632 Py_BEGIN_ALLOW_THREADS
2633 /* PyUnicode_AS_UNICODE OK without thread lock as
2634 it is a simple dereference. */
2635 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2636 Py_END_ALLOW_THREADS
2637 if (!res)
2638 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2639 Py_INCREF(Py_None);
2640 return Py_None;
2642 /* Drop the argument parsing error as narrow strings
2643 are also valid. */
2644 PyErr_Clear();
2646 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2647 PyUnicode_FSConverter, &opath, &mode))
2648 return NULL;
2649 path = bytes2str(opath, 1);
2650 Py_BEGIN_ALLOW_THREADS
2651 /* PyUnicode_AS_UNICODE OK without thread lock as
2652 it is a simple dereference. */
2653 res = CreateDirectoryA(path, NULL);
2654 Py_END_ALLOW_THREADS
2655 if (!res) {
2656 win32_error("mkdir", path);
2657 release_bytes(opath);
2658 return NULL;
2660 release_bytes(opath);
2661 Py_INCREF(Py_None);
2662 return Py_None;
2663 #else
2665 if (!PyArg_ParseTuple(args, "O&|i:mkdir",
2666 PyUnicode_FSConverter, &opath, &mode))
2667 return NULL;
2668 path = bytes2str(opath, 1);
2669 Py_BEGIN_ALLOW_THREADS
2670 #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
2671 res = mkdir(path);
2672 #else
2673 res = mkdir(path, mode);
2674 #endif
2675 Py_END_ALLOW_THREADS
2676 if (res < 0)
2677 return posix_error_with_allocated_filename(opath);
2678 release_bytes(opath);
2679 Py_INCREF(Py_None);
2680 return Py_None;
2681 #endif
2685 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2686 #if defined(HAVE_SYS_RESOURCE_H)
2687 #include <sys/resource.h>
2688 #endif
2691 #ifdef HAVE_NICE
2692 PyDoc_STRVAR(posix_nice__doc__,
2693 "nice(inc) -> new_priority\n\n\
2694 Decrease the priority of process by inc and return the new priority.");
2696 static PyObject *
2697 posix_nice(PyObject *self, PyObject *args)
2699 int increment, value;
2701 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2702 return NULL;
2704 /* There are two flavours of 'nice': one that returns the new
2705 priority (as required by almost all standards out there) and the
2706 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2707 the use of getpriority() to get the new priority.
2709 If we are of the nice family that returns the new priority, we
2710 need to clear errno before the call, and check if errno is filled
2711 before calling posix_error() on a returnvalue of -1, because the
2712 -1 may be the actual new priority! */
2714 errno = 0;
2715 value = nice(increment);
2716 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
2717 if (value == 0)
2718 value = getpriority(PRIO_PROCESS, 0);
2719 #endif
2720 if (value == -1 && errno != 0)
2721 /* either nice() or getpriority() returned an error */
2722 return posix_error();
2723 return PyLong_FromLong((long) value);
2725 #endif /* HAVE_NICE */
2727 PyDoc_STRVAR(posix_rename__doc__,
2728 "rename(old, new)\n\n\
2729 Rename a file or directory.");
2731 static PyObject *
2732 posix_rename(PyObject *self, PyObject *args)
2734 #ifdef MS_WINDOWS
2735 PyObject *o1, *o2;
2736 char *p1, *p2;
2737 BOOL result;
2738 if (unicode_file_names()) {
2739 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2740 goto error;
2741 if (!convert_to_unicode(&o1))
2742 goto error;
2743 if (!convert_to_unicode(&o2)) {
2744 Py_DECREF(o1);
2745 goto error;
2747 Py_BEGIN_ALLOW_THREADS
2748 result = MoveFileW(PyUnicode_AsUnicode(o1),
2749 PyUnicode_AsUnicode(o2));
2750 Py_END_ALLOW_THREADS
2751 Py_DECREF(o1);
2752 Py_DECREF(o2);
2753 if (!result)
2754 return win32_error("rename", NULL);
2755 Py_INCREF(Py_None);
2756 return Py_None;
2757 error:
2758 PyErr_Clear();
2760 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2761 return NULL;
2762 Py_BEGIN_ALLOW_THREADS
2763 result = MoveFileA(p1, p2);
2764 Py_END_ALLOW_THREADS
2765 if (!result)
2766 return win32_error("rename", NULL);
2767 Py_INCREF(Py_None);
2768 return Py_None;
2769 #else
2770 return posix_2str(args, "O&O&:rename", rename);
2771 #endif
2775 PyDoc_STRVAR(posix_rmdir__doc__,
2776 "rmdir(path)\n\n\
2777 Remove a directory.");
2779 static PyObject *
2780 posix_rmdir(PyObject *self, PyObject *args)
2782 #ifdef MS_WINDOWS
2783 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
2784 #else
2785 return posix_1str(args, "O&:rmdir", rmdir);
2786 #endif
2790 PyDoc_STRVAR(posix_stat__doc__,
2791 "stat(path) -> stat result\n\n\
2792 Perform a stat system call on the given path.");
2794 static PyObject *
2795 posix_stat(PyObject *self, PyObject *args)
2797 #ifdef MS_WINDOWS
2798 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_wstat);
2799 #else
2800 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL);
2801 #endif
2805 #ifdef HAVE_SYSTEM
2806 PyDoc_STRVAR(posix_system__doc__,
2807 "system(command) -> exit_status\n\n\
2808 Execute the command (a string) in a subshell.");
2810 static PyObject *
2811 posix_system(PyObject *self, PyObject *args)
2813 long sts;
2814 #ifdef MS_WINDOWS
2815 wchar_t *command;
2816 if (!PyArg_ParseTuple(args, "u:system", &command))
2817 return NULL;
2819 Py_BEGIN_ALLOW_THREADS
2820 sts = _wsystem(command);
2821 Py_END_ALLOW_THREADS
2822 #else
2823 PyObject *command_obj;
2824 char *command;
2825 if (!PyArg_ParseTuple(args, "O&:system",
2826 PyUnicode_FSConverter, &command_obj))
2827 return NULL;
2829 command = bytes2str(command_obj, 1);
2830 Py_BEGIN_ALLOW_THREADS
2831 sts = system(command);
2832 Py_END_ALLOW_THREADS
2833 release_bytes(command_obj);
2834 #endif
2835 return PyLong_FromLong(sts);
2837 #endif
2840 PyDoc_STRVAR(posix_umask__doc__,
2841 "umask(new_mask) -> old_mask\n\n\
2842 Set the current numeric umask and return the previous umask.");
2844 static PyObject *
2845 posix_umask(PyObject *self, PyObject *args)
2847 int i;
2848 if (!PyArg_ParseTuple(args, "i:umask", &i))
2849 return NULL;
2850 i = (int)umask(i);
2851 if (i < 0)
2852 return posix_error();
2853 return PyLong_FromLong((long)i);
2857 PyDoc_STRVAR(posix_unlink__doc__,
2858 "unlink(path)\n\n\
2859 Remove a file (same as remove(path)).");
2861 PyDoc_STRVAR(posix_remove__doc__,
2862 "remove(path)\n\n\
2863 Remove a file (same as unlink(path)).");
2865 static PyObject *
2866 posix_unlink(PyObject *self, PyObject *args)
2868 #ifdef MS_WINDOWS
2869 return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
2870 #else
2871 return posix_1str(args, "O&:remove", unlink);
2872 #endif
2876 #ifdef HAVE_UNAME
2877 PyDoc_STRVAR(posix_uname__doc__,
2878 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2879 Return a tuple identifying the current operating system.");
2881 static PyObject *
2882 posix_uname(PyObject *self, PyObject *noargs)
2884 struct utsname u;
2885 int res;
2887 Py_BEGIN_ALLOW_THREADS
2888 res = uname(&u);
2889 Py_END_ALLOW_THREADS
2890 if (res < 0)
2891 return posix_error();
2892 return Py_BuildValue("(sssss)",
2893 u.sysname,
2894 u.nodename,
2895 u.release,
2896 u.version,
2897 u.machine);
2899 #endif /* HAVE_UNAME */
2901 static int
2902 extract_time(PyObject *t, long* sec, long* usec)
2904 long intval;
2905 if (PyFloat_Check(t)) {
2906 double tval = PyFloat_AsDouble(t);
2907 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
2908 if (!intobj)
2909 return -1;
2910 intval = PyLong_AsLong(intobj);
2911 Py_DECREF(intobj);
2912 if (intval == -1 && PyErr_Occurred())
2913 return -1;
2914 *sec = intval;
2915 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2916 if (*usec < 0)
2917 /* If rounding gave us a negative number,
2918 truncate. */
2919 *usec = 0;
2920 return 0;
2922 intval = PyLong_AsLong(t);
2923 if (intval == -1 && PyErr_Occurred())
2924 return -1;
2925 *sec = intval;
2926 *usec = 0;
2927 return 0;
2930 PyDoc_STRVAR(posix_utime__doc__,
2931 "utime(path, (atime, mtime))\n\
2932 utime(path, None)\n\n\
2933 Set the access and modified time of the file to the given values. If the\n\
2934 second form is used, set the access and modified times to the current time.");
2936 static PyObject *
2937 posix_utime(PyObject *self, PyObject *args)
2939 #ifdef MS_WINDOWS
2940 PyObject *arg;
2941 PyUnicodeObject *obwpath;
2942 wchar_t *wpath = NULL;
2943 PyObject *oapath;
2944 char *apath;
2945 HANDLE hFile;
2946 long atimesec, mtimesec, ausec, musec;
2947 FILETIME atime, mtime;
2948 PyObject *result = NULL;
2950 if (unicode_file_names()) {
2951 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2952 wpath = PyUnicode_AS_UNICODE(obwpath);
2953 Py_BEGIN_ALLOW_THREADS
2954 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2955 NULL, OPEN_EXISTING,
2956 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2957 Py_END_ALLOW_THREADS
2958 if (hFile == INVALID_HANDLE_VALUE)
2959 return win32_error_unicode("utime", wpath);
2960 } else
2961 /* Drop the argument parsing error as narrow strings
2962 are also valid. */
2963 PyErr_Clear();
2965 if (!wpath) {
2966 if (!PyArg_ParseTuple(args, "O&O:utime",
2967 PyUnicode_FSConverter, &oapath, &arg))
2968 return NULL;
2969 apath = bytes2str(oapath, 1);
2970 Py_BEGIN_ALLOW_THREADS
2971 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2972 NULL, OPEN_EXISTING,
2973 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2974 Py_END_ALLOW_THREADS
2975 if (hFile == INVALID_HANDLE_VALUE) {
2976 win32_error("utime", apath);
2977 release_bytes(oapath);
2978 return NULL;
2980 release_bytes(oapath);
2983 if (arg == Py_None) {
2984 SYSTEMTIME now;
2985 GetSystemTime(&now);
2986 if (!SystemTimeToFileTime(&now, &mtime) ||
2987 !SystemTimeToFileTime(&now, &atime)) {
2988 win32_error("utime", NULL);
2989 goto done;
2992 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2993 PyErr_SetString(PyExc_TypeError,
2994 "utime() arg 2 must be a tuple (atime, mtime)");
2995 goto done;
2997 else {
2998 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2999 &atimesec, &ausec) == -1)
3000 goto done;
3001 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3002 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3003 &mtimesec, &musec) == -1)
3004 goto done;
3005 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3007 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3008 /* Avoid putting the file name into the error here,
3009 as that may confuse the user into believing that
3010 something is wrong with the file, when it also
3011 could be the time stamp that gives a problem. */
3012 win32_error("utime", NULL);
3014 Py_INCREF(Py_None);
3015 result = Py_None;
3016 done:
3017 CloseHandle(hFile);
3018 return result;
3019 #else /* MS_WINDOWS */
3021 PyObject *opath;
3022 char *path;
3023 long atime, mtime, ausec, musec;
3024 int res;
3025 PyObject* arg;
3027 #if defined(HAVE_UTIMES)
3028 struct timeval buf[2];
3029 #define ATIME buf[0].tv_sec
3030 #define MTIME buf[1].tv_sec
3031 #elif defined(HAVE_UTIME_H)
3032 /* XXX should define struct utimbuf instead, above */
3033 struct utimbuf buf;
3034 #define ATIME buf.actime
3035 #define MTIME buf.modtime
3036 #define UTIME_ARG &buf
3037 #else /* HAVE_UTIMES */
3038 time_t buf[2];
3039 #define ATIME buf[0]
3040 #define MTIME buf[1]
3041 #define UTIME_ARG buf
3042 #endif /* HAVE_UTIMES */
3045 if (!PyArg_ParseTuple(args, "O&O:utime",
3046 PyUnicode_FSConverter, &opath, &arg))
3047 return NULL;
3048 path = bytes2str(opath, 1);
3049 if (arg == Py_None) {
3050 /* optional time values not given */
3051 Py_BEGIN_ALLOW_THREADS
3052 res = utime(path, NULL);
3053 Py_END_ALLOW_THREADS
3055 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3056 PyErr_SetString(PyExc_TypeError,
3057 "utime() arg 2 must be a tuple (atime, mtime)");
3058 release_bytes(opath);
3059 return NULL;
3061 else {
3062 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3063 &atime, &ausec) == -1) {
3064 release_bytes(opath);
3065 return NULL;
3067 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3068 &mtime, &musec) == -1) {
3069 release_bytes(opath);
3070 return NULL;
3072 ATIME = atime;
3073 MTIME = mtime;
3074 #ifdef HAVE_UTIMES
3075 buf[0].tv_usec = ausec;
3076 buf[1].tv_usec = musec;
3077 Py_BEGIN_ALLOW_THREADS
3078 res = utimes(path, buf);
3079 Py_END_ALLOW_THREADS
3080 #else
3081 Py_BEGIN_ALLOW_THREADS
3082 res = utime(path, UTIME_ARG);
3083 Py_END_ALLOW_THREADS
3084 #endif /* HAVE_UTIMES */
3086 if (res < 0) {
3087 return posix_error_with_allocated_filename(opath);
3089 release_bytes(opath);
3090 Py_INCREF(Py_None);
3091 return Py_None;
3092 #undef UTIME_ARG
3093 #undef ATIME
3094 #undef MTIME
3095 #endif /* MS_WINDOWS */
3099 /* Process operations */
3101 PyDoc_STRVAR(posix__exit__doc__,
3102 "_exit(status)\n\n\
3103 Exit to the system with specified status, without normal exit processing.");
3105 static PyObject *
3106 posix__exit(PyObject *self, PyObject *args)
3108 int sts;
3109 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3110 return NULL;
3111 _exit(sts);
3112 return NULL; /* Make gcc -Wall happy */
3115 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3116 static void
3117 free_string_array(char **array, Py_ssize_t count)
3119 Py_ssize_t i;
3120 for (i = 0; i < count; i++)
3121 PyMem_Free(array[i]);
3122 PyMem_DEL(array);
3125 static
3126 int fsconvert_strdup(PyObject *o, char**out)
3128 PyObject *bytes;
3129 Py_ssize_t size;
3130 if (!PyUnicode_FSConverter(o, &bytes))
3131 return 0;
3132 size = PyObject_Size(bytes);
3133 *out = PyMem_Malloc(size+1);
3134 if (!*out)
3135 return 0;
3136 /* Don't lock bytes, as we hold the GIL */
3137 memcpy(*out, bytes2str(bytes, 0), size+1);
3138 Py_DECREF(bytes);
3139 return 1;
3141 #endif
3144 #ifdef HAVE_EXECV
3145 PyDoc_STRVAR(posix_execv__doc__,
3146 "execv(path, args)\n\n\
3147 Execute an executable path with arguments, replacing current process.\n\
3149 path: path of executable file\n\
3150 args: tuple or list of strings");
3152 static PyObject *
3153 posix_execv(PyObject *self, PyObject *args)
3155 PyObject *opath;
3156 char *path;
3157 PyObject *argv;
3158 char **argvlist;
3159 Py_ssize_t i, argc;
3160 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3162 /* execv has two arguments: (path, argv), where
3163 argv is a list or tuple of strings. */
3165 if (!PyArg_ParseTuple(args, "O&O:execv",
3166 PyUnicode_FSConverter,
3167 &opath, &argv))
3168 return NULL;
3169 path = bytes2str(opath, 1);
3170 if (PyList_Check(argv)) {
3171 argc = PyList_Size(argv);
3172 getitem = PyList_GetItem;
3174 else if (PyTuple_Check(argv)) {
3175 argc = PyTuple_Size(argv);
3176 getitem = PyTuple_GetItem;
3178 else {
3179 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3180 release_bytes(opath);
3181 return NULL;
3183 if (argc < 1) {
3184 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3185 release_bytes(opath);
3186 return NULL;
3189 argvlist = PyMem_NEW(char *, argc+1);
3190 if (argvlist == NULL) {
3191 release_bytes(opath);
3192 return PyErr_NoMemory();
3194 for (i = 0; i < argc; i++) {
3195 if (!fsconvert_strdup((*getitem)(argv, i),
3196 &argvlist[i])) {
3197 free_string_array(argvlist, i);
3198 PyErr_SetString(PyExc_TypeError,
3199 "execv() arg 2 must contain only strings");
3200 release_bytes(opath);
3201 return NULL;
3205 argvlist[argc] = NULL;
3207 execv(path, argvlist);
3209 /* If we get here it's definitely an error */
3211 free_string_array(argvlist, argc);
3212 release_bytes(opath);
3213 return posix_error();
3216 static char**
3217 parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
3219 char **envlist;
3220 Py_ssize_t i, pos, envc;
3221 PyObject *keys=NULL, *vals=NULL;
3222 PyObject *key, *val, *key2, *val2;
3223 char *p, *k, *v;
3224 size_t len;
3226 i = PyMapping_Size(env);
3227 if (i < 0)
3228 return NULL;
3229 envlist = PyMem_NEW(char *, i + 1);
3230 if (envlist == NULL) {
3231 PyErr_NoMemory();
3232 return NULL;
3234 envc = 0;
3235 keys = PyMapping_Keys(env);
3236 vals = PyMapping_Values(env);
3237 if (!keys || !vals)
3238 goto error;
3239 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3240 PyErr_Format(PyExc_TypeError,
3241 "env.keys() or env.values() is not a list");
3242 goto error;
3245 for (pos = 0; pos < i; pos++) {
3246 key = PyList_GetItem(keys, pos);
3247 val = PyList_GetItem(vals, pos);
3248 if (!key || !val)
3249 goto error;
3251 if (PyUnicode_FSConverter(key, &key2) == 0)
3252 goto error;
3253 if (PyUnicode_FSConverter(val, &val2) == 0) {
3254 Py_DECREF(key2);
3255 goto error;
3258 #if defined(PYOS_OS2)
3259 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3260 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3261 #endif
3262 k = PyBytes_AsString(key2);
3263 v = PyBytes_AsString(val2);
3264 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
3266 p = PyMem_NEW(char, len);
3267 if (p == NULL) {
3268 PyErr_NoMemory();
3269 Py_DECREF(key2);
3270 Py_DECREF(val2);
3271 goto error;
3273 PyOS_snprintf(p, len, "%s=%s", k, v);
3274 envlist[envc++] = p;
3275 Py_DECREF(key2);
3276 Py_DECREF(val2);
3277 #if defined(PYOS_OS2)
3279 #endif
3281 Py_DECREF(vals);
3282 Py_DECREF(keys);
3284 envlist[envc] = 0;
3285 *envc_ptr = envc;
3286 return envlist;
3288 error:
3289 Py_XDECREF(keys);
3290 Py_XDECREF(vals);
3291 while (--envc >= 0)
3292 PyMem_DEL(envlist[envc]);
3293 PyMem_DEL(envlist);
3294 return NULL;
3297 PyDoc_STRVAR(posix_execve__doc__,
3298 "execve(path, args, env)\n\n\
3299 Execute a path with arguments and environment, replacing current process.\n\
3301 path: path of executable file\n\
3302 args: tuple or list of arguments\n\
3303 env: dictionary of strings mapping to strings");
3305 static PyObject *
3306 posix_execve(PyObject *self, PyObject *args)
3308 PyObject *opath;
3309 char *path;
3310 PyObject *argv, *env;
3311 char **argvlist;
3312 char **envlist;
3313 Py_ssize_t i, argc, envc;
3314 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3315 Py_ssize_t lastarg = 0;
3317 /* execve has three arguments: (path, argv, env), where
3318 argv is a list or tuple of strings and env is a dictionary
3319 like posix.environ. */
3321 if (!PyArg_ParseTuple(args, "O&OO:execve",
3322 PyUnicode_FSConverter,
3323 &opath, &argv, &env))
3324 return NULL;
3325 path = bytes2str(opath, 1);
3326 if (PyList_Check(argv)) {
3327 argc = PyList_Size(argv);
3328 getitem = PyList_GetItem;
3330 else if (PyTuple_Check(argv)) {
3331 argc = PyTuple_Size(argv);
3332 getitem = PyTuple_GetItem;
3334 else {
3335 PyErr_SetString(PyExc_TypeError,
3336 "execve() arg 2 must be a tuple or list");
3337 goto fail_0;
3339 if (!PyMapping_Check(env)) {
3340 PyErr_SetString(PyExc_TypeError,
3341 "execve() arg 3 must be a mapping object");
3342 goto fail_0;
3345 argvlist = PyMem_NEW(char *, argc+1);
3346 if (argvlist == NULL) {
3347 PyErr_NoMemory();
3348 goto fail_0;
3350 for (i = 0; i < argc; i++) {
3351 if (!fsconvert_strdup((*getitem)(argv, i),
3352 &argvlist[i]))
3354 lastarg = i;
3355 goto fail_1;
3358 lastarg = argc;
3359 argvlist[argc] = NULL;
3361 envlist = parse_envlist(env, &envc);
3362 if (envlist == NULL)
3363 goto fail_1;
3365 execve(path, argvlist, envlist);
3367 /* If we get here it's definitely an error */
3369 (void) posix_error();
3371 while (--envc >= 0)
3372 PyMem_DEL(envlist[envc]);
3373 PyMem_DEL(envlist);
3374 fail_1:
3375 free_string_array(argvlist, lastarg);
3376 fail_0:
3377 release_bytes(opath);
3378 return NULL;
3380 #endif /* HAVE_EXECV */
3383 #ifdef HAVE_SPAWNV
3384 PyDoc_STRVAR(posix_spawnv__doc__,
3385 "spawnv(mode, path, args)\n\n\
3386 Execute the program 'path' in a new process.\n\
3388 mode: mode of process creation\n\
3389 path: path of executable file\n\
3390 args: tuple or list of strings");
3392 static PyObject *
3393 posix_spawnv(PyObject *self, PyObject *args)
3395 PyObject *opath;
3396 char *path;
3397 PyObject *argv;
3398 char **argvlist;
3399 int mode, i;
3400 Py_ssize_t argc;
3401 Py_intptr_t spawnval;
3402 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3404 /* spawnv has three arguments: (mode, path, argv), where
3405 argv is a list or tuple of strings. */
3407 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode,
3408 PyUnicode_FSConverter,
3409 &opath, &argv))
3410 return NULL;
3411 path = bytes2str(opath, 1);
3412 if (PyList_Check(argv)) {
3413 argc = PyList_Size(argv);
3414 getitem = PyList_GetItem;
3416 else if (PyTuple_Check(argv)) {
3417 argc = PyTuple_Size(argv);
3418 getitem = PyTuple_GetItem;
3420 else {
3421 PyErr_SetString(PyExc_TypeError,
3422 "spawnv() arg 2 must be a tuple or list");
3423 release_bytes(opath);
3424 return NULL;
3427 argvlist = PyMem_NEW(char *, argc+1);
3428 if (argvlist == NULL) {
3429 release_bytes(opath);
3430 return PyErr_NoMemory();
3432 for (i = 0; i < argc; i++) {
3433 if (!fsconvert_strdup((*getitem)(argv, i),
3434 &argvlist[i])) {
3435 free_string_array(argvlist, i);
3436 PyErr_SetString(
3437 PyExc_TypeError,
3438 "spawnv() arg 2 must contain only strings");
3439 release_bytes(opath);
3440 return NULL;
3443 argvlist[argc] = NULL;
3445 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3446 Py_BEGIN_ALLOW_THREADS
3447 spawnval = spawnv(mode, path, argvlist);
3448 Py_END_ALLOW_THREADS
3449 #else
3450 if (mode == _OLD_P_OVERLAY)
3451 mode = _P_OVERLAY;
3453 Py_BEGIN_ALLOW_THREADS
3454 spawnval = _spawnv(mode, path, argvlist);
3455 Py_END_ALLOW_THREADS
3456 #endif
3458 free_string_array(argvlist, argc);
3459 release_bytes(opath);
3461 if (spawnval == -1)
3462 return posix_error();
3463 else
3464 #if SIZEOF_LONG == SIZEOF_VOID_P
3465 return Py_BuildValue("l", (long) spawnval);
3466 #else
3467 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3468 #endif
3472 PyDoc_STRVAR(posix_spawnve__doc__,
3473 "spawnve(mode, path, args, env)\n\n\
3474 Execute the program 'path' in a new process.\n\
3476 mode: mode of process creation\n\
3477 path: path of executable file\n\
3478 args: tuple or list of arguments\n\
3479 env: dictionary of strings mapping to strings");
3481 static PyObject *
3482 posix_spawnve(PyObject *self, PyObject *args)
3484 PyObject *opath;
3485 char *path;
3486 PyObject *argv, *env;
3487 char **argvlist;
3488 char **envlist;
3489 PyObject *res = NULL;
3490 int mode, envc;
3491 Py_ssize_t argc, i;
3492 Py_intptr_t spawnval;
3493 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3494 Py_ssize_t lastarg = 0;
3496 /* spawnve has four arguments: (mode, path, argv, env), where
3497 argv is a list or tuple of strings and env is a dictionary
3498 like posix.environ. */
3500 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode,
3501 PyUnicode_FSConverter,
3502 &opath, &argv, &env))
3503 return NULL;
3504 path = bytes2str(opath, 1);
3505 if (PyList_Check(argv)) {
3506 argc = PyList_Size(argv);
3507 getitem = PyList_GetItem;
3509 else if (PyTuple_Check(argv)) {
3510 argc = PyTuple_Size(argv);
3511 getitem = PyTuple_GetItem;
3513 else {
3514 PyErr_SetString(PyExc_TypeError,
3515 "spawnve() arg 2 must be a tuple or list");
3516 goto fail_0;
3518 if (!PyMapping_Check(env)) {
3519 PyErr_SetString(PyExc_TypeError,
3520 "spawnve() arg 3 must be a mapping object");
3521 goto fail_0;
3524 argvlist = PyMem_NEW(char *, argc+1);
3525 if (argvlist == NULL) {
3526 PyErr_NoMemory();
3527 goto fail_0;
3529 for (i = 0; i < argc; i++) {
3530 if (!fsconvert_strdup((*getitem)(argv, i),
3531 &argvlist[i]))
3533 lastarg = i;
3534 goto fail_1;
3537 lastarg = argc;
3538 argvlist[argc] = NULL;
3540 envlist = parse_envlist(env, &envc);
3541 if (envlist == NULL)
3542 goto fail_1;
3544 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3545 Py_BEGIN_ALLOW_THREADS
3546 spawnval = spawnve(mode, path, argvlist, envlist);
3547 Py_END_ALLOW_THREADS
3548 #else
3549 if (mode == _OLD_P_OVERLAY)
3550 mode = _P_OVERLAY;
3552 Py_BEGIN_ALLOW_THREADS
3553 spawnval = _spawnve(mode, path, argvlist, envlist);
3554 Py_END_ALLOW_THREADS
3555 #endif
3557 if (spawnval == -1)
3558 (void) posix_error();
3559 else
3560 #if SIZEOF_LONG == SIZEOF_VOID_P
3561 res = Py_BuildValue("l", (long) spawnval);
3562 #else
3563 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3564 #endif
3566 while (--envc >= 0)
3567 PyMem_DEL(envlist[envc]);
3568 PyMem_DEL(envlist);
3569 fail_1:
3570 free_string_array(argvlist, lastarg);
3571 fail_0:
3572 release_bytes(opath);
3573 return res;
3576 /* OS/2 supports spawnvp & spawnvpe natively */
3577 #if defined(PYOS_OS2)
3578 PyDoc_STRVAR(posix_spawnvp__doc__,
3579 "spawnvp(mode, file, args)\n\n\
3580 Execute the program 'file' in a new process, using the environment\n\
3581 search path to find the file.\n\
3583 mode: mode of process creation\n\
3584 file: executable file name\n\
3585 args: tuple or list of strings");
3587 static PyObject *
3588 posix_spawnvp(PyObject *self, PyObject *args)
3590 PyObject *opath;
3591 char *path;
3592 PyObject *argv;
3593 char **argvlist;
3594 int mode, i, argc;
3595 Py_intptr_t spawnval;
3596 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3598 /* spawnvp has three arguments: (mode, path, argv), where
3599 argv is a list or tuple of strings. */
3601 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode,
3602 PyUnicode_FSConverter,
3603 &opath, &argv))
3604 return NULL;
3605 path = bytes2str(opath);
3606 if (PyList_Check(argv)) {
3607 argc = PyList_Size(argv);
3608 getitem = PyList_GetItem;
3610 else if (PyTuple_Check(argv)) {
3611 argc = PyTuple_Size(argv);
3612 getitem = PyTuple_GetItem;
3614 else {
3615 PyErr_SetString(PyExc_TypeError,
3616 "spawnvp() arg 2 must be a tuple or list");
3617 release_bytes(opath);
3618 return NULL;
3621 argvlist = PyMem_NEW(char *, argc+1);
3622 if (argvlist == NULL) {
3623 release_bytes(opath);
3624 return PyErr_NoMemory();
3626 for (i = 0; i < argc; i++) {
3627 if (!fsconvert_strdup((*getitem)(argv, i),
3628 &argvlist[i])) {
3629 free_string_array(argvlist, i);
3630 PyErr_SetString(
3631 PyExc_TypeError,
3632 "spawnvp() arg 2 must contain only strings");
3633 release_bytes(opath);
3634 return NULL;
3637 argvlist[argc] = NULL;
3639 Py_BEGIN_ALLOW_THREADS
3640 #if defined(PYCC_GCC)
3641 spawnval = spawnvp(mode, path, argvlist);
3642 #else
3643 spawnval = _spawnvp(mode, path, argvlist);
3644 #endif
3645 Py_END_ALLOW_THREADS
3647 free_string_array(argvlist, argc);
3648 release_bytes(opath);
3650 if (spawnval == -1)
3651 return posix_error();
3652 else
3653 return Py_BuildValue("l", (long) spawnval);
3657 PyDoc_STRVAR(posix_spawnvpe__doc__,
3658 "spawnvpe(mode, file, args, env)\n\n\
3659 Execute the program 'file' in a new process, using the environment\n\
3660 search path to find the file.\n\
3662 mode: mode of process creation\n\
3663 file: executable file name\n\
3664 args: tuple or list of arguments\n\
3665 env: dictionary of strings mapping to strings");
3667 static PyObject *
3668 posix_spawnvpe(PyObject *self, PyObject *args)
3670 PyObject *opath
3671 char *path;
3672 PyObject *argv, *env;
3673 char **argvlist;
3674 char **envlist;
3675 PyObject *res=NULL;
3676 int mode, i, argc, envc;
3677 Py_intptr_t spawnval;
3678 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3679 int lastarg = 0;
3681 /* spawnvpe has four arguments: (mode, path, argv, env), where
3682 argv is a list or tuple of strings and env is a dictionary
3683 like posix.environ. */
3685 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3686 PyUnicode_FSConverter,
3687 &opath, &argv, &env))
3688 return NULL;
3689 path = bytes2str(opath);
3690 if (PyList_Check(argv)) {
3691 argc = PyList_Size(argv);
3692 getitem = PyList_GetItem;
3694 else if (PyTuple_Check(argv)) {
3695 argc = PyTuple_Size(argv);
3696 getitem = PyTuple_GetItem;
3698 else {
3699 PyErr_SetString(PyExc_TypeError,
3700 "spawnvpe() arg 2 must be a tuple or list");
3701 goto fail_0;
3703 if (!PyMapping_Check(env)) {
3704 PyErr_SetString(PyExc_TypeError,
3705 "spawnvpe() arg 3 must be a mapping object");
3706 goto fail_0;
3709 argvlist = PyMem_NEW(char *, argc+1);
3710 if (argvlist == NULL) {
3711 PyErr_NoMemory();
3712 goto fail_0;
3714 for (i = 0; i < argc; i++) {
3715 if (!fsconvert_strdup((*getitem)(argv, i),
3716 &argvlist[i]))
3718 lastarg = i;
3719 goto fail_1;
3722 lastarg = argc;
3723 argvlist[argc] = NULL;
3725 envlist = parse_envlist(env, &envc);
3726 if (envlist == NULL)
3727 goto fail_1;
3729 Py_BEGIN_ALLOW_THREADS
3730 #if defined(PYCC_GCC)
3731 spawnval = spawnvpe(mode, path, argvlist, envlist);
3732 #else
3733 spawnval = _spawnvpe(mode, path, argvlist, envlist);
3734 #endif
3735 Py_END_ALLOW_THREADS
3737 if (spawnval == -1)
3738 (void) posix_error();
3739 else
3740 res = Py_BuildValue("l", (long) spawnval);
3742 while (--envc >= 0)
3743 PyMem_DEL(envlist[envc]);
3744 PyMem_DEL(envlist);
3745 fail_1:
3746 free_string_array(argvlist, lastarg);
3747 fail_0:
3748 release_bytes(opath);
3749 return res;
3751 #endif /* PYOS_OS2 */
3752 #endif /* HAVE_SPAWNV */
3755 #ifdef HAVE_FORK1
3756 PyDoc_STRVAR(posix_fork1__doc__,
3757 "fork1() -> pid\n\n\
3758 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3760 Return 0 to child process and PID of child to parent process.");
3762 static PyObject *
3763 posix_fork1(PyObject *self, PyObject *noargs)
3765 pid_t pid;
3766 int result;
3767 _PyImport_AcquireLock();
3768 pid = fork1();
3769 result = _PyImport_ReleaseLock();
3770 if (pid == -1)
3771 return posix_error();
3772 if (pid == 0)
3773 PyOS_AfterFork();
3774 if (result < 0) {
3775 /* Don't clobber the OSError if the fork failed. */
3776 PyErr_SetString(PyExc_RuntimeError,
3777 "not holding the import lock");
3778 return NULL;
3780 return PyLong_FromPid(pid);
3782 #endif
3785 #ifdef HAVE_FORK
3786 PyDoc_STRVAR(posix_fork__doc__,
3787 "fork() -> pid\n\n\
3788 Fork a child process.\n\
3789 Return 0 to child process and PID of child to parent process.");
3791 static PyObject *
3792 posix_fork(PyObject *self, PyObject *noargs)
3794 pid_t pid;
3795 int result;
3796 _PyImport_AcquireLock();
3797 pid = fork();
3798 result = _PyImport_ReleaseLock();
3799 if (pid == -1)
3800 return posix_error();
3801 if (pid == 0)
3802 PyOS_AfterFork();
3803 if (result < 0) {
3804 /* Don't clobber the OSError if the fork failed. */
3805 PyErr_SetString(PyExc_RuntimeError,
3806 "not holding the import lock");
3807 return NULL;
3809 return PyLong_FromPid(pid);
3811 #endif
3813 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
3814 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3815 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
3816 #define DEV_PTY_FILE "/dev/ptc"
3817 #define HAVE_DEV_PTMX
3818 #else
3819 #define DEV_PTY_FILE "/dev/ptmx"
3820 #endif
3822 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
3823 #ifdef HAVE_PTY_H
3824 #include <pty.h>
3825 #else
3826 #ifdef HAVE_LIBUTIL_H
3827 #include <libutil.h>
3828 #endif /* HAVE_LIBUTIL_H */
3829 #endif /* HAVE_PTY_H */
3830 #ifdef HAVE_STROPTS_H
3831 #include <stropts.h>
3832 #endif
3833 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
3835 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3836 PyDoc_STRVAR(posix_openpty__doc__,
3837 "openpty() -> (master_fd, slave_fd)\n\n\
3838 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
3840 static PyObject *
3841 posix_openpty(PyObject *self, PyObject *noargs)
3843 int master_fd, slave_fd;
3844 #ifndef HAVE_OPENPTY
3845 char * slave_name;
3846 #endif
3847 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
3848 PyOS_sighandler_t sig_saved;
3849 #ifdef sun
3850 extern char *ptsname(int fildes);
3851 #endif
3852 #endif
3854 #ifdef HAVE_OPENPTY
3855 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3856 return posix_error();
3857 #elif defined(HAVE__GETPTY)
3858 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3859 if (slave_name == NULL)
3860 return posix_error();
3862 slave_fd = open(slave_name, O_RDWR);
3863 if (slave_fd < 0)
3864 return posix_error();
3865 #else
3866 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3867 if (master_fd < 0)
3868 return posix_error();
3869 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3870 /* change permission of slave */
3871 if (grantpt(master_fd) < 0) {
3872 PyOS_setsig(SIGCHLD, sig_saved);
3873 return posix_error();
3875 /* unlock slave */
3876 if (unlockpt(master_fd) < 0) {
3877 PyOS_setsig(SIGCHLD, sig_saved);
3878 return posix_error();
3880 PyOS_setsig(SIGCHLD, sig_saved);
3881 slave_name = ptsname(master_fd); /* get name of slave */
3882 if (slave_name == NULL)
3883 return posix_error();
3884 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3885 if (slave_fd < 0)
3886 return posix_error();
3887 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
3888 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3889 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
3890 #ifndef __hpux
3891 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
3892 #endif /* __hpux */
3893 #endif /* HAVE_CYGWIN */
3894 #endif /* HAVE_OPENPTY */
3896 return Py_BuildValue("(ii)", master_fd, slave_fd);
3899 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3901 #ifdef HAVE_FORKPTY
3902 PyDoc_STRVAR(posix_forkpty__doc__,
3903 "forkpty() -> (pid, master_fd)\n\n\
3904 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3905 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3906 To both, return fd of newly opened pseudo-terminal.\n");
3908 static PyObject *
3909 posix_forkpty(PyObject *self, PyObject *noargs)
3911 int master_fd = -1, result;
3912 pid_t pid;
3914 _PyImport_AcquireLock();
3915 pid = forkpty(&master_fd, NULL, NULL, NULL);
3916 result = _PyImport_ReleaseLock();
3917 if (pid == -1)
3918 return posix_error();
3919 if (pid == 0)
3920 PyOS_AfterFork();
3921 if (result < 0) {
3922 /* Don't clobber the OSError if the fork failed. */
3923 PyErr_SetString(PyExc_RuntimeError,
3924 "not holding the import lock");
3925 return NULL;
3927 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
3929 #endif
3931 #ifdef HAVE_GETEGID
3932 PyDoc_STRVAR(posix_getegid__doc__,
3933 "getegid() -> egid\n\n\
3934 Return the current process's effective group id.");
3936 static PyObject *
3937 posix_getegid(PyObject *self, PyObject *noargs)
3939 return PyLong_FromLong((long)getegid());
3941 #endif
3944 #ifdef HAVE_GETEUID
3945 PyDoc_STRVAR(posix_geteuid__doc__,
3946 "geteuid() -> euid\n\n\
3947 Return the current process's effective user id.");
3949 static PyObject *
3950 posix_geteuid(PyObject *self, PyObject *noargs)
3952 return PyLong_FromLong((long)geteuid());
3954 #endif
3957 #ifdef HAVE_GETGID
3958 PyDoc_STRVAR(posix_getgid__doc__,
3959 "getgid() -> gid\n\n\
3960 Return the current process's group id.");
3962 static PyObject *
3963 posix_getgid(PyObject *self, PyObject *noargs)
3965 return PyLong_FromLong((long)getgid());
3967 #endif
3970 PyDoc_STRVAR(posix_getpid__doc__,
3971 "getpid() -> pid\n\n\
3972 Return the current process id");
3974 static PyObject *
3975 posix_getpid(PyObject *self, PyObject *noargs)
3977 return PyLong_FromPid(getpid());
3981 #ifdef HAVE_GETGROUPS
3982 PyDoc_STRVAR(posix_getgroups__doc__,
3983 "getgroups() -> list of group IDs\n\n\
3984 Return list of supplemental group IDs for the process.");
3986 static PyObject *
3987 posix_getgroups(PyObject *self, PyObject *noargs)
3989 PyObject *result = NULL;
3991 #ifdef NGROUPS_MAX
3992 #define MAX_GROUPS NGROUPS_MAX
3993 #else
3994 /* defined to be 16 on Solaris7, so this should be a small number */
3995 #define MAX_GROUPS 64
3996 #endif
3997 gid_t grouplist[MAX_GROUPS];
3998 int n;
4000 n = getgroups(MAX_GROUPS, grouplist);
4001 if (n < 0)
4002 posix_error();
4003 else {
4004 result = PyList_New(n);
4005 if (result != NULL) {
4006 int i;
4007 for (i = 0; i < n; ++i) {
4008 PyObject *o = PyLong_FromLong((long)grouplist[i]);
4009 if (o == NULL) {
4010 Py_DECREF(result);
4011 result = NULL;
4012 break;
4014 PyList_SET_ITEM(result, i, o);
4019 return result;
4021 #endif
4023 #ifdef HAVE_GETPGID
4024 PyDoc_STRVAR(posix_getpgid__doc__,
4025 "getpgid(pid) -> pgid\n\n\
4026 Call the system call getpgid().");
4028 static PyObject *
4029 posix_getpgid(PyObject *self, PyObject *args)
4031 pid_t pid, pgid;
4032 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4033 return NULL;
4034 pgid = getpgid(pid);
4035 if (pgid < 0)
4036 return posix_error();
4037 return PyLong_FromPid(pgid);
4039 #endif /* HAVE_GETPGID */
4042 #ifdef HAVE_GETPGRP
4043 PyDoc_STRVAR(posix_getpgrp__doc__,
4044 "getpgrp() -> pgrp\n\n\
4045 Return the current process group id.");
4047 static PyObject *
4048 posix_getpgrp(PyObject *self, PyObject *noargs)
4050 #ifdef GETPGRP_HAVE_ARG
4051 return PyLong_FromPid(getpgrp(0));
4052 #else /* GETPGRP_HAVE_ARG */
4053 return PyLong_FromPid(getpgrp());
4054 #endif /* GETPGRP_HAVE_ARG */
4056 #endif /* HAVE_GETPGRP */
4059 #ifdef HAVE_SETPGRP
4060 PyDoc_STRVAR(posix_setpgrp__doc__,
4061 "setpgrp()\n\n\
4062 Make this process the process group leader.");
4064 static PyObject *
4065 posix_setpgrp(PyObject *self, PyObject *noargs)
4067 #ifdef SETPGRP_HAVE_ARG
4068 if (setpgrp(0, 0) < 0)
4069 #else /* SETPGRP_HAVE_ARG */
4070 if (setpgrp() < 0)
4071 #endif /* SETPGRP_HAVE_ARG */
4072 return posix_error();
4073 Py_INCREF(Py_None);
4074 return Py_None;
4077 #endif /* HAVE_SETPGRP */
4079 #ifdef HAVE_GETPPID
4080 PyDoc_STRVAR(posix_getppid__doc__,
4081 "getppid() -> ppid\n\n\
4082 Return the parent's process id.");
4084 static PyObject *
4085 posix_getppid(PyObject *self, PyObject *noargs)
4087 return PyLong_FromPid(getppid());
4089 #endif
4092 #ifdef HAVE_GETLOGIN
4093 PyDoc_STRVAR(posix_getlogin__doc__,
4094 "getlogin() -> string\n\n\
4095 Return the actual login name.");
4097 static PyObject *
4098 posix_getlogin(PyObject *self, PyObject *noargs)
4100 PyObject *result = NULL;
4101 char *name;
4102 int old_errno = errno;
4104 errno = 0;
4105 name = getlogin();
4106 if (name == NULL) {
4107 if (errno)
4108 posix_error();
4109 else
4110 PyErr_SetString(PyExc_OSError,
4111 "unable to determine login name");
4113 else
4114 result = PyUnicode_FromString(name);
4115 errno = old_errno;
4117 return result;
4119 #endif
4121 #ifdef HAVE_GETUID
4122 PyDoc_STRVAR(posix_getuid__doc__,
4123 "getuid() -> uid\n\n\
4124 Return the current process's user id.");
4126 static PyObject *
4127 posix_getuid(PyObject *self, PyObject *noargs)
4129 return PyLong_FromLong((long)getuid());
4131 #endif
4134 #ifdef HAVE_KILL
4135 PyDoc_STRVAR(posix_kill__doc__,
4136 "kill(pid, sig)\n\n\
4137 Kill a process with a signal.");
4139 static PyObject *
4140 posix_kill(PyObject *self, PyObject *args)
4142 pid_t pid;
4143 int sig;
4144 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4145 return NULL;
4146 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
4147 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4148 APIRET rc;
4149 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
4150 return os2_error(rc);
4152 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4153 APIRET rc;
4154 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
4155 return os2_error(rc);
4157 } else
4158 return NULL; /* Unrecognized Signal Requested */
4159 #else
4160 if (kill(pid, sig) == -1)
4161 return posix_error();
4162 #endif
4163 Py_INCREF(Py_None);
4164 return Py_None;
4166 #endif
4168 #ifdef HAVE_KILLPG
4169 PyDoc_STRVAR(posix_killpg__doc__,
4170 "killpg(pgid, sig)\n\n\
4171 Kill a process group with a signal.");
4173 static PyObject *
4174 posix_killpg(PyObject *self, PyObject *args)
4176 int sig;
4177 pid_t pgid;
4178 /* XXX some man pages make the `pgid` parameter an int, others
4179 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4180 take the same type. Moreover, pid_t is always at least as wide as
4181 int (else compilation of this module fails), which is safe. */
4182 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4183 return NULL;
4184 if (killpg(pgid, sig) == -1)
4185 return posix_error();
4186 Py_INCREF(Py_None);
4187 return Py_None;
4189 #endif
4191 #ifdef HAVE_PLOCK
4193 #ifdef HAVE_SYS_LOCK_H
4194 #include <sys/lock.h>
4195 #endif
4197 PyDoc_STRVAR(posix_plock__doc__,
4198 "plock(op)\n\n\
4199 Lock program segments into memory.");
4201 static PyObject *
4202 posix_plock(PyObject *self, PyObject *args)
4204 int op;
4205 if (!PyArg_ParseTuple(args, "i:plock", &op))
4206 return NULL;
4207 if (plock(op) == -1)
4208 return posix_error();
4209 Py_INCREF(Py_None);
4210 return Py_None;
4212 #endif
4214 #ifdef HAVE_SETUID
4215 PyDoc_STRVAR(posix_setuid__doc__,
4216 "setuid(uid)\n\n\
4217 Set the current process's user id.");
4219 static PyObject *
4220 posix_setuid(PyObject *self, PyObject *args)
4222 long uid_arg;
4223 uid_t uid;
4224 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4225 return NULL;
4226 uid = uid_arg;
4227 if (uid != uid_arg) {
4228 PyErr_SetString(PyExc_OverflowError, "user id too big");
4229 return NULL;
4231 if (setuid(uid) < 0)
4232 return posix_error();
4233 Py_INCREF(Py_None);
4234 return Py_None;
4236 #endif /* HAVE_SETUID */
4239 #ifdef HAVE_SETEUID
4240 PyDoc_STRVAR(posix_seteuid__doc__,
4241 "seteuid(uid)\n\n\
4242 Set the current process's effective user id.");
4244 static PyObject *
4245 posix_seteuid (PyObject *self, PyObject *args)
4247 long euid_arg;
4248 uid_t euid;
4249 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4250 return NULL;
4251 euid = euid_arg;
4252 if (euid != euid_arg) {
4253 PyErr_SetString(PyExc_OverflowError, "user id too big");
4254 return NULL;
4256 if (seteuid(euid) < 0) {
4257 return posix_error();
4258 } else {
4259 Py_INCREF(Py_None);
4260 return Py_None;
4263 #endif /* HAVE_SETEUID */
4265 #ifdef HAVE_SETEGID
4266 PyDoc_STRVAR(posix_setegid__doc__,
4267 "setegid(gid)\n\n\
4268 Set the current process's effective group id.");
4270 static PyObject *
4271 posix_setegid (PyObject *self, PyObject *args)
4273 long egid_arg;
4274 gid_t egid;
4275 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4276 return NULL;
4277 egid = egid_arg;
4278 if (egid != egid_arg) {
4279 PyErr_SetString(PyExc_OverflowError, "group id too big");
4280 return NULL;
4282 if (setegid(egid) < 0) {
4283 return posix_error();
4284 } else {
4285 Py_INCREF(Py_None);
4286 return Py_None;
4289 #endif /* HAVE_SETEGID */
4291 #ifdef HAVE_SETREUID
4292 PyDoc_STRVAR(posix_setreuid__doc__,
4293 "setreuid(ruid, euid)\n\n\
4294 Set the current process's real and effective user ids.");
4296 static PyObject *
4297 posix_setreuid (PyObject *self, PyObject *args)
4299 long ruid_arg, euid_arg;
4300 uid_t ruid, euid;
4301 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4302 return NULL;
4303 if (ruid_arg == -1)
4304 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4305 else
4306 ruid = ruid_arg; /* otherwise, assign from our long */
4307 if (euid_arg == -1)
4308 euid = (uid_t)-1;
4309 else
4310 euid = euid_arg;
4311 if ((euid_arg != -1 && euid != euid_arg) ||
4312 (ruid_arg != -1 && ruid != ruid_arg)) {
4313 PyErr_SetString(PyExc_OverflowError, "user id too big");
4314 return NULL;
4316 if (setreuid(ruid, euid) < 0) {
4317 return posix_error();
4318 } else {
4319 Py_INCREF(Py_None);
4320 return Py_None;
4323 #endif /* HAVE_SETREUID */
4325 #ifdef HAVE_SETREGID
4326 PyDoc_STRVAR(posix_setregid__doc__,
4327 "setregid(rgid, egid)\n\n\
4328 Set the current process's real and effective group ids.");
4330 static PyObject *
4331 posix_setregid (PyObject *self, PyObject *args)
4333 long rgid_arg, egid_arg;
4334 gid_t rgid, egid;
4335 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4336 return NULL;
4337 if (rgid_arg == -1)
4338 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4339 else
4340 rgid = rgid_arg; /* otherwise, assign from our long */
4341 if (egid_arg == -1)
4342 egid = (gid_t)-1;
4343 else
4344 egid = egid_arg;
4345 if ((egid_arg != -1 && egid != egid_arg) ||
4346 (rgid_arg != -1 && rgid != rgid_arg)) {
4347 PyErr_SetString(PyExc_OverflowError, "group id too big");
4348 return NULL;
4350 if (setregid(rgid, egid) < 0) {
4351 return posix_error();
4352 } else {
4353 Py_INCREF(Py_None);
4354 return Py_None;
4357 #endif /* HAVE_SETREGID */
4359 #ifdef HAVE_SETGID
4360 PyDoc_STRVAR(posix_setgid__doc__,
4361 "setgid(gid)\n\n\
4362 Set the current process's group id.");
4364 static PyObject *
4365 posix_setgid(PyObject *self, PyObject *args)
4367 long gid_arg;
4368 gid_t gid;
4369 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4370 return NULL;
4371 gid = gid_arg;
4372 if (gid != gid_arg) {
4373 PyErr_SetString(PyExc_OverflowError, "group id too big");
4374 return NULL;
4376 if (setgid(gid) < 0)
4377 return posix_error();
4378 Py_INCREF(Py_None);
4379 return Py_None;
4381 #endif /* HAVE_SETGID */
4383 #ifdef HAVE_SETGROUPS
4384 PyDoc_STRVAR(posix_setgroups__doc__,
4385 "setgroups(list)\n\n\
4386 Set the groups of the current process to list.");
4388 static PyObject *
4389 posix_setgroups(PyObject *self, PyObject *groups)
4391 int i, len;
4392 gid_t grouplist[MAX_GROUPS];
4394 if (!PySequence_Check(groups)) {
4395 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4396 return NULL;
4398 len = PySequence_Size(groups);
4399 if (len > MAX_GROUPS) {
4400 PyErr_SetString(PyExc_ValueError, "too many groups");
4401 return NULL;
4403 for(i = 0; i < len; i++) {
4404 PyObject *elem;
4405 elem = PySequence_GetItem(groups, i);
4406 if (!elem)
4407 return NULL;
4408 if (!PyLong_Check(elem)) {
4409 PyErr_SetString(PyExc_TypeError,
4410 "groups must be integers");
4411 Py_DECREF(elem);
4412 return NULL;
4413 } else {
4414 unsigned long x = PyLong_AsUnsignedLong(elem);
4415 if (PyErr_Occurred()) {
4416 PyErr_SetString(PyExc_TypeError,
4417 "group id too big");
4418 Py_DECREF(elem);
4419 return NULL;
4421 grouplist[i] = x;
4422 /* read back the value to see if it fitted in gid_t */
4423 if (grouplist[i] != x) {
4424 PyErr_SetString(PyExc_TypeError,
4425 "group id too big");
4426 Py_DECREF(elem);
4427 return NULL;
4430 Py_DECREF(elem);
4433 if (setgroups(len, grouplist) < 0)
4434 return posix_error();
4435 Py_INCREF(Py_None);
4436 return Py_None;
4438 #endif /* HAVE_SETGROUPS */
4440 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4441 static PyObject *
4442 wait_helper(pid_t pid, int status, struct rusage *ru)
4444 PyObject *result;
4445 static PyObject *struct_rusage;
4447 if (pid == -1)
4448 return posix_error();
4450 if (struct_rusage == NULL) {
4451 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4452 if (m == NULL)
4453 return NULL;
4454 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4455 Py_DECREF(m);
4456 if (struct_rusage == NULL)
4457 return NULL;
4460 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4461 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4462 if (!result)
4463 return NULL;
4465 #ifndef doubletime
4466 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4467 #endif
4469 PyStructSequence_SET_ITEM(result, 0,
4470 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4471 PyStructSequence_SET_ITEM(result, 1,
4472 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4473 #define SET_INT(result, index, value)\
4474 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
4475 SET_INT(result, 2, ru->ru_maxrss);
4476 SET_INT(result, 3, ru->ru_ixrss);
4477 SET_INT(result, 4, ru->ru_idrss);
4478 SET_INT(result, 5, ru->ru_isrss);
4479 SET_INT(result, 6, ru->ru_minflt);
4480 SET_INT(result, 7, ru->ru_majflt);
4481 SET_INT(result, 8, ru->ru_nswap);
4482 SET_INT(result, 9, ru->ru_inblock);
4483 SET_INT(result, 10, ru->ru_oublock);
4484 SET_INT(result, 11, ru->ru_msgsnd);
4485 SET_INT(result, 12, ru->ru_msgrcv);
4486 SET_INT(result, 13, ru->ru_nsignals);
4487 SET_INT(result, 14, ru->ru_nvcsw);
4488 SET_INT(result, 15, ru->ru_nivcsw);
4489 #undef SET_INT
4491 if (PyErr_Occurred()) {
4492 Py_DECREF(result);
4493 return NULL;
4496 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
4498 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4500 #ifdef HAVE_WAIT3
4501 PyDoc_STRVAR(posix_wait3__doc__,
4502 "wait3(options) -> (pid, status, rusage)\n\n\
4503 Wait for completion of a child process.");
4505 static PyObject *
4506 posix_wait3(PyObject *self, PyObject *args)
4508 pid_t pid;
4509 int options;
4510 struct rusage ru;
4511 WAIT_TYPE status;
4512 WAIT_STATUS_INT(status) = 0;
4514 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4515 return NULL;
4517 Py_BEGIN_ALLOW_THREADS
4518 pid = wait3(&status, options, &ru);
4519 Py_END_ALLOW_THREADS
4521 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4523 #endif /* HAVE_WAIT3 */
4525 #ifdef HAVE_WAIT4
4526 PyDoc_STRVAR(posix_wait4__doc__,
4527 "wait4(pid, options) -> (pid, status, rusage)\n\n\
4528 Wait for completion of a given child process.");
4530 static PyObject *
4531 posix_wait4(PyObject *self, PyObject *args)
4533 pid_t pid;
4534 int options;
4535 struct rusage ru;
4536 WAIT_TYPE status;
4537 WAIT_STATUS_INT(status) = 0;
4539 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
4540 return NULL;
4542 Py_BEGIN_ALLOW_THREADS
4543 pid = wait4(pid, &status, options, &ru);
4544 Py_END_ALLOW_THREADS
4546 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4548 #endif /* HAVE_WAIT4 */
4550 #ifdef HAVE_WAITPID
4551 PyDoc_STRVAR(posix_waitpid__doc__,
4552 "waitpid(pid, options) -> (pid, status)\n\n\
4553 Wait for completion of a given child process.");
4555 static PyObject *
4556 posix_waitpid(PyObject *self, PyObject *args)
4558 pid_t pid;
4559 int options;
4560 WAIT_TYPE status;
4561 WAIT_STATUS_INT(status) = 0;
4563 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
4564 return NULL;
4565 Py_BEGIN_ALLOW_THREADS
4566 pid = waitpid(pid, &status, options);
4567 Py_END_ALLOW_THREADS
4568 if (pid == -1)
4569 return posix_error();
4571 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
4574 #elif defined(HAVE_CWAIT)
4576 /* MS C has a variant of waitpid() that's usable for most purposes. */
4577 PyDoc_STRVAR(posix_waitpid__doc__,
4578 "waitpid(pid, options) -> (pid, status << 8)\n\n"
4579 "Wait for completion of a given process. options is ignored on Windows.");
4581 static PyObject *
4582 posix_waitpid(PyObject *self, PyObject *args)
4584 Py_intptr_t pid;
4585 int status, options;
4587 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
4588 return NULL;
4589 Py_BEGIN_ALLOW_THREADS
4590 pid = _cwait(&status, pid, options);
4591 Py_END_ALLOW_THREADS
4592 if (pid == -1)
4593 return posix_error();
4595 /* shift the status left a byte so this is more like the POSIX waitpid */
4596 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
4598 #endif /* HAVE_WAITPID || HAVE_CWAIT */
4600 #ifdef HAVE_WAIT
4601 PyDoc_STRVAR(posix_wait__doc__,
4602 "wait() -> (pid, status)\n\n\
4603 Wait for completion of a child process.");
4605 static PyObject *
4606 posix_wait(PyObject *self, PyObject *noargs)
4608 pid_t pid;
4609 WAIT_TYPE status;
4610 WAIT_STATUS_INT(status) = 0;
4612 Py_BEGIN_ALLOW_THREADS
4613 pid = wait(&status);
4614 Py_END_ALLOW_THREADS
4615 if (pid == -1)
4616 return posix_error();
4618 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
4620 #endif
4623 PyDoc_STRVAR(posix_lstat__doc__,
4624 "lstat(path) -> stat result\n\n\
4625 Like stat(path), but do not follow symbolic links.");
4627 static PyObject *
4628 posix_lstat(PyObject *self, PyObject *args)
4630 #ifdef HAVE_LSTAT
4631 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL);
4632 #else /* !HAVE_LSTAT */
4633 #ifdef MS_WINDOWS
4634 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", win32_wstat);
4635 #else
4636 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL);
4637 #endif
4638 #endif /* !HAVE_LSTAT */
4642 #ifdef HAVE_READLINK
4643 PyDoc_STRVAR(posix_readlink__doc__,
4644 "readlink(path) -> path\n\n\
4645 Return a string representing the path to which the symbolic link points.");
4647 static PyObject *
4648 posix_readlink(PyObject *self, PyObject *args)
4650 PyObject* v;
4651 char buf[MAXPATHLEN];
4652 PyObject *opath;
4653 char *path;
4654 int n;
4655 int arg_is_unicode = 0;
4657 if (!PyArg_ParseTuple(args, "O&:readlink",
4658 PyUnicode_FSConverter, &opath))
4659 return NULL;
4660 path = bytes2str(opath, 1);
4661 v = PySequence_GetItem(args, 0);
4662 if (v == NULL) {
4663 release_bytes(opath);
4664 return NULL;
4667 if (PyUnicode_Check(v)) {
4668 arg_is_unicode = 1;
4670 Py_DECREF(v);
4672 Py_BEGIN_ALLOW_THREADS
4673 n = readlink(path, buf, (int) sizeof buf);
4674 Py_END_ALLOW_THREADS
4675 if (n < 0)
4676 return posix_error_with_allocated_filename(opath);
4678 release_bytes(opath);
4679 v = PyBytes_FromStringAndSize(buf, n);
4680 if (arg_is_unicode) {
4681 PyObject *w;
4683 w = PyUnicode_FromEncodedObject(v,
4684 Py_FileSystemDefaultEncoding,
4685 "surrogateescape");
4686 if (w != NULL) {
4687 Py_DECREF(v);
4688 v = w;
4690 else {
4691 v = NULL;
4694 return v;
4696 #endif /* HAVE_READLINK */
4699 #ifdef HAVE_SYMLINK
4700 PyDoc_STRVAR(posix_symlink__doc__,
4701 "symlink(src, dst)\n\n\
4702 Create a symbolic link pointing to src named dst.");
4704 static PyObject *
4705 posix_symlink(PyObject *self, PyObject *args)
4707 return posix_2str(args, "O&O&:symlink", symlink);
4709 #endif /* HAVE_SYMLINK */
4712 #ifdef HAVE_TIMES
4713 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
4714 static long
4715 system_uptime(void)
4717 ULONG value = 0;
4719 Py_BEGIN_ALLOW_THREADS
4720 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4721 Py_END_ALLOW_THREADS
4723 return value;
4726 static PyObject *
4727 posix_times(PyObject *self, PyObject *noargs)
4729 /* Currently Only Uptime is Provided -- Others Later */
4730 return Py_BuildValue("ddddd",
4731 (double)0 /* t.tms_utime / HZ */,
4732 (double)0 /* t.tms_stime / HZ */,
4733 (double)0 /* t.tms_cutime / HZ */,
4734 (double)0 /* t.tms_cstime / HZ */,
4735 (double)system_uptime() / 1000);
4737 #else /* not OS2 */
4738 #define NEED_TICKS_PER_SECOND
4739 static long ticks_per_second = -1;
4740 static PyObject *
4741 posix_times(PyObject *self, PyObject *noargs)
4743 struct tms t;
4744 clock_t c;
4745 errno = 0;
4746 c = times(&t);
4747 if (c == (clock_t) -1)
4748 return posix_error();
4749 return Py_BuildValue("ddddd",
4750 (double)t.tms_utime / ticks_per_second,
4751 (double)t.tms_stime / ticks_per_second,
4752 (double)t.tms_cutime / ticks_per_second,
4753 (double)t.tms_cstime / ticks_per_second,
4754 (double)c / ticks_per_second);
4756 #endif /* not OS2 */
4757 #endif /* HAVE_TIMES */
4760 #ifdef MS_WINDOWS
4761 #define HAVE_TIMES /* so the method table will pick it up */
4762 static PyObject *
4763 posix_times(PyObject *self, PyObject *noargs)
4765 FILETIME create, exit, kernel, user;
4766 HANDLE hProc;
4767 hProc = GetCurrentProcess();
4768 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4769 /* The fields of a FILETIME structure are the hi and lo part
4770 of a 64-bit value expressed in 100 nanosecond units.
4771 1e7 is one second in such units; 1e-7 the inverse.
4772 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4774 return Py_BuildValue(
4775 "ddddd",
4776 (double)(user.dwHighDateTime*429.4967296 +
4777 user.dwLowDateTime*1e-7),
4778 (double)(kernel.dwHighDateTime*429.4967296 +
4779 kernel.dwLowDateTime*1e-7),
4780 (double)0,
4781 (double)0,
4782 (double)0);
4784 #endif /* MS_WINDOWS */
4786 #ifdef HAVE_TIMES
4787 PyDoc_STRVAR(posix_times__doc__,
4788 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
4789 Return a tuple of floating point numbers indicating process times.");
4790 #endif
4793 #ifdef HAVE_GETSID
4794 PyDoc_STRVAR(posix_getsid__doc__,
4795 "getsid(pid) -> sid\n\n\
4796 Call the system call getsid().");
4798 static PyObject *
4799 posix_getsid(PyObject *self, PyObject *args)
4801 pid_t pid;
4802 int sid;
4803 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
4804 return NULL;
4805 sid = getsid(pid);
4806 if (sid < 0)
4807 return posix_error();
4808 return PyLong_FromLong((long)sid);
4810 #endif /* HAVE_GETSID */
4813 #ifdef HAVE_SETSID
4814 PyDoc_STRVAR(posix_setsid__doc__,
4815 "setsid()\n\n\
4816 Call the system call setsid().");
4818 static PyObject *
4819 posix_setsid(PyObject *self, PyObject *noargs)
4821 if (setsid() < 0)
4822 return posix_error();
4823 Py_INCREF(Py_None);
4824 return Py_None;
4826 #endif /* HAVE_SETSID */
4828 #ifdef HAVE_SETPGID
4829 PyDoc_STRVAR(posix_setpgid__doc__,
4830 "setpgid(pid, pgrp)\n\n\
4831 Call the system call setpgid().");
4833 static PyObject *
4834 posix_setpgid(PyObject *self, PyObject *args)
4836 pid_t pid;
4837 int pgrp;
4838 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
4839 return NULL;
4840 if (setpgid(pid, pgrp) < 0)
4841 return posix_error();
4842 Py_INCREF(Py_None);
4843 return Py_None;
4845 #endif /* HAVE_SETPGID */
4848 #ifdef HAVE_TCGETPGRP
4849 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
4850 "tcgetpgrp(fd) -> pgid\n\n\
4851 Return the process group associated with the terminal given by a fd.");
4853 static PyObject *
4854 posix_tcgetpgrp(PyObject *self, PyObject *args)
4856 int fd;
4857 pid_t pgid;
4858 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
4859 return NULL;
4860 pgid = tcgetpgrp(fd);
4861 if (pgid < 0)
4862 return posix_error();
4863 return PyLong_FromPid(pgid);
4865 #endif /* HAVE_TCGETPGRP */
4868 #ifdef HAVE_TCSETPGRP
4869 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
4870 "tcsetpgrp(fd, pgid)\n\n\
4871 Set the process group associated with the terminal given by a fd.");
4873 static PyObject *
4874 posix_tcsetpgrp(PyObject *self, PyObject *args)
4876 int fd;
4877 pid_t pgid;
4878 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
4879 return NULL;
4880 if (tcsetpgrp(fd, pgid) < 0)
4881 return posix_error();
4882 Py_INCREF(Py_None);
4883 return Py_None;
4885 #endif /* HAVE_TCSETPGRP */
4887 /* Functions acting on file descriptors */
4889 PyDoc_STRVAR(posix_open__doc__,
4890 "open(filename, flag [, mode=0777]) -> fd\n\n\
4891 Open a file (for low level IO).");
4893 static PyObject *
4894 posix_open(PyObject *self, PyObject *args)
4896 PyObject *ofile;
4897 char *file;
4898 int flag;
4899 int mode = 0777;
4900 int fd;
4902 #ifdef MS_WINDOWS
4903 if (unicode_file_names()) {
4904 PyUnicodeObject *po;
4905 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4906 Py_BEGIN_ALLOW_THREADS
4907 /* PyUnicode_AS_UNICODE OK without thread
4908 lock as it is a simple dereference. */
4909 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4910 Py_END_ALLOW_THREADS
4911 if (fd < 0)
4912 return posix_error();
4913 return PyLong_FromLong((long)fd);
4915 /* Drop the argument parsing error as narrow strings
4916 are also valid. */
4917 PyErr_Clear();
4919 #endif
4921 if (!PyArg_ParseTuple(args, "O&i|i",
4922 PyUnicode_FSConverter, &ofile,
4923 &flag, &mode))
4924 return NULL;
4925 file = bytes2str(ofile, 1);
4926 Py_BEGIN_ALLOW_THREADS
4927 fd = open(file, flag, mode);
4928 Py_END_ALLOW_THREADS
4929 if (fd < 0)
4930 return posix_error_with_allocated_filename(ofile);
4931 release_bytes(ofile);
4932 return PyLong_FromLong((long)fd);
4936 PyDoc_STRVAR(posix_close__doc__,
4937 "close(fd)\n\n\
4938 Close a file descriptor (for low level IO).");
4940 static PyObject *
4941 posix_close(PyObject *self, PyObject *args)
4943 int fd, res;
4944 if (!PyArg_ParseTuple(args, "i:close", &fd))
4945 return NULL;
4946 if (!_PyVerify_fd(fd))
4947 return posix_error();
4948 Py_BEGIN_ALLOW_THREADS
4949 res = close(fd);
4950 Py_END_ALLOW_THREADS
4951 if (res < 0)
4952 return posix_error();
4953 Py_INCREF(Py_None);
4954 return Py_None;
4958 PyDoc_STRVAR(posix_closerange__doc__,
4959 "closerange(fd_low, fd_high)\n\n\
4960 Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
4962 static PyObject *
4963 posix_closerange(PyObject *self, PyObject *args)
4965 int fd_from, fd_to, i;
4966 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
4967 return NULL;
4968 Py_BEGIN_ALLOW_THREADS
4969 for (i = fd_from; i < fd_to; i++)
4970 if (_PyVerify_fd(i))
4971 close(i);
4972 Py_END_ALLOW_THREADS
4973 Py_RETURN_NONE;
4977 PyDoc_STRVAR(posix_dup__doc__,
4978 "dup(fd) -> fd2\n\n\
4979 Return a duplicate of a file descriptor.");
4981 static PyObject *
4982 posix_dup(PyObject *self, PyObject *args)
4984 int fd;
4985 if (!PyArg_ParseTuple(args, "i:dup", &fd))
4986 return NULL;
4987 if (!_PyVerify_fd(fd))
4988 return posix_error();
4989 Py_BEGIN_ALLOW_THREADS
4990 fd = dup(fd);
4991 Py_END_ALLOW_THREADS
4992 if (fd < 0)
4993 return posix_error();
4994 return PyLong_FromLong((long)fd);
4998 PyDoc_STRVAR(posix_dup2__doc__,
4999 "dup2(old_fd, new_fd)\n\n\
5000 Duplicate file descriptor.");
5002 static PyObject *
5003 posix_dup2(PyObject *self, PyObject *args)
5005 int fd, fd2, res;
5006 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5007 return NULL;
5008 if (!_PyVerify_fd_dup2(fd, fd2))
5009 return posix_error();
5010 Py_BEGIN_ALLOW_THREADS
5011 res = dup2(fd, fd2);
5012 Py_END_ALLOW_THREADS
5013 if (res < 0)
5014 return posix_error();
5015 Py_INCREF(Py_None);
5016 return Py_None;
5020 PyDoc_STRVAR(posix_lseek__doc__,
5021 "lseek(fd, pos, how) -> newpos\n\n\
5022 Set the current position of a file descriptor.");
5024 static PyObject *
5025 posix_lseek(PyObject *self, PyObject *args)
5027 int fd, how;
5028 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5029 PY_LONG_LONG pos, res;
5030 #else
5031 off_t pos, res;
5032 #endif
5033 PyObject *posobj;
5034 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5035 return NULL;
5036 #ifdef SEEK_SET
5037 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5038 switch (how) {
5039 case 0: how = SEEK_SET; break;
5040 case 1: how = SEEK_CUR; break;
5041 case 2: how = SEEK_END; break;
5043 #endif /* SEEK_END */
5045 #if !defined(HAVE_LARGEFILE_SUPPORT)
5046 pos = PyLong_AsLong(posobj);
5047 #else
5048 pos = PyLong_Check(posobj) ?
5049 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
5050 #endif
5051 if (PyErr_Occurred())
5052 return NULL;
5054 if (!_PyVerify_fd(fd))
5055 return posix_error();
5056 Py_BEGIN_ALLOW_THREADS
5057 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5058 res = _lseeki64(fd, pos, how);
5059 #else
5060 res = lseek(fd, pos, how);
5061 #endif
5062 Py_END_ALLOW_THREADS
5063 if (res < 0)
5064 return posix_error();
5066 #if !defined(HAVE_LARGEFILE_SUPPORT)
5067 return PyLong_FromLong(res);
5068 #else
5069 return PyLong_FromLongLong(res);
5070 #endif
5074 PyDoc_STRVAR(posix_read__doc__,
5075 "read(fd, buffersize) -> string\n\n\
5076 Read a file descriptor.");
5078 static PyObject *
5079 posix_read(PyObject *self, PyObject *args)
5081 int fd, size;
5082 Py_ssize_t n;
5083 PyObject *buffer;
5084 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5085 return NULL;
5086 if (size < 0) {
5087 errno = EINVAL;
5088 return posix_error();
5090 buffer = PyBytes_FromStringAndSize((char *)NULL, size);
5091 if (buffer == NULL)
5092 return NULL;
5093 if (!_PyVerify_fd(fd))
5094 return posix_error();
5095 Py_BEGIN_ALLOW_THREADS
5096 n = read(fd, PyBytes_AS_STRING(buffer), size);
5097 Py_END_ALLOW_THREADS
5098 if (n < 0) {
5099 Py_DECREF(buffer);
5100 return posix_error();
5102 if (n != size)
5103 _PyBytes_Resize(&buffer, n);
5104 return buffer;
5108 PyDoc_STRVAR(posix_write__doc__,
5109 "write(fd, string) -> byteswritten\n\n\
5110 Write a string to a file descriptor.");
5112 static PyObject *
5113 posix_write(PyObject *self, PyObject *args)
5115 Py_buffer pbuf;
5116 int fd;
5117 Py_ssize_t size;
5119 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
5120 return NULL;
5121 if (!_PyVerify_fd(fd))
5122 return posix_error();
5123 Py_BEGIN_ALLOW_THREADS
5124 size = write(fd, pbuf.buf, (size_t)pbuf.len);
5125 Py_END_ALLOW_THREADS
5126 PyBuffer_Release(&pbuf);
5127 if (size < 0)
5128 return posix_error();
5129 return PyLong_FromSsize_t(size);
5133 PyDoc_STRVAR(posix_fstat__doc__,
5134 "fstat(fd) -> stat result\n\n\
5135 Like stat(), but for an open file descriptor.");
5137 static PyObject *
5138 posix_fstat(PyObject *self, PyObject *args)
5140 int fd;
5141 STRUCT_STAT st;
5142 int res;
5143 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5144 return NULL;
5145 #ifdef __VMS
5146 /* on OpenVMS we must ensure that all bytes are written to the file */
5147 fsync(fd);
5148 #endif
5149 if (!_PyVerify_fd(fd))
5150 return posix_error();
5151 Py_BEGIN_ALLOW_THREADS
5152 res = FSTAT(fd, &st);
5153 Py_END_ALLOW_THREADS
5154 if (res != 0) {
5155 #ifdef MS_WINDOWS
5156 return win32_error("fstat", NULL);
5157 #else
5158 return posix_error();
5159 #endif
5162 return _pystat_fromstructstat(&st);
5165 PyDoc_STRVAR(posix_isatty__doc__,
5166 "isatty(fd) -> bool\n\n\
5167 Return True if the file descriptor 'fd' is an open file descriptor\n\
5168 connected to the slave end of a terminal.");
5170 static PyObject *
5171 posix_isatty(PyObject *self, PyObject *args)
5173 int fd;
5174 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5175 return NULL;
5176 if (!_PyVerify_fd(fd))
5177 return PyBool_FromLong(0);
5178 return PyBool_FromLong(isatty(fd));
5181 #ifdef HAVE_PIPE
5182 PyDoc_STRVAR(posix_pipe__doc__,
5183 "pipe() -> (read_end, write_end)\n\n\
5184 Create a pipe.");
5186 static PyObject *
5187 posix_pipe(PyObject *self, PyObject *noargs)
5189 #if defined(PYOS_OS2)
5190 HFILE read, write;
5191 APIRET rc;
5193 Py_BEGIN_ALLOW_THREADS
5194 rc = DosCreatePipe( &read, &write, 4096);
5195 Py_END_ALLOW_THREADS
5196 if (rc != NO_ERROR)
5197 return os2_error(rc);
5199 return Py_BuildValue("(ii)", read, write);
5200 #else
5201 #if !defined(MS_WINDOWS)
5202 int fds[2];
5203 int res;
5204 Py_BEGIN_ALLOW_THREADS
5205 res = pipe(fds);
5206 Py_END_ALLOW_THREADS
5207 if (res != 0)
5208 return posix_error();
5209 return Py_BuildValue("(ii)", fds[0], fds[1]);
5210 #else /* MS_WINDOWS */
5211 HANDLE read, write;
5212 int read_fd, write_fd;
5213 BOOL ok;
5214 Py_BEGIN_ALLOW_THREADS
5215 ok = CreatePipe(&read, &write, NULL, 0);
5216 Py_END_ALLOW_THREADS
5217 if (!ok)
5218 return win32_error("CreatePipe", NULL);
5219 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5220 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5221 return Py_BuildValue("(ii)", read_fd, write_fd);
5222 #endif /* MS_WINDOWS */
5223 #endif
5225 #endif /* HAVE_PIPE */
5228 #ifdef HAVE_MKFIFO
5229 PyDoc_STRVAR(posix_mkfifo__doc__,
5230 "mkfifo(filename [, mode=0666])\n\n\
5231 Create a FIFO (a POSIX named pipe).");
5233 static PyObject *
5234 posix_mkfifo(PyObject *self, PyObject *args)
5236 char *filename;
5237 int mode = 0666;
5238 int res;
5239 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
5240 return NULL;
5241 Py_BEGIN_ALLOW_THREADS
5242 res = mkfifo(filename, mode);
5243 Py_END_ALLOW_THREADS
5244 if (res < 0)
5245 return posix_error();
5246 Py_INCREF(Py_None);
5247 return Py_None;
5249 #endif
5252 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
5253 PyDoc_STRVAR(posix_mknod__doc__,
5254 "mknod(filename [, mode=0600, device])\n\n\
5255 Create a filesystem node (file, device special file or named pipe)\n\
5256 named filename. mode specifies both the permissions to use and the\n\
5257 type of node to be created, being combined (bitwise OR) with one of\n\
5258 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
5259 device defines the newly created device special file (probably using\n\
5260 os.makedev()), otherwise it is ignored.");
5263 static PyObject *
5264 posix_mknod(PyObject *self, PyObject *args)
5266 char *filename;
5267 int mode = 0600;
5268 int device = 0;
5269 int res;
5270 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
5271 return NULL;
5272 Py_BEGIN_ALLOW_THREADS
5273 res = mknod(filename, mode, device);
5274 Py_END_ALLOW_THREADS
5275 if (res < 0)
5276 return posix_error();
5277 Py_INCREF(Py_None);
5278 return Py_None;
5280 #endif
5282 #ifdef HAVE_DEVICE_MACROS
5283 PyDoc_STRVAR(posix_major__doc__,
5284 "major(device) -> major number\n\
5285 Extracts a device major number from a raw device number.");
5287 static PyObject *
5288 posix_major(PyObject *self, PyObject *args)
5290 int device;
5291 if (!PyArg_ParseTuple(args, "i:major", &device))
5292 return NULL;
5293 return PyLong_FromLong((long)major(device));
5296 PyDoc_STRVAR(posix_minor__doc__,
5297 "minor(device) -> minor number\n\
5298 Extracts a device minor number from a raw device number.");
5300 static PyObject *
5301 posix_minor(PyObject *self, PyObject *args)
5303 int device;
5304 if (!PyArg_ParseTuple(args, "i:minor", &device))
5305 return NULL;
5306 return PyLong_FromLong((long)minor(device));
5309 PyDoc_STRVAR(posix_makedev__doc__,
5310 "makedev(major, minor) -> device number\n\
5311 Composes a raw device number from the major and minor device numbers.");
5313 static PyObject *
5314 posix_makedev(PyObject *self, PyObject *args)
5316 int major, minor;
5317 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5318 return NULL;
5319 return PyLong_FromLong((long)makedev(major, minor));
5321 #endif /* device macros */
5324 #ifdef HAVE_FTRUNCATE
5325 PyDoc_STRVAR(posix_ftruncate__doc__,
5326 "ftruncate(fd, length)\n\n\
5327 Truncate a file to a specified length.");
5329 static PyObject *
5330 posix_ftruncate(PyObject *self, PyObject *args)
5332 int fd;
5333 off_t length;
5334 int res;
5335 PyObject *lenobj;
5337 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5338 return NULL;
5340 #if !defined(HAVE_LARGEFILE_SUPPORT)
5341 length = PyLong_AsLong(lenobj);
5342 #else
5343 length = PyLong_Check(lenobj) ?
5344 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
5345 #endif
5346 if (PyErr_Occurred())
5347 return NULL;
5349 Py_BEGIN_ALLOW_THREADS
5350 res = ftruncate(fd, length);
5351 Py_END_ALLOW_THREADS
5352 if (res < 0)
5353 return posix_error();
5354 Py_INCREF(Py_None);
5355 return Py_None;
5357 #endif
5359 #ifdef HAVE_PUTENV
5360 PyDoc_STRVAR(posix_putenv__doc__,
5361 "putenv(key, value)\n\n\
5362 Change or add an environment variable.");
5364 /* Save putenv() parameters as values here, so we can collect them when they
5365 * get re-set with another call for the same key. */
5366 static PyObject *posix_putenv_garbage;
5368 static PyObject *
5369 posix_putenv(PyObject *self, PyObject *args)
5371 #ifdef MS_WINDOWS
5372 wchar_t *s1, *s2;
5373 wchar_t *newenv;
5374 #else
5375 PyObject *os1, *os2;
5376 char *s1, *s2;
5377 char *newenv;
5378 #endif
5379 PyObject *newstr;
5380 size_t len;
5382 #ifdef MS_WINDOWS
5383 if (!PyArg_ParseTuple(args,
5384 "uu:putenv",
5385 &s1, &s2))
5386 return NULL;
5387 #else
5388 if (!PyArg_ParseTuple(args,
5389 "O&O&:putenv",
5390 PyUnicode_FSConverter, &os1,
5391 PyUnicode_FSConverter, &os2))
5392 return NULL;
5393 s1 = bytes2str(os1, 1);
5394 s2 = bytes2str(os2, 1);
5395 #endif
5397 #if defined(PYOS_OS2)
5398 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5399 APIRET rc;
5401 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5402 if (rc != NO_ERROR)
5403 return os2_error(rc);
5405 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5406 APIRET rc;
5408 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5409 if (rc != NO_ERROR)
5410 return os2_error(rc);
5411 } else {
5412 #endif
5413 /* XXX This can leak memory -- not easy to fix :-( */
5414 /* len includes space for a trailing \0; the size arg to
5415 PyBytes_FromStringAndSize does not count that */
5416 #ifdef MS_WINDOWS
5417 len = wcslen(s1) + wcslen(s2) + 2;
5418 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
5419 #else
5420 len = strlen(s1) + strlen(s2) + 2;
5421 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
5422 #endif
5423 if (newstr == NULL)
5424 return PyErr_NoMemory();
5425 #ifdef MS_WINDOWS
5426 newenv = PyUnicode_AsUnicode(newstr);
5427 _snwprintf(newenv, len, L"%s=%s", s1, s2);
5428 if (_wputenv(newenv)) {
5429 Py_DECREF(newstr);
5430 posix_error();
5431 return NULL;
5433 #else
5434 newenv = PyBytes_AS_STRING(newstr);
5435 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5436 if (putenv(newenv)) {
5437 Py_DECREF(newstr);
5438 release_bytes(os1);
5439 release_bytes(os2);
5440 posix_error();
5441 return NULL;
5443 #endif
5444 /* Install the first arg and newstr in posix_putenv_garbage;
5445 * this will cause previous value to be collected. This has to
5446 * happen after the real putenv() call because the old value
5447 * was still accessible until then. */
5448 if (PyDict_SetItem(posix_putenv_garbage,
5449 PyTuple_GET_ITEM(args, 0), newstr)) {
5450 /* really not much we can do; just leak */
5451 PyErr_Clear();
5453 else {
5454 Py_DECREF(newstr);
5457 #if defined(PYOS_OS2)
5459 #endif
5460 #ifndef MS_WINDOWS
5461 release_bytes(os1);
5462 release_bytes(os2);
5463 #endif
5464 Py_INCREF(Py_None);
5465 return Py_None;
5467 #endif /* putenv */
5469 #ifdef HAVE_UNSETENV
5470 PyDoc_STRVAR(posix_unsetenv__doc__,
5471 "unsetenv(key)\n\n\
5472 Delete an environment variable.");
5474 static PyObject *
5475 posix_unsetenv(PyObject *self, PyObject *args)
5477 char *s1;
5479 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5480 return NULL;
5482 unsetenv(s1);
5484 /* Remove the key from posix_putenv_garbage;
5485 * this will cause it to be collected. This has to
5486 * happen after the real unsetenv() call because the
5487 * old value was still accessible until then.
5489 if (PyDict_DelItem(posix_putenv_garbage,
5490 PyTuple_GET_ITEM(args, 0))) {
5491 /* really not much we can do; just leak */
5492 PyErr_Clear();
5495 Py_INCREF(Py_None);
5496 return Py_None;
5498 #endif /* unsetenv */
5500 PyDoc_STRVAR(posix_strerror__doc__,
5501 "strerror(code) -> string\n\n\
5502 Translate an error code to a message string.");
5504 static PyObject *
5505 posix_strerror(PyObject *self, PyObject *args)
5507 int code;
5508 char *message;
5509 if (!PyArg_ParseTuple(args, "i:strerror", &code))
5510 return NULL;
5511 message = strerror(code);
5512 if (message == NULL) {
5513 PyErr_SetString(PyExc_ValueError,
5514 "strerror() argument out of range");
5515 return NULL;
5517 return PyUnicode_FromString(message);
5521 #ifdef HAVE_SYS_WAIT_H
5523 #ifdef WCOREDUMP
5524 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
5525 "WCOREDUMP(status) -> bool\n\n\
5526 Return True if the process returning 'status' was dumped to a core file.");
5528 static PyObject *
5529 posix_WCOREDUMP(PyObject *self, PyObject *args)
5531 WAIT_TYPE status;
5532 WAIT_STATUS_INT(status) = 0;
5534 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
5535 return NULL;
5537 return PyBool_FromLong(WCOREDUMP(status));
5539 #endif /* WCOREDUMP */
5541 #ifdef WIFCONTINUED
5542 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
5543 "WIFCONTINUED(status) -> bool\n\n\
5544 Return True if the process returning 'status' was continued from a\n\
5545 job control stop.");
5547 static PyObject *
5548 posix_WIFCONTINUED(PyObject *self, PyObject *args)
5550 WAIT_TYPE status;
5551 WAIT_STATUS_INT(status) = 0;
5553 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
5554 return NULL;
5556 return PyBool_FromLong(WIFCONTINUED(status));
5558 #endif /* WIFCONTINUED */
5560 #ifdef WIFSTOPPED
5561 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
5562 "WIFSTOPPED(status) -> bool\n\n\
5563 Return True if the process returning 'status' was stopped.");
5565 static PyObject *
5566 posix_WIFSTOPPED(PyObject *self, PyObject *args)
5568 WAIT_TYPE status;
5569 WAIT_STATUS_INT(status) = 0;
5571 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
5572 return NULL;
5574 return PyBool_FromLong(WIFSTOPPED(status));
5576 #endif /* WIFSTOPPED */
5578 #ifdef WIFSIGNALED
5579 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
5580 "WIFSIGNALED(status) -> bool\n\n\
5581 Return True if the process returning 'status' was terminated by a signal.");
5583 static PyObject *
5584 posix_WIFSIGNALED(PyObject *self, PyObject *args)
5586 WAIT_TYPE status;
5587 WAIT_STATUS_INT(status) = 0;
5589 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
5590 return NULL;
5592 return PyBool_FromLong(WIFSIGNALED(status));
5594 #endif /* WIFSIGNALED */
5596 #ifdef WIFEXITED
5597 PyDoc_STRVAR(posix_WIFEXITED__doc__,
5598 "WIFEXITED(status) -> bool\n\n\
5599 Return true if the process returning 'status' exited using the exit()\n\
5600 system call.");
5602 static PyObject *
5603 posix_WIFEXITED(PyObject *self, PyObject *args)
5605 WAIT_TYPE status;
5606 WAIT_STATUS_INT(status) = 0;
5608 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
5609 return NULL;
5611 return PyBool_FromLong(WIFEXITED(status));
5613 #endif /* WIFEXITED */
5615 #ifdef WEXITSTATUS
5616 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
5617 "WEXITSTATUS(status) -> integer\n\n\
5618 Return the process return code from 'status'.");
5620 static PyObject *
5621 posix_WEXITSTATUS(PyObject *self, PyObject *args)
5623 WAIT_TYPE status;
5624 WAIT_STATUS_INT(status) = 0;
5626 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
5627 return NULL;
5629 return Py_BuildValue("i", WEXITSTATUS(status));
5631 #endif /* WEXITSTATUS */
5633 #ifdef WTERMSIG
5634 PyDoc_STRVAR(posix_WTERMSIG__doc__,
5635 "WTERMSIG(status) -> integer\n\n\
5636 Return the signal that terminated the process that provided the 'status'\n\
5637 value.");
5639 static PyObject *
5640 posix_WTERMSIG(PyObject *self, PyObject *args)
5642 WAIT_TYPE status;
5643 WAIT_STATUS_INT(status) = 0;
5645 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
5646 return NULL;
5648 return Py_BuildValue("i", WTERMSIG(status));
5650 #endif /* WTERMSIG */
5652 #ifdef WSTOPSIG
5653 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
5654 "WSTOPSIG(status) -> integer\n\n\
5655 Return the signal that stopped the process that provided\n\
5656 the 'status' value.");
5658 static PyObject *
5659 posix_WSTOPSIG(PyObject *self, PyObject *args)
5661 WAIT_TYPE status;
5662 WAIT_STATUS_INT(status) = 0;
5664 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
5665 return NULL;
5667 return Py_BuildValue("i", WSTOPSIG(status));
5669 #endif /* WSTOPSIG */
5671 #endif /* HAVE_SYS_WAIT_H */
5674 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
5675 #ifdef _SCO_DS
5676 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5677 needed definitions in sys/statvfs.h */
5678 #define _SVID3
5679 #endif
5680 #include <sys/statvfs.h>
5682 static PyObject*
5683 _pystatvfs_fromstructstatvfs(struct statvfs st) {
5684 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5685 if (v == NULL)
5686 return NULL;
5688 #if !defined(HAVE_LARGEFILE_SUPPORT)
5689 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5690 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5691 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
5692 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
5693 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
5694 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
5695 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
5696 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
5697 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5698 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
5699 #else
5700 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
5701 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
5702 PyStructSequence_SET_ITEM(v, 2,
5703 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
5704 PyStructSequence_SET_ITEM(v, 3,
5705 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
5706 PyStructSequence_SET_ITEM(v, 4,
5707 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
5708 PyStructSequence_SET_ITEM(v, 5,
5709 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
5710 PyStructSequence_SET_ITEM(v, 6,
5711 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
5712 PyStructSequence_SET_ITEM(v, 7,
5713 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
5714 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
5715 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
5716 #endif
5718 return v;
5721 PyDoc_STRVAR(posix_fstatvfs__doc__,
5722 "fstatvfs(fd) -> statvfs result\n\n\
5723 Perform an fstatvfs system call on the given fd.");
5725 static PyObject *
5726 posix_fstatvfs(PyObject *self, PyObject *args)
5728 int fd, res;
5729 struct statvfs st;
5731 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
5732 return NULL;
5733 Py_BEGIN_ALLOW_THREADS
5734 res = fstatvfs(fd, &st);
5735 Py_END_ALLOW_THREADS
5736 if (res != 0)
5737 return posix_error();
5739 return _pystatvfs_fromstructstatvfs(st);
5741 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
5744 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
5745 #include <sys/statvfs.h>
5747 PyDoc_STRVAR(posix_statvfs__doc__,
5748 "statvfs(path) -> statvfs result\n\n\
5749 Perform a statvfs system call on the given path.");
5751 static PyObject *
5752 posix_statvfs(PyObject *self, PyObject *args)
5754 char *path;
5755 int res;
5756 struct statvfs st;
5757 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
5758 return NULL;
5759 Py_BEGIN_ALLOW_THREADS
5760 res = statvfs(path, &st);
5761 Py_END_ALLOW_THREADS
5762 if (res != 0)
5763 return posix_error_with_filename(path);
5765 return _pystatvfs_fromstructstatvfs(st);
5767 #endif /* HAVE_STATVFS */
5769 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5770 * It maps strings representing configuration variable names to
5771 * integer values, allowing those functions to be called with the
5772 * magic names instead of polluting the module's namespace with tons of
5773 * rarely-used constants. There are three separate tables that use
5774 * these definitions.
5776 * This code is always included, even if none of the interfaces that
5777 * need it are included. The #if hackery needed to avoid it would be
5778 * sufficiently pervasive that it's not worth the loss of readability.
5780 struct constdef {
5781 char *name;
5782 long value;
5785 static int
5786 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5787 size_t tablesize)
5789 if (PyLong_Check(arg)) {
5790 *valuep = PyLong_AS_LONG(arg);
5791 return 1;
5793 else {
5794 /* look up the value in the table using a binary search */
5795 size_t lo = 0;
5796 size_t mid;
5797 size_t hi = tablesize;
5798 int cmp;
5799 const char *confname;
5800 if (!PyUnicode_Check(arg)) {
5801 PyErr_SetString(PyExc_TypeError,
5802 "configuration names must be strings or integers");
5803 return 0;
5805 confname = _PyUnicode_AsString(arg);
5806 if (confname == NULL)
5807 return 0;
5808 while (lo < hi) {
5809 mid = (lo + hi) / 2;
5810 cmp = strcmp(confname, table[mid].name);
5811 if (cmp < 0)
5812 hi = mid;
5813 else if (cmp > 0)
5814 lo = mid + 1;
5815 else {
5816 *valuep = table[mid].value;
5817 return 1;
5820 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5821 return 0;
5826 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5827 static struct constdef posix_constants_pathconf[] = {
5828 #ifdef _PC_ABI_AIO_XFER_MAX
5829 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5830 #endif
5831 #ifdef _PC_ABI_ASYNC_IO
5832 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5833 #endif
5834 #ifdef _PC_ASYNC_IO
5835 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5836 #endif
5837 #ifdef _PC_CHOWN_RESTRICTED
5838 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5839 #endif
5840 #ifdef _PC_FILESIZEBITS
5841 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5842 #endif
5843 #ifdef _PC_LAST
5844 {"PC_LAST", _PC_LAST},
5845 #endif
5846 #ifdef _PC_LINK_MAX
5847 {"PC_LINK_MAX", _PC_LINK_MAX},
5848 #endif
5849 #ifdef _PC_MAX_CANON
5850 {"PC_MAX_CANON", _PC_MAX_CANON},
5851 #endif
5852 #ifdef _PC_MAX_INPUT
5853 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5854 #endif
5855 #ifdef _PC_NAME_MAX
5856 {"PC_NAME_MAX", _PC_NAME_MAX},
5857 #endif
5858 #ifdef _PC_NO_TRUNC
5859 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5860 #endif
5861 #ifdef _PC_PATH_MAX
5862 {"PC_PATH_MAX", _PC_PATH_MAX},
5863 #endif
5864 #ifdef _PC_PIPE_BUF
5865 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5866 #endif
5867 #ifdef _PC_PRIO_IO
5868 {"PC_PRIO_IO", _PC_PRIO_IO},
5869 #endif
5870 #ifdef _PC_SOCK_MAXBUF
5871 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5872 #endif
5873 #ifdef _PC_SYNC_IO
5874 {"PC_SYNC_IO", _PC_SYNC_IO},
5875 #endif
5876 #ifdef _PC_VDISABLE
5877 {"PC_VDISABLE", _PC_VDISABLE},
5878 #endif
5881 static int
5882 conv_path_confname(PyObject *arg, int *valuep)
5884 return conv_confname(arg, valuep, posix_constants_pathconf,
5885 sizeof(posix_constants_pathconf)
5886 / sizeof(struct constdef));
5888 #endif
5890 #ifdef HAVE_FPATHCONF
5891 PyDoc_STRVAR(posix_fpathconf__doc__,
5892 "fpathconf(fd, name) -> integer\n\n\
5893 Return the configuration limit name for the file descriptor fd.\n\
5894 If there is no limit, return -1.");
5896 static PyObject *
5897 posix_fpathconf(PyObject *self, PyObject *args)
5899 PyObject *result = NULL;
5900 int name, fd;
5902 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5903 conv_path_confname, &name)) {
5904 long limit;
5906 errno = 0;
5907 limit = fpathconf(fd, name);
5908 if (limit == -1 && errno != 0)
5909 posix_error();
5910 else
5911 result = PyLong_FromLong(limit);
5913 return result;
5915 #endif
5918 #ifdef HAVE_PATHCONF
5919 PyDoc_STRVAR(posix_pathconf__doc__,
5920 "pathconf(path, name) -> integer\n\n\
5921 Return the configuration limit name for the file or directory path.\n\
5922 If there is no limit, return -1.");
5924 static PyObject *
5925 posix_pathconf(PyObject *self, PyObject *args)
5927 PyObject *result = NULL;
5928 int name;
5929 char *path;
5931 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5932 conv_path_confname, &name)) {
5933 long limit;
5935 errno = 0;
5936 limit = pathconf(path, name);
5937 if (limit == -1 && errno != 0) {
5938 if (errno == EINVAL)
5939 /* could be a path or name problem */
5940 posix_error();
5941 else
5942 posix_error_with_filename(path);
5944 else
5945 result = PyLong_FromLong(limit);
5947 return result;
5949 #endif
5951 #ifdef HAVE_CONFSTR
5952 static struct constdef posix_constants_confstr[] = {
5953 #ifdef _CS_ARCHITECTURE
5954 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5955 #endif
5956 #ifdef _CS_GNU_LIBC_VERSION
5957 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
5958 #endif
5959 #ifdef _CS_GNU_LIBPTHREAD_VERSION
5960 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
5961 #endif
5962 #ifdef _CS_HOSTNAME
5963 {"CS_HOSTNAME", _CS_HOSTNAME},
5964 #endif
5965 #ifdef _CS_HW_PROVIDER
5966 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5967 #endif
5968 #ifdef _CS_HW_SERIAL
5969 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5970 #endif
5971 #ifdef _CS_INITTAB_NAME
5972 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5973 #endif
5974 #ifdef _CS_LFS64_CFLAGS
5975 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5976 #endif
5977 #ifdef _CS_LFS64_LDFLAGS
5978 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5979 #endif
5980 #ifdef _CS_LFS64_LIBS
5981 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5982 #endif
5983 #ifdef _CS_LFS64_LINTFLAGS
5984 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5985 #endif
5986 #ifdef _CS_LFS_CFLAGS
5987 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5988 #endif
5989 #ifdef _CS_LFS_LDFLAGS
5990 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5991 #endif
5992 #ifdef _CS_LFS_LIBS
5993 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5994 #endif
5995 #ifdef _CS_LFS_LINTFLAGS
5996 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5997 #endif
5998 #ifdef _CS_MACHINE
5999 {"CS_MACHINE", _CS_MACHINE},
6000 #endif
6001 #ifdef _CS_PATH
6002 {"CS_PATH", _CS_PATH},
6003 #endif
6004 #ifdef _CS_RELEASE
6005 {"CS_RELEASE", _CS_RELEASE},
6006 #endif
6007 #ifdef _CS_SRPC_DOMAIN
6008 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6009 #endif
6010 #ifdef _CS_SYSNAME
6011 {"CS_SYSNAME", _CS_SYSNAME},
6012 #endif
6013 #ifdef _CS_VERSION
6014 {"CS_VERSION", _CS_VERSION},
6015 #endif
6016 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6017 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6018 #endif
6019 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6020 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6021 #endif
6022 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
6023 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6024 #endif
6025 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6026 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6027 #endif
6028 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6029 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6030 #endif
6031 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6032 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6033 #endif
6034 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6035 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6036 #endif
6037 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6038 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6039 #endif
6040 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6041 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6042 #endif
6043 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6044 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6045 #endif
6046 #ifdef _CS_XBS5_LP64_OFF64_LIBS
6047 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6048 #endif
6049 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6050 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6051 #endif
6052 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6053 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6054 #endif
6055 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6056 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6057 #endif
6058 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6059 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6060 #endif
6061 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6062 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6063 #endif
6064 #ifdef _MIPS_CS_AVAIL_PROCESSORS
6065 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6066 #endif
6067 #ifdef _MIPS_CS_BASE
6068 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6069 #endif
6070 #ifdef _MIPS_CS_HOSTID
6071 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6072 #endif
6073 #ifdef _MIPS_CS_HW_NAME
6074 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6075 #endif
6076 #ifdef _MIPS_CS_NUM_PROCESSORS
6077 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6078 #endif
6079 #ifdef _MIPS_CS_OSREL_MAJ
6080 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6081 #endif
6082 #ifdef _MIPS_CS_OSREL_MIN
6083 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6084 #endif
6085 #ifdef _MIPS_CS_OSREL_PATCH
6086 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6087 #endif
6088 #ifdef _MIPS_CS_OS_NAME
6089 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6090 #endif
6091 #ifdef _MIPS_CS_OS_PROVIDER
6092 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6093 #endif
6094 #ifdef _MIPS_CS_PROCESSORS
6095 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6096 #endif
6097 #ifdef _MIPS_CS_SERIAL
6098 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6099 #endif
6100 #ifdef _MIPS_CS_VENDOR
6101 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6102 #endif
6105 static int
6106 conv_confstr_confname(PyObject *arg, int *valuep)
6108 return conv_confname(arg, valuep, posix_constants_confstr,
6109 sizeof(posix_constants_confstr)
6110 / sizeof(struct constdef));
6113 PyDoc_STRVAR(posix_confstr__doc__,
6114 "confstr(name) -> string\n\n\
6115 Return a string-valued system configuration variable.");
6117 static PyObject *
6118 posix_confstr(PyObject *self, PyObject *args)
6120 PyObject *result = NULL;
6121 int name;
6122 char buffer[256];
6124 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6125 int len;
6127 errno = 0;
6128 len = confstr(name, buffer, sizeof(buffer));
6129 if (len == 0) {
6130 if (errno) {
6131 posix_error();
6133 else {
6134 result = Py_None;
6135 Py_INCREF(Py_None);
6138 else {
6139 if ((unsigned int)len >= sizeof(buffer)) {
6140 result = PyUnicode_FromStringAndSize(NULL, len-1);
6141 if (result != NULL)
6142 confstr(name, _PyUnicode_AsString(result), len);
6144 else
6145 result = PyUnicode_FromStringAndSize(buffer, len-1);
6148 return result;
6150 #endif
6153 #ifdef HAVE_SYSCONF
6154 static struct constdef posix_constants_sysconf[] = {
6155 #ifdef _SC_2_CHAR_TERM
6156 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6157 #endif
6158 #ifdef _SC_2_C_BIND
6159 {"SC_2_C_BIND", _SC_2_C_BIND},
6160 #endif
6161 #ifdef _SC_2_C_DEV
6162 {"SC_2_C_DEV", _SC_2_C_DEV},
6163 #endif
6164 #ifdef _SC_2_C_VERSION
6165 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6166 #endif
6167 #ifdef _SC_2_FORT_DEV
6168 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6169 #endif
6170 #ifdef _SC_2_FORT_RUN
6171 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6172 #endif
6173 #ifdef _SC_2_LOCALEDEF
6174 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6175 #endif
6176 #ifdef _SC_2_SW_DEV
6177 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6178 #endif
6179 #ifdef _SC_2_UPE
6180 {"SC_2_UPE", _SC_2_UPE},
6181 #endif
6182 #ifdef _SC_2_VERSION
6183 {"SC_2_VERSION", _SC_2_VERSION},
6184 #endif
6185 #ifdef _SC_ABI_ASYNCHRONOUS_IO
6186 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6187 #endif
6188 #ifdef _SC_ACL
6189 {"SC_ACL", _SC_ACL},
6190 #endif
6191 #ifdef _SC_AIO_LISTIO_MAX
6192 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6193 #endif
6194 #ifdef _SC_AIO_MAX
6195 {"SC_AIO_MAX", _SC_AIO_MAX},
6196 #endif
6197 #ifdef _SC_AIO_PRIO_DELTA_MAX
6198 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6199 #endif
6200 #ifdef _SC_ARG_MAX
6201 {"SC_ARG_MAX", _SC_ARG_MAX},
6202 #endif
6203 #ifdef _SC_ASYNCHRONOUS_IO
6204 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6205 #endif
6206 #ifdef _SC_ATEXIT_MAX
6207 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6208 #endif
6209 #ifdef _SC_AUDIT
6210 {"SC_AUDIT", _SC_AUDIT},
6211 #endif
6212 #ifdef _SC_AVPHYS_PAGES
6213 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6214 #endif
6215 #ifdef _SC_BC_BASE_MAX
6216 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6217 #endif
6218 #ifdef _SC_BC_DIM_MAX
6219 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6220 #endif
6221 #ifdef _SC_BC_SCALE_MAX
6222 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6223 #endif
6224 #ifdef _SC_BC_STRING_MAX
6225 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6226 #endif
6227 #ifdef _SC_CAP
6228 {"SC_CAP", _SC_CAP},
6229 #endif
6230 #ifdef _SC_CHARCLASS_NAME_MAX
6231 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6232 #endif
6233 #ifdef _SC_CHAR_BIT
6234 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6235 #endif
6236 #ifdef _SC_CHAR_MAX
6237 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6238 #endif
6239 #ifdef _SC_CHAR_MIN
6240 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6241 #endif
6242 #ifdef _SC_CHILD_MAX
6243 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6244 #endif
6245 #ifdef _SC_CLK_TCK
6246 {"SC_CLK_TCK", _SC_CLK_TCK},
6247 #endif
6248 #ifdef _SC_COHER_BLKSZ
6249 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6250 #endif
6251 #ifdef _SC_COLL_WEIGHTS_MAX
6252 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6253 #endif
6254 #ifdef _SC_DCACHE_ASSOC
6255 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6256 #endif
6257 #ifdef _SC_DCACHE_BLKSZ
6258 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6259 #endif
6260 #ifdef _SC_DCACHE_LINESZ
6261 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6262 #endif
6263 #ifdef _SC_DCACHE_SZ
6264 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6265 #endif
6266 #ifdef _SC_DCACHE_TBLKSZ
6267 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6268 #endif
6269 #ifdef _SC_DELAYTIMER_MAX
6270 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6271 #endif
6272 #ifdef _SC_EQUIV_CLASS_MAX
6273 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6274 #endif
6275 #ifdef _SC_EXPR_NEST_MAX
6276 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6277 #endif
6278 #ifdef _SC_FSYNC
6279 {"SC_FSYNC", _SC_FSYNC},
6280 #endif
6281 #ifdef _SC_GETGR_R_SIZE_MAX
6282 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6283 #endif
6284 #ifdef _SC_GETPW_R_SIZE_MAX
6285 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6286 #endif
6287 #ifdef _SC_ICACHE_ASSOC
6288 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6289 #endif
6290 #ifdef _SC_ICACHE_BLKSZ
6291 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6292 #endif
6293 #ifdef _SC_ICACHE_LINESZ
6294 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6295 #endif
6296 #ifdef _SC_ICACHE_SZ
6297 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6298 #endif
6299 #ifdef _SC_INF
6300 {"SC_INF", _SC_INF},
6301 #endif
6302 #ifdef _SC_INT_MAX
6303 {"SC_INT_MAX", _SC_INT_MAX},
6304 #endif
6305 #ifdef _SC_INT_MIN
6306 {"SC_INT_MIN", _SC_INT_MIN},
6307 #endif
6308 #ifdef _SC_IOV_MAX
6309 {"SC_IOV_MAX", _SC_IOV_MAX},
6310 #endif
6311 #ifdef _SC_IP_SECOPTS
6312 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6313 #endif
6314 #ifdef _SC_JOB_CONTROL
6315 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6316 #endif
6317 #ifdef _SC_KERN_POINTERS
6318 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6319 #endif
6320 #ifdef _SC_KERN_SIM
6321 {"SC_KERN_SIM", _SC_KERN_SIM},
6322 #endif
6323 #ifdef _SC_LINE_MAX
6324 {"SC_LINE_MAX", _SC_LINE_MAX},
6325 #endif
6326 #ifdef _SC_LOGIN_NAME_MAX
6327 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6328 #endif
6329 #ifdef _SC_LOGNAME_MAX
6330 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6331 #endif
6332 #ifdef _SC_LONG_BIT
6333 {"SC_LONG_BIT", _SC_LONG_BIT},
6334 #endif
6335 #ifdef _SC_MAC
6336 {"SC_MAC", _SC_MAC},
6337 #endif
6338 #ifdef _SC_MAPPED_FILES
6339 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6340 #endif
6341 #ifdef _SC_MAXPID
6342 {"SC_MAXPID", _SC_MAXPID},
6343 #endif
6344 #ifdef _SC_MB_LEN_MAX
6345 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6346 #endif
6347 #ifdef _SC_MEMLOCK
6348 {"SC_MEMLOCK", _SC_MEMLOCK},
6349 #endif
6350 #ifdef _SC_MEMLOCK_RANGE
6351 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6352 #endif
6353 #ifdef _SC_MEMORY_PROTECTION
6354 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6355 #endif
6356 #ifdef _SC_MESSAGE_PASSING
6357 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6358 #endif
6359 #ifdef _SC_MMAP_FIXED_ALIGNMENT
6360 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6361 #endif
6362 #ifdef _SC_MQ_OPEN_MAX
6363 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6364 #endif
6365 #ifdef _SC_MQ_PRIO_MAX
6366 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6367 #endif
6368 #ifdef _SC_NACLS_MAX
6369 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6370 #endif
6371 #ifdef _SC_NGROUPS_MAX
6372 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6373 #endif
6374 #ifdef _SC_NL_ARGMAX
6375 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6376 #endif
6377 #ifdef _SC_NL_LANGMAX
6378 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6379 #endif
6380 #ifdef _SC_NL_MSGMAX
6381 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6382 #endif
6383 #ifdef _SC_NL_NMAX
6384 {"SC_NL_NMAX", _SC_NL_NMAX},
6385 #endif
6386 #ifdef _SC_NL_SETMAX
6387 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6388 #endif
6389 #ifdef _SC_NL_TEXTMAX
6390 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6391 #endif
6392 #ifdef _SC_NPROCESSORS_CONF
6393 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6394 #endif
6395 #ifdef _SC_NPROCESSORS_ONLN
6396 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6397 #endif
6398 #ifdef _SC_NPROC_CONF
6399 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6400 #endif
6401 #ifdef _SC_NPROC_ONLN
6402 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6403 #endif
6404 #ifdef _SC_NZERO
6405 {"SC_NZERO", _SC_NZERO},
6406 #endif
6407 #ifdef _SC_OPEN_MAX
6408 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6409 #endif
6410 #ifdef _SC_PAGESIZE
6411 {"SC_PAGESIZE", _SC_PAGESIZE},
6412 #endif
6413 #ifdef _SC_PAGE_SIZE
6414 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6415 #endif
6416 #ifdef _SC_PASS_MAX
6417 {"SC_PASS_MAX", _SC_PASS_MAX},
6418 #endif
6419 #ifdef _SC_PHYS_PAGES
6420 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6421 #endif
6422 #ifdef _SC_PII
6423 {"SC_PII", _SC_PII},
6424 #endif
6425 #ifdef _SC_PII_INTERNET
6426 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6427 #endif
6428 #ifdef _SC_PII_INTERNET_DGRAM
6429 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6430 #endif
6431 #ifdef _SC_PII_INTERNET_STREAM
6432 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6433 #endif
6434 #ifdef _SC_PII_OSI
6435 {"SC_PII_OSI", _SC_PII_OSI},
6436 #endif
6437 #ifdef _SC_PII_OSI_CLTS
6438 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6439 #endif
6440 #ifdef _SC_PII_OSI_COTS
6441 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6442 #endif
6443 #ifdef _SC_PII_OSI_M
6444 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6445 #endif
6446 #ifdef _SC_PII_SOCKET
6447 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6448 #endif
6449 #ifdef _SC_PII_XTI
6450 {"SC_PII_XTI", _SC_PII_XTI},
6451 #endif
6452 #ifdef _SC_POLL
6453 {"SC_POLL", _SC_POLL},
6454 #endif
6455 #ifdef _SC_PRIORITIZED_IO
6456 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6457 #endif
6458 #ifdef _SC_PRIORITY_SCHEDULING
6459 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6460 #endif
6461 #ifdef _SC_REALTIME_SIGNALS
6462 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6463 #endif
6464 #ifdef _SC_RE_DUP_MAX
6465 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6466 #endif
6467 #ifdef _SC_RTSIG_MAX
6468 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6469 #endif
6470 #ifdef _SC_SAVED_IDS
6471 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6472 #endif
6473 #ifdef _SC_SCHAR_MAX
6474 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6475 #endif
6476 #ifdef _SC_SCHAR_MIN
6477 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6478 #endif
6479 #ifdef _SC_SELECT
6480 {"SC_SELECT", _SC_SELECT},
6481 #endif
6482 #ifdef _SC_SEMAPHORES
6483 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6484 #endif
6485 #ifdef _SC_SEM_NSEMS_MAX
6486 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6487 #endif
6488 #ifdef _SC_SEM_VALUE_MAX
6489 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6490 #endif
6491 #ifdef _SC_SHARED_MEMORY_OBJECTS
6492 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6493 #endif
6494 #ifdef _SC_SHRT_MAX
6495 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6496 #endif
6497 #ifdef _SC_SHRT_MIN
6498 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6499 #endif
6500 #ifdef _SC_SIGQUEUE_MAX
6501 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6502 #endif
6503 #ifdef _SC_SIGRT_MAX
6504 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6505 #endif
6506 #ifdef _SC_SIGRT_MIN
6507 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6508 #endif
6509 #ifdef _SC_SOFTPOWER
6510 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6511 #endif
6512 #ifdef _SC_SPLIT_CACHE
6513 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6514 #endif
6515 #ifdef _SC_SSIZE_MAX
6516 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6517 #endif
6518 #ifdef _SC_STACK_PROT
6519 {"SC_STACK_PROT", _SC_STACK_PROT},
6520 #endif
6521 #ifdef _SC_STREAM_MAX
6522 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6523 #endif
6524 #ifdef _SC_SYNCHRONIZED_IO
6525 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6526 #endif
6527 #ifdef _SC_THREADS
6528 {"SC_THREADS", _SC_THREADS},
6529 #endif
6530 #ifdef _SC_THREAD_ATTR_STACKADDR
6531 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6532 #endif
6533 #ifdef _SC_THREAD_ATTR_STACKSIZE
6534 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6535 #endif
6536 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6537 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6538 #endif
6539 #ifdef _SC_THREAD_KEYS_MAX
6540 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6541 #endif
6542 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
6543 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6544 #endif
6545 #ifdef _SC_THREAD_PRIO_INHERIT
6546 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6547 #endif
6548 #ifdef _SC_THREAD_PRIO_PROTECT
6549 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6550 #endif
6551 #ifdef _SC_THREAD_PROCESS_SHARED
6552 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6553 #endif
6554 #ifdef _SC_THREAD_SAFE_FUNCTIONS
6555 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6556 #endif
6557 #ifdef _SC_THREAD_STACK_MIN
6558 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6559 #endif
6560 #ifdef _SC_THREAD_THREADS_MAX
6561 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6562 #endif
6563 #ifdef _SC_TIMERS
6564 {"SC_TIMERS", _SC_TIMERS},
6565 #endif
6566 #ifdef _SC_TIMER_MAX
6567 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6568 #endif
6569 #ifdef _SC_TTY_NAME_MAX
6570 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6571 #endif
6572 #ifdef _SC_TZNAME_MAX
6573 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6574 #endif
6575 #ifdef _SC_T_IOV_MAX
6576 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6577 #endif
6578 #ifdef _SC_UCHAR_MAX
6579 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6580 #endif
6581 #ifdef _SC_UINT_MAX
6582 {"SC_UINT_MAX", _SC_UINT_MAX},
6583 #endif
6584 #ifdef _SC_UIO_MAXIOV
6585 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6586 #endif
6587 #ifdef _SC_ULONG_MAX
6588 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6589 #endif
6590 #ifdef _SC_USHRT_MAX
6591 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6592 #endif
6593 #ifdef _SC_VERSION
6594 {"SC_VERSION", _SC_VERSION},
6595 #endif
6596 #ifdef _SC_WORD_BIT
6597 {"SC_WORD_BIT", _SC_WORD_BIT},
6598 #endif
6599 #ifdef _SC_XBS5_ILP32_OFF32
6600 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6601 #endif
6602 #ifdef _SC_XBS5_ILP32_OFFBIG
6603 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6604 #endif
6605 #ifdef _SC_XBS5_LP64_OFF64
6606 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6607 #endif
6608 #ifdef _SC_XBS5_LPBIG_OFFBIG
6609 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6610 #endif
6611 #ifdef _SC_XOPEN_CRYPT
6612 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6613 #endif
6614 #ifdef _SC_XOPEN_ENH_I18N
6615 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6616 #endif
6617 #ifdef _SC_XOPEN_LEGACY
6618 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6619 #endif
6620 #ifdef _SC_XOPEN_REALTIME
6621 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6622 #endif
6623 #ifdef _SC_XOPEN_REALTIME_THREADS
6624 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6625 #endif
6626 #ifdef _SC_XOPEN_SHM
6627 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6628 #endif
6629 #ifdef _SC_XOPEN_UNIX
6630 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6631 #endif
6632 #ifdef _SC_XOPEN_VERSION
6633 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6634 #endif
6635 #ifdef _SC_XOPEN_XCU_VERSION
6636 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6637 #endif
6638 #ifdef _SC_XOPEN_XPG2
6639 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6640 #endif
6641 #ifdef _SC_XOPEN_XPG3
6642 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6643 #endif
6644 #ifdef _SC_XOPEN_XPG4
6645 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6646 #endif
6649 static int
6650 conv_sysconf_confname(PyObject *arg, int *valuep)
6652 return conv_confname(arg, valuep, posix_constants_sysconf,
6653 sizeof(posix_constants_sysconf)
6654 / sizeof(struct constdef));
6657 PyDoc_STRVAR(posix_sysconf__doc__,
6658 "sysconf(name) -> integer\n\n\
6659 Return an integer-valued system configuration variable.");
6661 static PyObject *
6662 posix_sysconf(PyObject *self, PyObject *args)
6664 PyObject *result = NULL;
6665 int name;
6667 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6668 int value;
6670 errno = 0;
6671 value = sysconf(name);
6672 if (value == -1 && errno != 0)
6673 posix_error();
6674 else
6675 result = PyLong_FromLong(value);
6677 return result;
6679 #endif
6682 /* This code is used to ensure that the tables of configuration value names
6683 * are in sorted order as required by conv_confname(), and also to build the
6684 * the exported dictionaries that are used to publish information about the
6685 * names available on the host platform.
6687 * Sorting the table at runtime ensures that the table is properly ordered
6688 * when used, even for platforms we're not able to test on. It also makes
6689 * it easier to add additional entries to the tables.
6692 static int
6693 cmp_constdefs(const void *v1, const void *v2)
6695 const struct constdef *c1 =
6696 (const struct constdef *) v1;
6697 const struct constdef *c2 =
6698 (const struct constdef *) v2;
6700 return strcmp(c1->name, c2->name);
6703 static int
6704 setup_confname_table(struct constdef *table, size_t tablesize,
6705 char *tablename, PyObject *module)
6707 PyObject *d = NULL;
6708 size_t i;
6710 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6711 d = PyDict_New();
6712 if (d == NULL)
6713 return -1;
6715 for (i=0; i < tablesize; ++i) {
6716 PyObject *o = PyLong_FromLong(table[i].value);
6717 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6718 Py_XDECREF(o);
6719 Py_DECREF(d);
6720 return -1;
6722 Py_DECREF(o);
6724 return PyModule_AddObject(module, tablename, d);
6727 /* Return -1 on failure, 0 on success. */
6728 static int
6729 setup_confname_tables(PyObject *module)
6731 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6732 if (setup_confname_table(posix_constants_pathconf,
6733 sizeof(posix_constants_pathconf)
6734 / sizeof(struct constdef),
6735 "pathconf_names", module))
6736 return -1;
6737 #endif
6738 #ifdef HAVE_CONFSTR
6739 if (setup_confname_table(posix_constants_confstr,
6740 sizeof(posix_constants_confstr)
6741 / sizeof(struct constdef),
6742 "confstr_names", module))
6743 return -1;
6744 #endif
6745 #ifdef HAVE_SYSCONF
6746 if (setup_confname_table(posix_constants_sysconf,
6747 sizeof(posix_constants_sysconf)
6748 / sizeof(struct constdef),
6749 "sysconf_names", module))
6750 return -1;
6751 #endif
6752 return 0;
6756 PyDoc_STRVAR(posix_abort__doc__,
6757 "abort() -> does not return!\n\n\
6758 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
6759 in the hardest way possible on the hosting operating system.");
6761 static PyObject *
6762 posix_abort(PyObject *self, PyObject *noargs)
6764 abort();
6765 /*NOTREACHED*/
6766 Py_FatalError("abort() called from Python code didn't abort!");
6767 return NULL;
6770 #ifdef MS_WINDOWS
6771 PyDoc_STRVAR(win32_startfile__doc__,
6772 "startfile(filepath [, operation]) - Start a file with its associated\n\
6773 application.\n\
6775 When \"operation\" is not specified or \"open\", this acts like\n\
6776 double-clicking the file in Explorer, or giving the file name as an\n\
6777 argument to the DOS \"start\" command: the file is opened with whatever\n\
6778 application (if any) its extension is associated.\n\
6779 When another \"operation\" is given, it specifies what should be done with\n\
6780 the file. A typical operation is \"print\".\n\
6782 startfile returns as soon as the associated application is launched.\n\
6783 There is no option to wait for the application to close, and no way\n\
6784 to retrieve the application's exit status.\n\
6786 The filepath is relative to the current directory. If you want to use\n\
6787 an absolute path, make sure the first character is not a slash (\"/\");\n\
6788 the underlying Win32 ShellExecute function doesn't work if it is.");
6790 static PyObject *
6791 win32_startfile(PyObject *self, PyObject *args)
6793 PyObject *ofilepath;
6794 char *filepath;
6795 char *operation = NULL;
6796 HINSTANCE rc;
6798 if (unicode_file_names()) {
6799 PyObject *unipath, *woperation = NULL;
6800 if (!PyArg_ParseTuple(args, "U|s:startfile",
6801 &unipath, &operation)) {
6802 PyErr_Clear();
6803 goto normal;
6807 if (operation) {
6808 woperation = PyUnicode_DecodeASCII(operation,
6809 strlen(operation), NULL);
6810 if (!woperation) {
6811 PyErr_Clear();
6812 operation = NULL;
6813 goto normal;
6817 Py_BEGIN_ALLOW_THREADS
6818 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
6819 PyUnicode_AS_UNICODE(unipath),
6820 NULL, NULL, SW_SHOWNORMAL);
6821 Py_END_ALLOW_THREADS
6823 Py_XDECREF(woperation);
6824 if (rc <= (HINSTANCE)32) {
6825 PyObject *errval = win32_error_unicode("startfile",
6826 PyUnicode_AS_UNICODE(unipath));
6827 return errval;
6829 Py_INCREF(Py_None);
6830 return Py_None;
6833 normal:
6834 if (!PyArg_ParseTuple(args, "O&|s:startfile",
6835 PyUnicode_FSConverter, &ofilepath,
6836 &operation))
6837 return NULL;
6838 filepath = bytes2str(ofilepath, 1);
6839 Py_BEGIN_ALLOW_THREADS
6840 rc = ShellExecute((HWND)0, operation, filepath,
6841 NULL, NULL, SW_SHOWNORMAL);
6842 Py_END_ALLOW_THREADS
6843 if (rc <= (HINSTANCE)32) {
6844 PyObject *errval = win32_error("startfile", filepath);
6845 release_bytes(ofilepath);
6846 return errval;
6848 release_bytes(ofilepath);
6849 Py_INCREF(Py_None);
6850 return Py_None;
6852 #endif
6854 #ifdef HAVE_GETLOADAVG
6855 PyDoc_STRVAR(posix_getloadavg__doc__,
6856 "getloadavg() -> (float, float, float)\n\n\
6857 Return the number of processes in the system run queue averaged over\n\
6858 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6859 was unobtainable");
6861 static PyObject *
6862 posix_getloadavg(PyObject *self, PyObject *noargs)
6864 double loadavg[3];
6865 if (getloadavg(loadavg, 3)!=3) {
6866 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6867 return NULL;
6868 } else
6869 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6871 #endif
6873 #ifdef MS_WINDOWS
6875 PyDoc_STRVAR(win32_urandom__doc__,
6876 "urandom(n) -> str\n\n\
6877 Return n random bytes suitable for cryptographic use.");
6879 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
6880 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
6881 DWORD dwFlags );
6882 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
6883 BYTE *pbBuffer );
6885 static CRYPTGENRANDOM pCryptGenRandom = NULL;
6886 /* This handle is never explicitly released. Instead, the operating
6887 system will release it when the process terminates. */
6888 static HCRYPTPROV hCryptProv = 0;
6890 static PyObject*
6891 win32_urandom(PyObject *self, PyObject *args)
6893 int howMany;
6894 PyObject* result;
6896 /* Read arguments */
6897 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
6898 return NULL;
6899 if (howMany < 0)
6900 return PyErr_Format(PyExc_ValueError,
6901 "negative argument not allowed");
6903 if (hCryptProv == 0) {
6904 HINSTANCE hAdvAPI32 = NULL;
6905 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
6907 /* Obtain handle to the DLL containing CryptoAPI
6908 This should not fail */
6909 hAdvAPI32 = GetModuleHandle("advapi32.dll");
6910 if(hAdvAPI32 == NULL)
6911 return win32_error("GetModuleHandle", NULL);
6913 /* Obtain pointers to the CryptoAPI functions
6914 This will fail on some early versions of Win95 */
6915 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
6916 hAdvAPI32,
6917 "CryptAcquireContextA");
6918 if (pCryptAcquireContext == NULL)
6919 return PyErr_Format(PyExc_NotImplementedError,
6920 "CryptAcquireContextA not found");
6922 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
6923 hAdvAPI32, "CryptGenRandom");
6924 if (pCryptGenRandom == NULL)
6925 return PyErr_Format(PyExc_NotImplementedError,
6926 "CryptGenRandom not found");
6928 /* Acquire context */
6929 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
6930 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
6931 return win32_error("CryptAcquireContext", NULL);
6934 /* Allocate bytes */
6935 result = PyBytes_FromStringAndSize(NULL, howMany);
6936 if (result != NULL) {
6937 /* Get random data */
6938 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
6939 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
6940 PyBytes_AS_STRING(result))) {
6941 Py_DECREF(result);
6942 return win32_error("CryptGenRandom", NULL);
6945 return result;
6947 #endif
6949 PyDoc_STRVAR(device_encoding__doc__,
6950 "device_encoding(fd) -> str\n\n\
6951 Return a string describing the encoding of the device\n\
6952 if the output is a terminal; else return None.");
6954 static PyObject *
6955 device_encoding(PyObject *self, PyObject *args)
6957 int fd;
6958 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
6959 return NULL;
6960 if (!_PyVerify_fd(fd) || !isatty(fd)) {
6961 Py_INCREF(Py_None);
6962 return Py_None;
6964 #if defined(MS_WINDOWS) || defined(MS_WIN64)
6965 if (fd == 0) {
6966 char buf[100];
6967 sprintf(buf, "cp%d", GetConsoleCP());
6968 return PyUnicode_FromString(buf);
6970 if (fd == 1 || fd == 2) {
6971 char buf[100];
6972 sprintf(buf, "cp%d", GetConsoleOutputCP());
6973 return PyUnicode_FromString(buf);
6975 #elif defined(CODESET)
6977 char *codeset = nl_langinfo(CODESET);
6978 if (codeset != NULL && codeset[0] != 0)
6979 return PyUnicode_FromString(codeset);
6981 #endif
6982 Py_INCREF(Py_None);
6983 return Py_None;
6986 #ifdef __VMS
6987 /* Use openssl random routine */
6988 #include <openssl/rand.h>
6989 PyDoc_STRVAR(vms_urandom__doc__,
6990 "urandom(n) -> str\n\n\
6991 Return n random bytes suitable for cryptographic use.");
6993 static PyObject*
6994 vms_urandom(PyObject *self, PyObject *args)
6996 int howMany;
6997 PyObject* result;
6999 /* Read arguments */
7000 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7001 return NULL;
7002 if (howMany < 0)
7003 return PyErr_Format(PyExc_ValueError,
7004 "negative argument not allowed");
7006 /* Allocate bytes */
7007 result = PyBytes_FromStringAndSize(NULL, howMany);
7008 if (result != NULL) {
7009 /* Get random data */
7010 if (RAND_pseudo_bytes((unsigned char*)
7011 PyBytes_AS_STRING(result),
7012 howMany) < 0) {
7013 Py_DECREF(result);
7014 return PyErr_Format(PyExc_ValueError,
7015 "RAND_pseudo_bytes");
7018 return result;
7020 #endif
7022 static PyMethodDef posix_methods[] = {
7023 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7024 #ifdef HAVE_TTYNAME
7025 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7026 #endif
7027 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7028 #ifdef HAVE_CHFLAGS
7029 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
7030 #endif /* HAVE_CHFLAGS */
7031 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
7032 #ifdef HAVE_FCHMOD
7033 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
7034 #endif /* HAVE_FCHMOD */
7035 #ifdef HAVE_CHOWN
7036 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
7037 #endif /* HAVE_CHOWN */
7038 #ifdef HAVE_LCHMOD
7039 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
7040 #endif /* HAVE_LCHMOD */
7041 #ifdef HAVE_FCHOWN
7042 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
7043 #endif /* HAVE_FCHOWN */
7044 #ifdef HAVE_LCHFLAGS
7045 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
7046 #endif /* HAVE_LCHFLAGS */
7047 #ifdef HAVE_LCHOWN
7048 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7049 #endif /* HAVE_LCHOWN */
7050 #ifdef HAVE_CHROOT
7051 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7052 #endif
7053 #ifdef HAVE_CTERMID
7054 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
7055 #endif
7056 #ifdef HAVE_GETCWD
7057 {"getcwd", (PyCFunction)posix_getcwd_unicode,
7058 METH_NOARGS, posix_getcwd__doc__},
7059 {"getcwdb", (PyCFunction)posix_getcwd_bytes,
7060 METH_NOARGS, posix_getcwdb__doc__},
7061 #endif
7062 #ifdef HAVE_LINK
7063 {"link", posix_link, METH_VARARGS, posix_link__doc__},
7064 #endif /* HAVE_LINK */
7065 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7066 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7067 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
7068 #ifdef HAVE_NICE
7069 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
7070 #endif /* HAVE_NICE */
7071 #ifdef HAVE_READLINK
7072 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
7073 #endif /* HAVE_READLINK */
7074 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7075 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7076 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
7077 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
7078 #ifdef HAVE_SYMLINK
7079 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
7080 #endif /* HAVE_SYMLINK */
7081 #ifdef HAVE_SYSTEM
7082 {"system", posix_system, METH_VARARGS, posix_system__doc__},
7083 #endif
7084 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
7085 #ifdef HAVE_UNAME
7086 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
7087 #endif /* HAVE_UNAME */
7088 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7089 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7090 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
7091 #ifdef HAVE_TIMES
7092 {"times", posix_times, METH_NOARGS, posix_times__doc__},
7093 #endif /* HAVE_TIMES */
7094 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
7095 #ifdef HAVE_EXECV
7096 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7097 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
7098 #endif /* HAVE_EXECV */
7099 #ifdef HAVE_SPAWNV
7100 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7101 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
7102 #if defined(PYOS_OS2)
7103 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7104 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7105 #endif /* PYOS_OS2 */
7106 #endif /* HAVE_SPAWNV */
7107 #ifdef HAVE_FORK1
7108 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
7109 #endif /* HAVE_FORK1 */
7110 #ifdef HAVE_FORK
7111 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
7112 #endif /* HAVE_FORK */
7113 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
7114 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
7115 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
7116 #ifdef HAVE_FORKPTY
7117 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
7118 #endif /* HAVE_FORKPTY */
7119 #ifdef HAVE_GETEGID
7120 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
7121 #endif /* HAVE_GETEGID */
7122 #ifdef HAVE_GETEUID
7123 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
7124 #endif /* HAVE_GETEUID */
7125 #ifdef HAVE_GETGID
7126 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
7127 #endif /* HAVE_GETGID */
7128 #ifdef HAVE_GETGROUPS
7129 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
7130 #endif
7131 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
7132 #ifdef HAVE_GETPGRP
7133 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
7134 #endif /* HAVE_GETPGRP */
7135 #ifdef HAVE_GETPPID
7136 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
7137 #endif /* HAVE_GETPPID */
7138 #ifdef HAVE_GETUID
7139 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
7140 #endif /* HAVE_GETUID */
7141 #ifdef HAVE_GETLOGIN
7142 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
7143 #endif
7144 #ifdef HAVE_KILL
7145 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
7146 #endif /* HAVE_KILL */
7147 #ifdef HAVE_KILLPG
7148 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7149 #endif /* HAVE_KILLPG */
7150 #ifdef HAVE_PLOCK
7151 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
7152 #endif /* HAVE_PLOCK */
7153 #ifdef MS_WINDOWS
7154 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7155 #endif
7156 #ifdef HAVE_SETUID
7157 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
7158 #endif /* HAVE_SETUID */
7159 #ifdef HAVE_SETEUID
7160 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7161 #endif /* HAVE_SETEUID */
7162 #ifdef HAVE_SETEGID
7163 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7164 #endif /* HAVE_SETEGID */
7165 #ifdef HAVE_SETREUID
7166 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7167 #endif /* HAVE_SETREUID */
7168 #ifdef HAVE_SETREGID
7169 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7170 #endif /* HAVE_SETREGID */
7171 #ifdef HAVE_SETGID
7172 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
7173 #endif /* HAVE_SETGID */
7174 #ifdef HAVE_SETGROUPS
7175 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
7176 #endif /* HAVE_SETGROUPS */
7177 #ifdef HAVE_GETPGID
7178 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7179 #endif /* HAVE_GETPGID */
7180 #ifdef HAVE_SETPGRP
7181 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
7182 #endif /* HAVE_SETPGRP */
7183 #ifdef HAVE_WAIT
7184 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
7185 #endif /* HAVE_WAIT */
7186 #ifdef HAVE_WAIT3
7187 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7188 #endif /* HAVE_WAIT3 */
7189 #ifdef HAVE_WAIT4
7190 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7191 #endif /* HAVE_WAIT4 */
7192 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
7193 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
7194 #endif /* HAVE_WAITPID */
7195 #ifdef HAVE_GETSID
7196 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7197 #endif /* HAVE_GETSID */
7198 #ifdef HAVE_SETSID
7199 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
7200 #endif /* HAVE_SETSID */
7201 #ifdef HAVE_SETPGID
7202 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
7203 #endif /* HAVE_SETPGID */
7204 #ifdef HAVE_TCGETPGRP
7205 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
7206 #endif /* HAVE_TCGETPGRP */
7207 #ifdef HAVE_TCSETPGRP
7208 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
7209 #endif /* HAVE_TCSETPGRP */
7210 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7211 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7212 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7213 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
7214 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7215 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7216 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7217 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7218 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7219 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7220 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
7221 #ifdef HAVE_PIPE
7222 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
7223 #endif
7224 #ifdef HAVE_MKFIFO
7225 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
7226 #endif
7227 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
7228 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7229 #endif
7230 #ifdef HAVE_DEVICE_MACROS
7231 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7232 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7233 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7234 #endif
7235 #ifdef HAVE_FTRUNCATE
7236 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
7237 #endif
7238 #ifdef HAVE_PUTENV
7239 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
7240 #endif
7241 #ifdef HAVE_UNSETENV
7242 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7243 #endif
7244 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
7245 #ifdef HAVE_FCHDIR
7246 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7247 #endif
7248 #ifdef HAVE_FSYNC
7249 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
7250 #endif
7251 #ifdef HAVE_FDATASYNC
7252 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
7253 #endif
7254 #ifdef HAVE_SYS_WAIT_H
7255 #ifdef WCOREDUMP
7256 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7257 #endif /* WCOREDUMP */
7258 #ifdef WIFCONTINUED
7259 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7260 #endif /* WIFCONTINUED */
7261 #ifdef WIFSTOPPED
7262 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
7263 #endif /* WIFSTOPPED */
7264 #ifdef WIFSIGNALED
7265 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
7266 #endif /* WIFSIGNALED */
7267 #ifdef WIFEXITED
7268 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
7269 #endif /* WIFEXITED */
7270 #ifdef WEXITSTATUS
7271 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
7272 #endif /* WEXITSTATUS */
7273 #ifdef WTERMSIG
7274 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
7275 #endif /* WTERMSIG */
7276 #ifdef WSTOPSIG
7277 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
7278 #endif /* WSTOPSIG */
7279 #endif /* HAVE_SYS_WAIT_H */
7280 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
7281 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
7282 #endif
7283 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
7284 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
7285 #endif
7286 #ifdef HAVE_CONFSTR
7287 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7288 #endif
7289 #ifdef HAVE_SYSCONF
7290 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7291 #endif
7292 #ifdef HAVE_FPATHCONF
7293 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7294 #endif
7295 #ifdef HAVE_PATHCONF
7296 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7297 #endif
7298 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
7299 #ifdef MS_WINDOWS
7300 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7301 #endif
7302 #ifdef HAVE_GETLOADAVG
7303 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
7304 #endif
7305 #ifdef MS_WINDOWS
7306 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7307 #endif
7308 #ifdef __VMS
7309 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
7310 #endif
7311 {NULL, NULL} /* Sentinel */
7315 static int
7316 ins(PyObject *module, char *symbol, long value)
7318 return PyModule_AddIntConstant(module, symbol, value);
7321 #if defined(PYOS_OS2)
7322 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
7323 static int insertvalues(PyObject *module)
7325 APIRET rc;
7326 ULONG values[QSV_MAX+1];
7327 PyObject *v;
7328 char *ver, tmp[50];
7330 Py_BEGIN_ALLOW_THREADS
7331 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
7332 Py_END_ALLOW_THREADS
7334 if (rc != NO_ERROR) {
7335 os2_error(rc);
7336 return -1;
7339 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7340 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7341 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7342 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7343 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7344 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7345 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
7347 switch (values[QSV_VERSION_MINOR]) {
7348 case 0: ver = "2.00"; break;
7349 case 10: ver = "2.10"; break;
7350 case 11: ver = "2.11"; break;
7351 case 30: ver = "3.00"; break;
7352 case 40: ver = "4.00"; break;
7353 case 50: ver = "5.00"; break;
7354 default:
7355 PyOS_snprintf(tmp, sizeof(tmp),
7356 "%d-%d", values[QSV_VERSION_MAJOR],
7357 values[QSV_VERSION_MINOR]);
7358 ver = &tmp[0];
7361 /* Add Indicator of the Version of the Operating System */
7362 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
7363 return -1;
7365 /* Add Indicator of Which Drive was Used to Boot the System */
7366 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7367 tmp[1] = ':';
7368 tmp[2] = '\0';
7370 return PyModule_AddStringConstant(module, "bootdrive", tmp);
7372 #endif
7374 static int
7375 all_ins(PyObject *d)
7377 #ifdef F_OK
7378 if (ins(d, "F_OK", (long)F_OK)) return -1;
7379 #endif
7380 #ifdef R_OK
7381 if (ins(d, "R_OK", (long)R_OK)) return -1;
7382 #endif
7383 #ifdef W_OK
7384 if (ins(d, "W_OK", (long)W_OK)) return -1;
7385 #endif
7386 #ifdef X_OK
7387 if (ins(d, "X_OK", (long)X_OK)) return -1;
7388 #endif
7389 #ifdef NGROUPS_MAX
7390 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7391 #endif
7392 #ifdef TMP_MAX
7393 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7394 #endif
7395 #ifdef WCONTINUED
7396 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7397 #endif
7398 #ifdef WNOHANG
7399 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
7400 #endif
7401 #ifdef WUNTRACED
7402 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7403 #endif
7404 #ifdef O_RDONLY
7405 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7406 #endif
7407 #ifdef O_WRONLY
7408 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7409 #endif
7410 #ifdef O_RDWR
7411 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7412 #endif
7413 #ifdef O_NDELAY
7414 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7415 #endif
7416 #ifdef O_NONBLOCK
7417 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7418 #endif
7419 #ifdef O_APPEND
7420 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7421 #endif
7422 #ifdef O_DSYNC
7423 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7424 #endif
7425 #ifdef O_RSYNC
7426 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7427 #endif
7428 #ifdef O_SYNC
7429 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7430 #endif
7431 #ifdef O_NOCTTY
7432 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7433 #endif
7434 #ifdef O_CREAT
7435 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7436 #endif
7437 #ifdef O_EXCL
7438 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7439 #endif
7440 #ifdef O_TRUNC
7441 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7442 #endif
7443 #ifdef O_BINARY
7444 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7445 #endif
7446 #ifdef O_TEXT
7447 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7448 #endif
7449 #ifdef O_LARGEFILE
7450 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7451 #endif
7452 #ifdef O_SHLOCK
7453 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7454 #endif
7455 #ifdef O_EXLOCK
7456 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7457 #endif
7459 /* MS Windows */
7460 #ifdef O_NOINHERIT
7461 /* Don't inherit in child processes. */
7462 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7463 #endif
7464 #ifdef _O_SHORT_LIVED
7465 /* Optimize for short life (keep in memory). */
7466 /* MS forgot to define this one with a non-underscore form too. */
7467 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7468 #endif
7469 #ifdef O_TEMPORARY
7470 /* Automatically delete when last handle is closed. */
7471 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7472 #endif
7473 #ifdef O_RANDOM
7474 /* Optimize for random access. */
7475 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7476 #endif
7477 #ifdef O_SEQUENTIAL
7478 /* Optimize for sequential access. */
7479 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7480 #endif
7482 /* GNU extensions. */
7483 #ifdef O_ASYNC
7484 /* Send a SIGIO signal whenever input or output
7485 becomes available on file descriptor */
7486 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
7487 #endif
7488 #ifdef O_DIRECT
7489 /* Direct disk access. */
7490 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7491 #endif
7492 #ifdef O_DIRECTORY
7493 /* Must be a directory. */
7494 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7495 #endif
7496 #ifdef O_NOFOLLOW
7497 /* Do not follow links. */
7498 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7499 #endif
7500 #ifdef O_NOATIME
7501 /* Do not update the access time. */
7502 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
7503 #endif
7505 /* These come from sysexits.h */
7506 #ifdef EX_OK
7507 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
7508 #endif /* EX_OK */
7509 #ifdef EX_USAGE
7510 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
7511 #endif /* EX_USAGE */
7512 #ifdef EX_DATAERR
7513 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
7514 #endif /* EX_DATAERR */
7515 #ifdef EX_NOINPUT
7516 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
7517 #endif /* EX_NOINPUT */
7518 #ifdef EX_NOUSER
7519 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
7520 #endif /* EX_NOUSER */
7521 #ifdef EX_NOHOST
7522 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
7523 #endif /* EX_NOHOST */
7524 #ifdef EX_UNAVAILABLE
7525 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
7526 #endif /* EX_UNAVAILABLE */
7527 #ifdef EX_SOFTWARE
7528 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
7529 #endif /* EX_SOFTWARE */
7530 #ifdef EX_OSERR
7531 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
7532 #endif /* EX_OSERR */
7533 #ifdef EX_OSFILE
7534 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
7535 #endif /* EX_OSFILE */
7536 #ifdef EX_CANTCREAT
7537 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
7538 #endif /* EX_CANTCREAT */
7539 #ifdef EX_IOERR
7540 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
7541 #endif /* EX_IOERR */
7542 #ifdef EX_TEMPFAIL
7543 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
7544 #endif /* EX_TEMPFAIL */
7545 #ifdef EX_PROTOCOL
7546 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
7547 #endif /* EX_PROTOCOL */
7548 #ifdef EX_NOPERM
7549 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
7550 #endif /* EX_NOPERM */
7551 #ifdef EX_CONFIG
7552 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
7553 #endif /* EX_CONFIG */
7554 #ifdef EX_NOTFOUND
7555 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
7556 #endif /* EX_NOTFOUND */
7558 #ifdef HAVE_SPAWNV
7559 #if defined(PYOS_OS2) && defined(PYCC_GCC)
7560 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7561 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7562 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7563 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7564 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7565 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7566 if (ins(d, "P_PM", (long)P_PM)) return -1;
7567 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7568 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7569 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7570 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7571 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7572 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7573 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7574 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7575 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7576 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7577 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7578 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7579 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7580 #else
7581 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7582 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7583 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7584 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7585 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
7586 #endif
7587 #endif
7589 #if defined(PYOS_OS2)
7590 if (insertvalues(d)) return -1;
7591 #endif
7592 return 0;
7596 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
7597 #define INITFUNC PyInit_nt
7598 #define MODNAME "nt"
7600 #elif defined(PYOS_OS2)
7601 #define INITFUNC PyInit_os2
7602 #define MODNAME "os2"
7604 #else
7605 #define INITFUNC PyInit_posix
7606 #define MODNAME "posix"
7607 #endif
7609 static struct PyModuleDef posixmodule = {
7610 PyModuleDef_HEAD_INIT,
7611 MODNAME,
7612 posix__doc__,
7614 posix_methods,
7615 NULL,
7616 NULL,
7617 NULL,
7618 NULL
7622 PyMODINIT_FUNC
7623 INITFUNC(void)
7625 PyObject *m, *v;
7627 m = PyModule_Create(&posixmodule);
7628 if (m == NULL)
7629 return NULL;
7631 /* Initialize environ dictionary */
7632 v = convertenviron();
7633 Py_XINCREF(v);
7634 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
7635 return NULL;
7636 Py_DECREF(v);
7638 if (all_ins(m))
7639 return NULL;
7641 if (setup_confname_tables(m))
7642 return NULL;
7644 Py_INCREF(PyExc_OSError);
7645 PyModule_AddObject(m, "error", PyExc_OSError);
7647 #ifdef HAVE_PUTENV
7648 if (posix_putenv_garbage == NULL)
7649 posix_putenv_garbage = PyDict_New();
7650 #endif
7652 if (!initialized) {
7653 stat_result_desc.name = MODNAME ".stat_result";
7654 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7655 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7656 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7657 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7658 structseq_new = StatResultType.tp_new;
7659 StatResultType.tp_new = statresult_new;
7661 statvfs_result_desc.name = MODNAME ".statvfs_result";
7662 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
7663 #ifdef NEED_TICKS_PER_SECOND
7664 # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
7665 ticks_per_second = sysconf(_SC_CLK_TCK);
7666 # elif defined(HZ)
7667 ticks_per_second = HZ;
7668 # else
7669 ticks_per_second = 60; /* magic fallback value; may be bogus */
7670 # endif
7671 #endif
7673 Py_INCREF((PyObject*) &StatResultType);
7674 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
7675 Py_INCREF((PyObject*) &StatVFSResultType);
7676 PyModule_AddObject(m, "statvfs_result",
7677 (PyObject*) &StatVFSResultType);
7678 initialized = 1;
7680 #ifdef __APPLE__
7682 * Step 2 of weak-linking support on Mac OS X.
7684 * The code below removes functions that are not available on the
7685 * currently active platform.
7687 * This block allow one to use a python binary that was build on
7688 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
7689 * OSX 10.4.
7691 #ifdef HAVE_FSTATVFS
7692 if (fstatvfs == NULL) {
7693 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
7694 return NULL;
7697 #endif /* HAVE_FSTATVFS */
7699 #ifdef HAVE_STATVFS
7700 if (statvfs == NULL) {
7701 if (PyObject_DelAttrString(m, "statvfs") == -1) {
7702 return NULL;
7705 #endif /* HAVE_STATVFS */
7707 # ifdef HAVE_LCHOWN
7708 if (lchown == NULL) {
7709 if (PyObject_DelAttrString(m, "lchown") == -1) {
7710 return NULL;
7713 #endif /* HAVE_LCHOWN */
7716 #endif /* __APPLE__ */
7717 return m;
7721 #ifdef __cplusplus
7723 #endif