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