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