1 /** @file
2 OS-specific module implementation for EDK II and UEFI.
3 Derived from posixmodule.c in Python 2.7.2.
4
5 Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are licensed and made available under
7 the terms and conditions of the BSD License that accompanies this distribution.
8 The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 **/
14 #define PY_SSIZE_T_CLEAN
15
16 #include "Python.h"
17 #include "structseq.h"
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <wchar.h>
22 #include <sys/syslimits.h>
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28 PyDoc_STRVAR(edk2__doc__,
29 "This module provides access to UEFI firmware functionality that is\n\
30 standardized by the C Standard and the POSIX standard (a thinly\n\
31 disguised Unix interface). Refer to the library manual and\n\
32 corresponding UEFI Specification entries for more information on calls.");
33
34 #ifndef Py_USING_UNICODE
35 /* This is used in signatures of functions. */
36 #define Py_UNICODE void
37 #endif
38
39 #ifdef HAVE_SYS_TYPES_H
40 #include <sys/types.h>
41 #endif /* HAVE_SYS_TYPES_H */
42
43 #ifdef HAVE_SYS_STAT_H
44 #include <sys/stat.h>
45 #endif /* HAVE_SYS_STAT_H */
46
47 #ifdef HAVE_SYS_WAIT_H
48 #include <sys/wait.h> /* For WNOHANG */
49 #endif
50
51 #ifdef HAVE_SIGNAL_H
52 #include <signal.h>
53 #endif
54
55 #ifdef HAVE_FCNTL_H
56 #include <fcntl.h>
57 #endif /* HAVE_FCNTL_H */
58
59 #ifdef HAVE_GRP_H
60 #include <grp.h>
61 #endif
62
63 #ifdef HAVE_SYSEXITS_H
64 #include <sysexits.h>
65 #endif /* HAVE_SYSEXITS_H */
66
67 #ifdef HAVE_SYS_LOADAVG_H
68 #include <sys/loadavg.h>
69 #endif
70
71 #ifdef HAVE_UTIME_H
72 #include <utime.h>
73 #endif /* HAVE_UTIME_H */
74
75 #ifdef HAVE_SYS_UTIME_H
76 #include <sys/utime.h>
77 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
78 #endif /* HAVE_SYS_UTIME_H */
79
80 #ifdef HAVE_SYS_TIMES_H
81 #include <sys/times.h>
82 #endif /* HAVE_SYS_TIMES_H */
83
84 #ifdef HAVE_SYS_PARAM_H
85 #include <sys/param.h>
86 #endif /* HAVE_SYS_PARAM_H */
87
88 #ifdef HAVE_SYS_UTSNAME_H
89 #include <sys/utsname.h>
90 #endif /* HAVE_SYS_UTSNAME_H */
91
92 #ifdef HAVE_DIRENT_H
93 #include <dirent.h>
94 #define NAMLEN(dirent) wcslen((dirent)->FileName)
95 #else
96 #define dirent direct
97 #define NAMLEN(dirent) (dirent)->d_namlen
98 #ifdef HAVE_SYS_NDIR_H
99 #include <sys/ndir.h>
100 #endif
101 #ifdef HAVE_SYS_DIR_H
102 #include <sys/dir.h>
103 #endif
104 #ifdef HAVE_NDIR_H
105 #include <ndir.h>
106 #endif
107 #endif
108
109 #ifndef MAXPATHLEN
110 #if defined(PATH_MAX) && PATH_MAX > 1024
111 #define MAXPATHLEN PATH_MAX
112 #else
113 #define MAXPATHLEN 1024
114 #endif
115 #endif /* MAXPATHLEN */
116
117 #define WAIT_TYPE int
118 #define WAIT_STATUS_INT(s) (s)
119
120 /* Issue #1983: pid_t can be longer than a C long on some systems */
121 #if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
122 #define PARSE_PID "i"
123 #define PyLong_FromPid PyInt_FromLong
124 #define PyLong_AsPid PyInt_AsLong
125 #elif SIZEOF_PID_T == SIZEOF_LONG
126 #define PARSE_PID "l"
127 #define PyLong_FromPid PyInt_FromLong
128 #define PyLong_AsPid PyInt_AsLong
129 #elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
130 #define PARSE_PID "L"
131 #define PyLong_FromPid PyLong_FromLongLong
132 #define PyLong_AsPid PyInt_AsLongLong
133 #else
134 #error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
135 #endif /* SIZEOF_PID_T */
136
137 /* Don't use the "_r" form if we don't need it (also, won't have a
138 prototype for it, at least on Solaris -- maybe others as well?). */
139 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
140 #define USE_CTERMID_R
141 #endif
142
143 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
144 #define USE_TMPNAM_R
145 #endif
146
147 /* choose the appropriate stat and fstat functions and return structs */
148 #undef STAT
149 #undef FSTAT
150 #undef STRUCT_STAT
151 #define STAT stat
152 #define FSTAT fstat
153 #define STRUCT_STAT struct stat
154
155 /* dummy version. _PyVerify_fd() is already defined in fileobject.h */
156 #define _PyVerify_fd_dup2(A, B) (1)
157
158 #ifndef UEFI_C_SOURCE
159 /* Return a dictionary corresponding to the POSIX environment table */
160 extern char **environ;
161
162 static PyObject *
convertenviron(void)163 convertenviron(void)
164 {
165 PyObject *d;
166 char **e;
167 d = PyDict_New();
168 if (d == NULL)
169 return NULL;
170 if (environ == NULL)
171 return d;
172 /* This part ignores errors */
173 for (e = environ; *e != NULL; e++) {
174 PyObject *k;
175 PyObject *v;
176 char *p = strchr(*e, '=');
177 if (p == NULL)
178 continue;
179 k = PyString_FromStringAndSize(*e, (int)(p-*e));
180 if (k == NULL) {
181 PyErr_Clear();
182 continue;
183 }
184 v = PyString_FromString(p+1);
185 if (v == NULL) {
186 PyErr_Clear();
187 Py_DECREF(k);
188 continue;
189 }
190 if (PyDict_GetItem(d, k) == NULL) {
191 if (PyDict_SetItem(d, k, v) != 0)
192 PyErr_Clear();
193 }
194 Py_DECREF(k);
195 Py_DECREF(v);
196 }
197 return d;
198 }
199 #endif /* UEFI_C_SOURCE */
200
201 /* Set a POSIX-specific error from errno, and return NULL */
202
203 static PyObject *
posix_error(void)204 posix_error(void)
205 {
206 return PyErr_SetFromErrno(PyExc_OSError);
207 }
208 static PyObject *
posix_error_with_filename(char * name)209 posix_error_with_filename(char* name)
210 {
211 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
212 }
213
214
215 static PyObject *
posix_error_with_allocated_filename(char * name)216 posix_error_with_allocated_filename(char* name)
217 {
218 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
219 PyMem_Free(name);
220 return rc;
221 }
222
223 /* POSIX generic methods */
224
225 #ifndef UEFI_C_SOURCE
226 static PyObject *
posix_fildes(PyObject * fdobj,int (* func)(int))227 posix_fildes(PyObject *fdobj, int (*func)(int))
228 {
229 int fd;
230 int res;
231 fd = PyObject_AsFileDescriptor(fdobj);
232 if (fd < 0)
233 return NULL;
234 if (!_PyVerify_fd(fd))
235 return posix_error();
236 Py_BEGIN_ALLOW_THREADS
237 res = (*func)(fd);
238 Py_END_ALLOW_THREADS
239 if (res < 0)
240 return posix_error();
241 Py_INCREF(Py_None);
242 return Py_None;
243 }
244 #endif /* UEFI_C_SOURCE */
245
246 static PyObject *
posix_1str(PyObject * args,char * format,int (* func)(const char *))247 posix_1str(PyObject *args, char *format, int (*func)(const char*))
248 {
249 char *path1 = NULL;
250 int res;
251 if (!PyArg_ParseTuple(args, format,
252 Py_FileSystemDefaultEncoding, &path1))
253 return NULL;
254 Py_BEGIN_ALLOW_THREADS
255 res = (*func)(path1);
256 Py_END_ALLOW_THREADS
257 if (res < 0)
258 return posix_error_with_allocated_filename(path1);
259 PyMem_Free(path1);
260 Py_INCREF(Py_None);
261 return Py_None;
262 }
263
264 static PyObject *
posix_2str(PyObject * args,char * format,int (* func)(const char *,const char *))265 posix_2str(PyObject *args,
266 char *format,
267 int (*func)(const char *, const char *))
268 {
269 char *path1 = NULL, *path2 = NULL;
270 int res;
271 if (!PyArg_ParseTuple(args, format,
272 Py_FileSystemDefaultEncoding, &path1,
273 Py_FileSystemDefaultEncoding, &path2))
274 return NULL;
275 Py_BEGIN_ALLOW_THREADS
276 res = (*func)(path1, path2);
277 Py_END_ALLOW_THREADS
278 PyMem_Free(path1);
279 PyMem_Free(path2);
280 if (res != 0)
281 /* XXX how to report both path1 and path2??? */
282 return posix_error();
283 Py_INCREF(Py_None);
284 return Py_None;
285 }
286
287 PyDoc_STRVAR(stat_result__doc__,
288 "stat_result: Result from stat or lstat.\n\n\
289 This object may be accessed either as a tuple of\n\
290 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
291 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
292 \n\
293 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
294 or st_flags, they are available as attributes only.\n\
295 \n\
296 See os.stat for more information.");
297
298 static PyStructSequence_Field stat_result_fields[] = {
299 {"st_mode", "protection bits"},
300 //{"st_ino", "inode"},
301 //{"st_dev", "device"},
302 //{"st_nlink", "number of hard links"},
303 //{"st_uid", "user ID of owner"},
304 //{"st_gid", "group ID of owner"},
305 {"st_size", "total size, in bytes"},
306 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
307 {NULL, "integer time of last access"},
308 {NULL, "integer time of last modification"},
309 {NULL, "integer time of last change"},
310 {"st_atime", "time of last access"},
311 {"st_mtime", "time of last modification"},
312 {"st_ctime", "time of last change"},
313 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
314 {"st_blksize", "blocksize for filesystem I/O"},
315 #endif
316 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
317 {"st_blocks", "number of blocks allocated"},
318 #endif
319 #ifdef HAVE_STRUCT_STAT_ST_RDEV
320 {"st_rdev", "device type (if inode device)"},
321 #endif
322 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
323 {"st_flags", "user defined flags for file"},
324 #endif
325 #ifdef HAVE_STRUCT_STAT_ST_GEN
326 {"st_gen", "generation number"},
327 #endif
328 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
329 {"st_birthtime", "time of creation"},
330 #endif
331 {0}
332 };
333
334 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
335 #define ST_BLKSIZE_IDX 8
336 #else
337 #define ST_BLKSIZE_IDX 12
338 #endif
339
340 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
341 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
342 #else
343 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
344 #endif
345
346 #ifdef HAVE_STRUCT_STAT_ST_RDEV
347 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
348 #else
349 #define ST_RDEV_IDX ST_BLOCKS_IDX
350 #endif
351
352 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
353 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
354 #else
355 #define ST_FLAGS_IDX ST_RDEV_IDX
356 #endif
357
358 #ifdef HAVE_STRUCT_STAT_ST_GEN
359 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
360 #else
361 #define ST_GEN_IDX ST_FLAGS_IDX
362 #endif
363
364 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
365 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
366 #else
367 #define ST_BIRTHTIME_IDX ST_GEN_IDX
368 #endif
369
370 static PyStructSequence_Desc stat_result_desc = {
371 "stat_result", /* name */
372 stat_result__doc__, /* doc */
373 stat_result_fields,
374 10
375 };
376
377 #ifndef UEFI_C_SOURCE /* Not in UEFI */
378 PyDoc_STRVAR(statvfs_result__doc__,
379 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
380 This object may be accessed either as a tuple of\n\
381 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
382 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
383 \n\
384 See os.statvfs for more information.");
385
386 static PyStructSequence_Field statvfs_result_fields[] = {
387 {"f_bsize", },
388 {"f_frsize", },
389 {"f_blocks", },
390 {"f_bfree", },
391 {"f_bavail", },
392 {"f_files", },
393 {"f_ffree", },
394 {"f_favail", },
395 {"f_flag", },
396 {"f_namemax",},
397 {0}
398 };
399
400 static PyStructSequence_Desc statvfs_result_desc = {
401 "statvfs_result", /* name */
402 statvfs_result__doc__, /* doc */
403 statvfs_result_fields,
404 10
405 };
406
407 static PyTypeObject StatVFSResultType;
408 #endif
409
410 static int initialized;
411 static PyTypeObject StatResultType;
412 static newfunc structseq_new;
413
414 static PyObject *
statresult_new(PyTypeObject * type,PyObject * args,PyObject * kwds)415 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
416 {
417 PyStructSequence *result;
418 int i;
419
420 result = (PyStructSequence*)structseq_new(type, args, kwds);
421 if (!result)
422 return NULL;
423 /* If we have been initialized from a tuple,
424 st_?time might be set to None. Initialize it
425 from the int slots. */
426 for (i = 7; i <= 9; i++) {
427 if (result->ob_item[i+3] == Py_None) {
428 Py_DECREF(Py_None);
429 Py_INCREF(result->ob_item[i]);
430 result->ob_item[i+3] = result->ob_item[i];
431 }
432 }
433 return (PyObject*)result;
434 }
435
436
437
438 /* If true, st_?time is float. */
439 #if defined(UEFI_C_SOURCE)
440 static int _stat_float_times = 0;
441 #else
442 static int _stat_float_times = 1;
443
444 PyDoc_STRVAR(stat_float_times__doc__,
445 "stat_float_times([newval]) -> oldval\n\n\
446 Determine whether os.[lf]stat represents time stamps as float objects.\n\
447 If newval is True, future calls to stat() return floats, if it is False,\n\
448 future calls return ints. \n\
449 If newval is omitted, return the current setting.\n");
450
451 static PyObject*
stat_float_times(PyObject * self,PyObject * args)452 stat_float_times(PyObject* self, PyObject *args)
453 {
454 int newval = -1;
455
456 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
457 return NULL;
458 if (newval == -1)
459 /* Return old value */
460 return PyBool_FromLong(_stat_float_times);
461 _stat_float_times = newval;
462 Py_INCREF(Py_None);
463 return Py_None;
464 }
465 #endif /* UEFI_C_SOURCE */
466
467 static void
fill_time(PyObject * v,int index,time_t sec,unsigned long nsec)468 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
469 {
470 PyObject *fval,*ival;
471 #if SIZEOF_TIME_T > SIZEOF_LONG
472 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
473 #else
474 ival = PyInt_FromLong((long)sec);
475 #endif
476 if (!ival)
477 return;
478 if (_stat_float_times) {
479 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
480 } else {
481 fval = ival;
482 Py_INCREF(fval);
483 }
484 PyStructSequence_SET_ITEM(v, index, ival);
485 PyStructSequence_SET_ITEM(v, index+3, fval);
486 }
487
488 /* pack a system stat C structure into the Python stat tuple
489 (used by posix_stat() and posix_fstat()) */
490 static PyObject*
_pystat_fromstructstat(STRUCT_STAT * st)491 _pystat_fromstructstat(STRUCT_STAT *st)
492 {
493 unsigned long ansec, mnsec, cnsec;
494 PyObject *v = PyStructSequence_New(&StatResultType);
495 if (v == NULL)
496 return NULL;
497
498 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
499 PyStructSequence_SET_ITEM(v, 1,
500 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
501
502 ansec = mnsec = cnsec = 0;
503 /* The index used by fill_time is the index of the integer time.
504 fill_time will add 3 to the index to get the floating time index.
505 */
506 fill_time(v, 2, st->st_atime, ansec);
507 fill_time(v, 3, st->st_mtime, mnsec);
508 fill_time(v, 4, st->st_mtime, cnsec);
509
510 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
511 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
512 PyInt_FromLong((long)st->st_blksize));
513 #endif
514 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
515 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
516 PyInt_FromLong((long)st->st_blocks));
517 #endif
518 #ifdef HAVE_STRUCT_STAT_ST_RDEV
519 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
520 PyInt_FromLong((long)st->st_rdev));
521 #endif
522 #ifdef HAVE_STRUCT_STAT_ST_GEN
523 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
524 PyInt_FromLong((long)st->st_gen));
525 #endif
526 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
527 {
528 PyObject *val;
529 unsigned long bsec,bnsec;
530 bsec = (long)st->st_birthtime;
531 #ifdef HAVE_STAT_TV_NSEC2
532 bnsec = st->st_birthtimespec.tv_nsec;
533 #else
534 bnsec = 0;
535 #endif
536 if (_stat_float_times) {
537 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
538 } else {
539 val = PyInt_FromLong((long)bsec);
540 }
541 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
542 val);
543 }
544 #endif
545 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
546 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
547 PyInt_FromLong((long)st->st_flags));
548 #endif
549
550 if (PyErr_Occurred()) {
551 Py_DECREF(v);
552 return NULL;
553 }
554
555 return v;
556 }
557
558 static PyObject *
posix_do_stat(PyObject * self,PyObject * args,char * format,int (* statfunc)(const char *,STRUCT_STAT *),char * wformat,int (* wstatfunc)(const Py_UNICODE *,STRUCT_STAT *))559 posix_do_stat(PyObject *self, PyObject *args,
560 char *format,
561 int (*statfunc)(const char *, STRUCT_STAT *),
562 char *wformat,
563 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
564 {
565 STRUCT_STAT st;
566 char *path = NULL; /* pass this to stat; do not free() it */
567 char *pathfree = NULL; /* this memory must be free'd */
568 int res;
569 PyObject *result;
570
571 if (!PyArg_ParseTuple(args, format,
572 Py_FileSystemDefaultEncoding, &path))
573 return NULL;
574 pathfree = path;
575
576 Py_BEGIN_ALLOW_THREADS
577 res = (*statfunc)(path, &st);
578 Py_END_ALLOW_THREADS
579
580 if (res != 0) {
581 result = posix_error_with_filename(pathfree);
582 }
583 else
584 result = _pystat_fromstructstat(&st);
585
586 PyMem_Free(pathfree);
587 return result;
588 }
589
590 /* POSIX methods */
591
592 PyDoc_STRVAR(posix_access__doc__,
593 "access(path, mode) -> True if granted, False otherwise\n\n\
594 Use the real uid/gid to test for access to a path. Note that most\n\
595 operations will use the effective uid/gid, therefore this routine can\n\
596 be used in a suid/sgid environment to test if the invoking user has the\n\
597 specified access to the path. The mode argument can be F_OK to test\n\
598 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
599
600 static PyObject *
posix_access(PyObject * self,PyObject * args)601 posix_access(PyObject *self, PyObject *args)
602 {
603 char *path;
604 int mode;
605
606 int res;
607 if (!PyArg_ParseTuple(args, "eti:access",
608 Py_FileSystemDefaultEncoding, &path, &mode))
609 return NULL;
610 Py_BEGIN_ALLOW_THREADS
611 res = access(path, mode);
612 Py_END_ALLOW_THREADS
613 PyMem_Free(path);
614 return PyBool_FromLong(res == 0);
615 }
616
617 #ifndef F_OK
618 #define F_OK 0
619 #endif
620 #ifndef R_OK
621 #define R_OK 4
622 #endif
623 #ifndef W_OK
624 #define W_OK 2
625 #endif
626 #ifndef X_OK
627 #define X_OK 1
628 #endif
629
630 PyDoc_STRVAR(posix_chdir__doc__,
631 "chdir(path)\n\n\
632 Change the current working directory to the specified path.");
633
634 static PyObject *
posix_chdir(PyObject * self,PyObject * args)635 posix_chdir(PyObject *self, PyObject *args)
636 {
637 return posix_1str(args, "et:chdir", chdir);
638 }
639
640 PyDoc_STRVAR(posix_chmod__doc__,
641 "chmod(path, mode)\n\n\
642 Change the access permissions of a file.");
643
644 static PyObject *
posix_chmod(PyObject * self,PyObject * args)645 posix_chmod(PyObject *self, PyObject *args)
646 {
647 char *path = NULL;
648 int i;
649 int res;
650 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
651 &path, &i))
652 return NULL;
653 Py_BEGIN_ALLOW_THREADS
654 res = chmod(path, i);
655 Py_END_ALLOW_THREADS
656 if (res < 0)
657 return posix_error_with_allocated_filename(path);
658 PyMem_Free(path);
659 Py_INCREF(Py_None);
660 return Py_None;
661 }
662
663 #ifdef HAVE_FCHMOD
664 PyDoc_STRVAR(posix_fchmod__doc__,
665 "fchmod(fd, mode)\n\n\
666 Change the access permissions of the file given by file\n\
667 descriptor fd.");
668
669 static PyObject *
posix_fchmod(PyObject * self,PyObject * args)670 posix_fchmod(PyObject *self, PyObject *args)
671 {
672 int fd, mode, res;
673 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
674 return NULL;
675 Py_BEGIN_ALLOW_THREADS
676 res = fchmod(fd, mode);
677 Py_END_ALLOW_THREADS
678 if (res < 0)
679 return posix_error();
680 Py_RETURN_NONE;
681 }
682 #endif /* HAVE_FCHMOD */
683
684 #ifdef HAVE_LCHMOD
685 PyDoc_STRVAR(posix_lchmod__doc__,
686 "lchmod(path, mode)\n\n\
687 Change the access permissions of a file. If path is a symlink, this\n\
688 affects the link itself rather than the target.");
689
690 static PyObject *
posix_lchmod(PyObject * self,PyObject * args)691 posix_lchmod(PyObject *self, PyObject *args)
692 {
693 char *path = NULL;
694 int i;
695 int res;
696 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
697 &path, &i))
698 return NULL;
699 Py_BEGIN_ALLOW_THREADS
700 res = lchmod(path, i);
701 Py_END_ALLOW_THREADS
702 if (res < 0)
703 return posix_error_with_allocated_filename(path);
704 PyMem_Free(path);
705 Py_RETURN_NONE;
706 }
707 #endif /* HAVE_LCHMOD */
708
709
710 #ifdef HAVE_CHFLAGS
711 PyDoc_STRVAR(posix_chflags__doc__,
712 "chflags(path, flags)\n\n\
713 Set file flags.");
714
715 static PyObject *
posix_chflags(PyObject * self,PyObject * args)716 posix_chflags(PyObject *self, PyObject *args)
717 {
718 char *path;
719 unsigned long flags;
720 int res;
721 if (!PyArg_ParseTuple(args, "etk:chflags",
722 Py_FileSystemDefaultEncoding, &path, &flags))
723 return NULL;
724 Py_BEGIN_ALLOW_THREADS
725 res = chflags(path, flags);
726 Py_END_ALLOW_THREADS
727 if (res < 0)
728 return posix_error_with_allocated_filename(path);
729 PyMem_Free(path);
730 Py_INCREF(Py_None);
731 return Py_None;
732 }
733 #endif /* HAVE_CHFLAGS */
734
735 #ifdef HAVE_LCHFLAGS
736 PyDoc_STRVAR(posix_lchflags__doc__,
737 "lchflags(path, flags)\n\n\
738 Set file flags.\n\
739 This function will not follow symbolic links.");
740
741 static PyObject *
posix_lchflags(PyObject * self,PyObject * args)742 posix_lchflags(PyObject *self, PyObject *args)
743 {
744 char *path;
745 unsigned long flags;
746 int res;
747 if (!PyArg_ParseTuple(args, "etk:lchflags",
748 Py_FileSystemDefaultEncoding, &path, &flags))
749 return NULL;
750 Py_BEGIN_ALLOW_THREADS
751 res = lchflags(path, flags);
752 Py_END_ALLOW_THREADS
753 if (res < 0)
754 return posix_error_with_allocated_filename(path);
755 PyMem_Free(path);
756 Py_INCREF(Py_None);
757 return Py_None;
758 }
759 #endif /* HAVE_LCHFLAGS */
760
761 #ifdef HAVE_CHROOT
762 PyDoc_STRVAR(posix_chroot__doc__,
763 "chroot(path)\n\n\
764 Change root directory to path.");
765
766 static PyObject *
posix_chroot(PyObject * self,PyObject * args)767 posix_chroot(PyObject *self, PyObject *args)
768 {
769 return posix_1str(args, "et:chroot", chroot);
770 }
771 #endif
772
773 #ifdef HAVE_FSYNC
774 PyDoc_STRVAR(posix_fsync__doc__,
775 "fsync(fildes)\n\n\
776 force write of file with filedescriptor to disk.");
777
778 static PyObject *
posix_fsync(PyObject * self,PyObject * fdobj)779 posix_fsync(PyObject *self, PyObject *fdobj)
780 {
781 return posix_fildes(fdobj, fsync);
782 }
783 #endif /* HAVE_FSYNC */
784
785 #ifdef HAVE_FDATASYNC
786
787 #ifdef __hpux
788 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
789 #endif
790
791 PyDoc_STRVAR(posix_fdatasync__doc__,
792 "fdatasync(fildes)\n\n\
793 force write of file with filedescriptor to disk.\n\
794 does not force update of metadata.");
795
796 static PyObject *
posix_fdatasync(PyObject * self,PyObject * fdobj)797 posix_fdatasync(PyObject *self, PyObject *fdobj)
798 {
799 return posix_fildes(fdobj, fdatasync);
800 }
801 #endif /* HAVE_FDATASYNC */
802
803
804 #ifdef HAVE_CHOWN
805 PyDoc_STRVAR(posix_chown__doc__,
806 "chown(path, uid, gid)\n\n\
807 Change the owner and group id of path to the numeric uid and gid.");
808
809 static PyObject *
posix_chown(PyObject * self,PyObject * args)810 posix_chown(PyObject *self, PyObject *args)
811 {
812 char *path = NULL;
813 long uid, gid;
814 int res;
815 if (!PyArg_ParseTuple(args, "etll:chown",
816 Py_FileSystemDefaultEncoding, &path,
817 &uid, &gid))
818 return NULL;
819 Py_BEGIN_ALLOW_THREADS
820 res = chown(path, (uid_t) uid, (gid_t) gid);
821 Py_END_ALLOW_THREADS
822 if (res < 0)
823 return posix_error_with_allocated_filename(path);
824 PyMem_Free(path);
825 Py_INCREF(Py_None);
826 return Py_None;
827 }
828 #endif /* HAVE_CHOWN */
829
830 #ifdef HAVE_FCHOWN
831 PyDoc_STRVAR(posix_fchown__doc__,
832 "fchown(fd, uid, gid)\n\n\
833 Change the owner and group id of the file given by file descriptor\n\
834 fd to the numeric uid and gid.");
835
836 static PyObject *
posix_fchown(PyObject * self,PyObject * args)837 posix_fchown(PyObject *self, PyObject *args)
838 {
839 int fd;
840 long uid, gid;
841 int res;
842 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
843 return NULL;
844 Py_BEGIN_ALLOW_THREADS
845 res = fchown(fd, (uid_t) uid, (gid_t) gid);
846 Py_END_ALLOW_THREADS
847 if (res < 0)
848 return posix_error();
849 Py_RETURN_NONE;
850 }
851 #endif /* HAVE_FCHOWN */
852
853 #ifdef HAVE_LCHOWN
854 PyDoc_STRVAR(posix_lchown__doc__,
855 "lchown(path, uid, gid)\n\n\
856 Change the owner and group id of path to the numeric uid and gid.\n\
857 This function will not follow symbolic links.");
858
859 static PyObject *
posix_lchown(PyObject * self,PyObject * args)860 posix_lchown(PyObject *self, PyObject *args)
861 {
862 char *path = NULL;
863 long uid, gid;
864 int res;
865 if (!PyArg_ParseTuple(args, "etll:lchown",
866 Py_FileSystemDefaultEncoding, &path,
867 &uid, &gid))
868 return NULL;
869 Py_BEGIN_ALLOW_THREADS
870 res = lchown(path, (uid_t) uid, (gid_t) gid);
871 Py_END_ALLOW_THREADS
872 if (res < 0)
873 return posix_error_with_allocated_filename(path);
874 PyMem_Free(path);
875 Py_INCREF(Py_None);
876 return Py_None;
877 }
878 #endif /* HAVE_LCHOWN */
879
880
881 #ifdef HAVE_GETCWD
882 PyDoc_STRVAR(posix_getcwd__doc__,
883 "getcwd() -> path\n\n\
884 Return a string representing the current working directory.");
885
886 static PyObject *
posix_getcwd(PyObject * self,PyObject * noargs)887 posix_getcwd(PyObject *self, PyObject *noargs)
888 {
889 int bufsize_incr = 1024;
890 int bufsize = 0;
891 char *tmpbuf = NULL;
892 char *res = NULL;
893 PyObject *dynamic_return;
894
895 Py_BEGIN_ALLOW_THREADS
896 do {
897 bufsize = bufsize + bufsize_incr;
898 tmpbuf = malloc(bufsize);
899 if (tmpbuf == NULL) {
900 break;
901 }
902 res = getcwd(tmpbuf, bufsize);
903 if (res == NULL) {
904 free(tmpbuf);
905 }
906 } while ((res == NULL) && (errno == ERANGE));
907 Py_END_ALLOW_THREADS
908
909 if (res == NULL)
910 return posix_error();
911
912 dynamic_return = PyString_FromString(tmpbuf);
913 free(tmpbuf);
914
915 return dynamic_return;
916 }
917
918 #ifdef Py_USING_UNICODE
919 PyDoc_STRVAR(posix_getcwdu__doc__,
920 "getcwdu() -> path\n\n\
921 Return a unicode string representing the current working directory.");
922
923 static PyObject *
posix_getcwdu(PyObject * self,PyObject * noargs)924 posix_getcwdu(PyObject *self, PyObject *noargs)
925 {
926 char buf[1026];
927 char *res;
928
929 Py_BEGIN_ALLOW_THREADS
930 res = getcwd(buf, sizeof buf);
931 Py_END_ALLOW_THREADS
932 if (res == NULL)
933 return posix_error();
934 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
935 }
936 #endif /* Py_USING_UNICODE */
937 #endif /* HAVE_GETCWD */
938
939
940 PyDoc_STRVAR(posix_listdir__doc__,
941 "listdir(path) -> list_of_strings\n\n\
942 Return a list containing the names of the entries in the directory.\n\
943 \n\
944 path: path of directory to list\n\
945 \n\
946 The list is in arbitrary order. It does not include the special\n\
947 entries '.' and '..' even if they are present in the directory.");
948
949 static PyObject *
posix_listdir(PyObject * self,PyObject * args)950 posix_listdir(PyObject *self, PyObject *args)
951 {
952 /* XXX Should redo this putting the (now four) versions of opendir
953 in separate files instead of having them all here... */
954
955 char *name = NULL;
956 char *MBname;
957 PyObject *d, *v;
958 DIR *dirp;
959 struct dirent *ep;
960 int arg_is_unicode = 1;
961
962 errno = 0;
963 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
964 arg_is_unicode = 0;
965 PyErr_Clear();
966 }
967 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
968 return NULL;
969 Py_BEGIN_ALLOW_THREADS
970 dirp = opendir(name);
971 Py_END_ALLOW_THREADS
972 if (dirp == NULL) {
973 return posix_error_with_allocated_filename(name);
974 }
975 if ((d = PyList_New(0)) == NULL) {
976 Py_BEGIN_ALLOW_THREADS
977 closedir(dirp);
978 Py_END_ALLOW_THREADS
979 PyMem_Free(name);
980 return NULL;
981 }
982 if((MBname = malloc(NAME_MAX)) == NULL) {
983 Py_BEGIN_ALLOW_THREADS
984 closedir(dirp);
985 Py_END_ALLOW_THREADS
986 Py_DECREF(d);
987 PyMem_Free(name);
988 return NULL;
989 }
990 for (;;) {
991 errno = 0;
992 Py_BEGIN_ALLOW_THREADS
993 ep = readdir(dirp);
994 Py_END_ALLOW_THREADS
995 if (ep == NULL) {
996 if ((errno == 0) || (errno == EISDIR)) {
997 break;
998 } else {
999 Py_BEGIN_ALLOW_THREADS
1000 closedir(dirp);
1001 Py_END_ALLOW_THREADS
1002 Py_DECREF(d);
1003 return posix_error_with_allocated_filename(name);
1004 }
1005 }
1006 if (ep->FileName[0] == L'.' &&
1007 (NAMLEN(ep) == 1 ||
1008 (ep->FileName[1] == L'.' && NAMLEN(ep) == 2)))
1009 continue;
1010 if(wcstombs(MBname, ep->FileName, NAME_MAX) == -1) {
1011 free(MBname);
1012 Py_BEGIN_ALLOW_THREADS
1013 closedir(dirp);
1014 Py_END_ALLOW_THREADS
1015 Py_DECREF(d);
1016 PyMem_Free(name);
1017 return NULL;
1018 }
1019 v = PyString_FromStringAndSize(MBname, strlen(MBname));
1020 if (v == NULL) {
1021 Py_DECREF(d);
1022 d = NULL;
1023 break;
1024 }
1025 #ifdef Py_USING_UNICODE
1026 if (arg_is_unicode) {
1027 PyObject *w;
1028
1029 w = PyUnicode_FromEncodedObject(v,
1030 Py_FileSystemDefaultEncoding,
1031 "strict");
1032 if (w != NULL) {
1033 Py_DECREF(v);
1034 v = w;
1035 }
1036 else {
1037 /* fall back to the original byte string, as
1038 discussed in patch #683592 */
1039 PyErr_Clear();
1040 }
1041 }
1042 #endif
1043 if (PyList_Append(d, v) != 0) {
1044 Py_DECREF(v);
1045 Py_DECREF(d);
1046 d = NULL;
1047 break;
1048 }
1049 Py_DECREF(v);
1050 }
1051 Py_BEGIN_ALLOW_THREADS
1052 closedir(dirp);
1053 Py_END_ALLOW_THREADS
1054 PyMem_Free(name);
1055 if(MBname != NULL) {
1056 free(MBname);
1057 }
1058
1059 return d;
1060
1061 } /* end of posix_listdir */
1062
1063 #ifdef MS_WINDOWS
1064 /* A helper function for abspath on win32 */
1065 static PyObject *
posix__getfullpathname(PyObject * self,PyObject * args)1066 posix__getfullpathname(PyObject *self, PyObject *args)
1067 {
1068 /* assume encoded strings won't more than double no of chars */
1069 char inbuf[MAX_PATH*2];
1070 char *inbufp = inbuf;
1071 Py_ssize_t insize = sizeof(inbuf);
1072 char outbuf[MAX_PATH*2];
1073 char *temp;
1074
1075 PyUnicodeObject *po;
1076 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1077 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1078 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
1079 Py_UNICODE *wtemp;
1080 DWORD result;
1081 PyObject *v;
1082 result = GetFullPathNameW(wpath,
1083 sizeof(woutbuf)/sizeof(woutbuf[0]),
1084 woutbuf, &wtemp);
1085 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
1086 woutbufp = malloc(result * sizeof(Py_UNICODE));
1087 if (!woutbufp)
1088 return PyErr_NoMemory();
1089 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
1090 }
1091 if (result)
1092 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
1093 else
1094 v = win32_error_unicode("GetFullPathNameW", wpath);
1095 if (woutbufp != woutbuf)
1096 free(woutbufp);
1097 return v;
1098 }
1099 /* Drop the argument parsing error as narrow strings
1100 are also valid. */
1101 PyErr_Clear();
1102
1103 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1104 Py_FileSystemDefaultEncoding, &inbufp,
1105 &insize))
1106 return NULL;
1107 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1108 outbuf, &temp))
1109 return win32_error("GetFullPathName", inbuf);
1110 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1111 return PyUnicode_Decode(outbuf, strlen(outbuf),
1112 Py_FileSystemDefaultEncoding, NULL);
1113 }
1114 return PyString_FromString(outbuf);
1115 } /* end of posix__getfullpathname */
1116 #endif /* MS_WINDOWS */
1117
1118 PyDoc_STRVAR(posix_mkdir__doc__,
1119 "mkdir(path [, mode=0777])\n\n\
1120 Create a directory.");
1121
1122 static PyObject *
posix_mkdir(PyObject * self,PyObject * args)1123 posix_mkdir(PyObject *self, PyObject *args)
1124 {
1125 int res;
1126 char *path = NULL;
1127 int mode = 0777;
1128
1129 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1130 Py_FileSystemDefaultEncoding, &path, &mode))
1131 return NULL;
1132 Py_BEGIN_ALLOW_THREADS
1133 res = mkdir(path, mode);
1134 Py_END_ALLOW_THREADS
1135 if (res < 0)
1136 return posix_error_with_allocated_filename(path);
1137 PyMem_Free(path);
1138 Py_INCREF(Py_None);
1139 return Py_None;
1140 }
1141
1142
1143 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
1144 #if defined(HAVE_SYS_RESOURCE_H)
1145 #include <sys/resource.h>
1146 #endif
1147
1148
1149 #ifdef HAVE_NICE
1150 PyDoc_STRVAR(posix_nice__doc__,
1151 "nice(inc) -> new_priority\n\n\
1152 Decrease the priority of process by inc and return the new priority.");
1153
1154 static PyObject *
posix_nice(PyObject * self,PyObject * args)1155 posix_nice(PyObject *self, PyObject *args)
1156 {
1157 int increment, value;
1158
1159 if (!PyArg_ParseTuple(args, "i:nice", &increment))
1160 return NULL;
1161
1162 /* There are two flavours of 'nice': one that returns the new
1163 priority (as required by almost all standards out there) and the
1164 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1165 the use of getpriority() to get the new priority.
1166
1167 If we are of the nice family that returns the new priority, we
1168 need to clear errno before the call, and check if errno is filled
1169 before calling posix_error() on a returnvalue of -1, because the
1170 -1 may be the actual new priority! */
1171
1172 errno = 0;
1173 value = nice(increment);
1174 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
1175 if (value == 0)
1176 value = getpriority(PRIO_PROCESS, 0);
1177 #endif
1178 if (value == -1 && errno != 0)
1179 /* either nice() or getpriority() returned an error */
1180 return posix_error();
1181 return PyInt_FromLong((long) value);
1182 }
1183 #endif /* HAVE_NICE */
1184
1185 PyDoc_STRVAR(posix_rename__doc__,
1186 "rename(old, new)\n\n\
1187 Rename a file or directory.");
1188
1189 static PyObject *
posix_rename(PyObject * self,PyObject * args)1190 posix_rename(PyObject *self, PyObject *args)
1191 {
1192 return posix_2str(args, "etet:rename", rename);
1193 }
1194
1195
1196 PyDoc_STRVAR(posix_rmdir__doc__,
1197 "rmdir(path)\n\n\
1198 Remove a directory.");
1199
1200 static PyObject *
posix_rmdir(PyObject * self,PyObject * args)1201 posix_rmdir(PyObject *self, PyObject *args)
1202 {
1203 return posix_1str(args, "et:rmdir", rmdir);
1204 }
1205
1206
1207 PyDoc_STRVAR(posix_stat__doc__,
1208 "stat(path) -> stat result\n\n\
1209 Perform a stat system call on the given path.");
1210
1211 static PyObject *
posix_stat(PyObject * self,PyObject * args)1212 posix_stat(PyObject *self, PyObject *args)
1213 {
1214 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1215 }
1216
1217
1218 #ifdef HAVE_SYSTEM
1219 PyDoc_STRVAR(posix_system__doc__,
1220 "system(command) -> exit_status\n\n\
1221 Execute the command (a string) in a subshell.");
1222
1223 static PyObject *
posix_system(PyObject * self,PyObject * args)1224 posix_system(PyObject *self, PyObject *args)
1225 {
1226 char *command;
1227 long sts;
1228 if (!PyArg_ParseTuple(args, "s:system", &command))
1229 return NULL;
1230 Py_BEGIN_ALLOW_THREADS
1231 sts = system(command);
1232 Py_END_ALLOW_THREADS
1233 return PyInt_FromLong(sts);
1234 }
1235 #endif
1236
1237
1238 PyDoc_STRVAR(posix_umask__doc__,
1239 "umask(new_mask) -> old_mask\n\n\
1240 Set the current numeric umask and return the previous umask.");
1241
1242 static PyObject *
posix_umask(PyObject * self,PyObject * args)1243 posix_umask(PyObject *self, PyObject *args)
1244 {
1245 int i;
1246 if (!PyArg_ParseTuple(args, "i:umask", &i))
1247 return NULL;
1248 i = (int)umask(i);
1249 if (i < 0)
1250 return posix_error();
1251 return PyInt_FromLong((long)i);
1252 }
1253
1254
1255 PyDoc_STRVAR(posix_unlink__doc__,
1256 "unlink(path)\n\n\
1257 Remove a file (same as remove(path)).");
1258
1259 PyDoc_STRVAR(posix_remove__doc__,
1260 "remove(path)\n\n\
1261 Remove a file (same as unlink(path)).");
1262
1263 static PyObject *
posix_unlink(PyObject * self,PyObject * args)1264 posix_unlink(PyObject *self, PyObject *args)
1265 {
1266 return posix_1str(args, "et:remove", unlink);
1267 }
1268
1269
1270 static int
extract_time(PyObject * t,time_t * sec,long * usec)1271 extract_time(PyObject *t, time_t* sec, long* usec)
1272 {
1273 time_t intval;
1274 if (PyFloat_Check(t)) {
1275 double tval = PyFloat_AsDouble(t);
1276 PyObject *intobj = PyNumber_Long(t);
1277 if (!intobj)
1278 return -1;
1279 #if SIZEOF_TIME_T > SIZEOF_LONG
1280 intval = PyInt_AsUnsignedLongLongMask(intobj);
1281 #else
1282 intval = PyInt_AsLong(intobj);
1283 #endif
1284 Py_DECREF(intobj);
1285 if (intval == -1 && PyErr_Occurred())
1286 return -1;
1287 *sec = intval;
1288 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
1289 if (*usec < 0)
1290 /* If rounding gave us a negative number,
1291 truncate. */
1292 *usec = 0;
1293 return 0;
1294 }
1295 #if SIZEOF_TIME_T > SIZEOF_LONG
1296 intval = PyInt_AsUnsignedLongLongMask(t);
1297 #else
1298 intval = PyInt_AsLong(t);
1299 #endif
1300 if (intval == -1 && PyErr_Occurred())
1301 return -1;
1302 *sec = intval;
1303 *usec = 0;
1304 return 0;
1305 }
1306
1307 PyDoc_STRVAR(posix_utime__doc__,
1308 "utime(path, (atime, mtime))\n\
1309 utime(path, None)\n\n\
1310 Set the access and modified time of the file to the given values. If the\n\
1311 second form is used, set the access and modified times to the current time.");
1312
1313 static PyObject *
posix_utime(PyObject * self,PyObject * args)1314 posix_utime(PyObject *self, PyObject *args)
1315 {
1316 char *path = NULL;
1317 time_t atime, mtime;
1318 long ausec, musec;
1319 int res;
1320 PyObject* arg;
1321
1322 #if defined(HAVE_UTIMES)
1323 struct timeval buf[2];
1324 #define ATIME buf[0].tv_sec
1325 #define MTIME buf[1].tv_sec
1326 #elif defined(HAVE_UTIME_H)
1327 /* XXX should define struct utimbuf instead, above */
1328 struct utimbuf buf;
1329 #define ATIME buf.actime
1330 #define MTIME buf.modtime
1331 #define UTIME_ARG &buf
1332 #else /* HAVE_UTIMES */
1333 time_t buf[2];
1334 #define ATIME buf[0]
1335 #define MTIME buf[1]
1336 #define UTIME_ARG buf
1337 #endif /* HAVE_UTIMES */
1338
1339
1340 if (!PyArg_ParseTuple(args, "etO:utime",
1341 Py_FileSystemDefaultEncoding, &path, &arg))
1342 return NULL;
1343 if (arg == Py_None) {
1344 /* optional time values not given */
1345 Py_BEGIN_ALLOW_THREADS
1346 res = utime(path, NULL);
1347 Py_END_ALLOW_THREADS
1348 }
1349 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
1350 PyErr_SetString(PyExc_TypeError,
1351 "utime() arg 2 must be a tuple (atime, mtime)");
1352 PyMem_Free(path);
1353 return NULL;
1354 }
1355 else {
1356 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1357 &atime, &ausec) == -1) {
1358 PyMem_Free(path);
1359 return NULL;
1360 }
1361 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1362 &mtime, &musec) == -1) {
1363 PyMem_Free(path);
1364 return NULL;
1365 }
1366 ATIME = atime;
1367 MTIME = mtime;
1368 #ifdef HAVE_UTIMES
1369 buf[0].tv_usec = ausec;
1370 buf[1].tv_usec = musec;
1371 Py_BEGIN_ALLOW_THREADS
1372 res = utimes(path, buf);
1373 Py_END_ALLOW_THREADS
1374 #else
1375 Py_BEGIN_ALLOW_THREADS
1376 res = utime(path, UTIME_ARG);
1377 Py_END_ALLOW_THREADS
1378 #endif /* HAVE_UTIMES */
1379 }
1380 if (res < 0) {
1381 return posix_error_with_allocated_filename(path);
1382 }
1383 PyMem_Free(path);
1384 Py_INCREF(Py_None);
1385 return Py_None;
1386 #undef UTIME_ARG
1387 #undef ATIME
1388 #undef MTIME
1389 }
1390
1391
1392 /* Process operations */
1393
1394 PyDoc_STRVAR(posix__exit__doc__,
1395 "_exit(status)\n\n\
1396 Exit to the system with specified status, without normal exit processing.");
1397
1398 static PyObject *
posix__exit(PyObject * self,PyObject * args)1399 posix__exit(PyObject *self, PyObject *args)
1400 {
1401 int sts;
1402 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
1403 return NULL;
1404 _Exit(sts);
1405 return NULL; /* Make gcc -Wall happy */
1406 }
1407
1408 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
1409 static void
free_string_array(char ** array,Py_ssize_t count)1410 free_string_array(char **array, Py_ssize_t count)
1411 {
1412 Py_ssize_t i;
1413 for (i = 0; i < count; i++)
1414 PyMem_Free(array[i]);
1415 PyMem_DEL(array);
1416 }
1417 #endif
1418
1419
1420 #ifdef HAVE_EXECV
1421 PyDoc_STRVAR(posix_execv__doc__,
1422 "execv(path, args)\n\n\
1423 Execute an executable path with arguments, replacing current process.\n\
1424 \n\
1425 path: path of executable file\n\
1426 args: tuple or list of strings");
1427
1428 static PyObject *
posix_execv(PyObject * self,PyObject * args)1429 posix_execv(PyObject *self, PyObject *args)
1430 {
1431 char *path;
1432 PyObject *argv;
1433 char **argvlist;
1434 Py_ssize_t i, argc;
1435 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1436
1437 /* execv has two arguments: (path, argv), where
1438 argv is a list or tuple of strings. */
1439
1440 if (!PyArg_ParseTuple(args, "etO:execv",
1441 Py_FileSystemDefaultEncoding,
1442 &path, &argv))
1443 return NULL;
1444 if (PyList_Check(argv)) {
1445 argc = PyList_Size(argv);
1446 getitem = PyList_GetItem;
1447 }
1448 else if (PyTuple_Check(argv)) {
1449 argc = PyTuple_Size(argv);
1450 getitem = PyTuple_GetItem;
1451 }
1452 else {
1453 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
1454 PyMem_Free(path);
1455 return NULL;
1456 }
1457 if (argc < 1) {
1458 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
1459 PyMem_Free(path);
1460 return NULL;
1461 }
1462
1463 argvlist = PyMem_NEW(char *, argc+1);
1464 if (argvlist == NULL) {
1465 PyMem_Free(path);
1466 return PyErr_NoMemory();
1467 }
1468 for (i = 0; i < argc; i++) {
1469 if (!PyArg_Parse((*getitem)(argv, i), "et",
1470 Py_FileSystemDefaultEncoding,
1471 &argvlist[i])) {
1472 free_string_array(argvlist, i);
1473 PyErr_SetString(PyExc_TypeError,
1474 "execv() arg 2 must contain only strings");
1475 PyMem_Free(path);
1476 return NULL;
1477
1478 }
1479 }
1480 argvlist[argc] = NULL;
1481
1482 execv(path, argvlist);
1483
1484 /* If we get here it's definitely an error */
1485
1486 free_string_array(argvlist, argc);
1487 PyMem_Free(path);
1488 return posix_error();
1489 }
1490
1491
1492 PyDoc_STRVAR(posix_execve__doc__,
1493 "execve(path, args, env)\n\n\
1494 Execute a path with arguments and environment, replacing current process.\n\
1495 \n\
1496 path: path of executable file\n\
1497 args: tuple or list of arguments\n\
1498 env: dictionary of strings mapping to strings");
1499
1500 static PyObject *
posix_execve(PyObject * self,PyObject * args)1501 posix_execve(PyObject *self, PyObject *args)
1502 {
1503 char *path;
1504 PyObject *argv, *env;
1505 char **argvlist;
1506 char **envlist;
1507 PyObject *key, *val, *keys=NULL, *vals=NULL;
1508 Py_ssize_t i, pos, argc, envc;
1509 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1510 Py_ssize_t lastarg = 0;
1511
1512 /* execve has three arguments: (path, argv, env), where
1513 argv is a list or tuple of strings and env is a dictionary
1514 like posix.environ. */
1515
1516 if (!PyArg_ParseTuple(args, "etOO:execve",
1517 Py_FileSystemDefaultEncoding,
1518 &path, &argv, &env))
1519 return NULL;
1520 if (PyList_Check(argv)) {
1521 argc = PyList_Size(argv);
1522 getitem = PyList_GetItem;
1523 }
1524 else if (PyTuple_Check(argv)) {
1525 argc = PyTuple_Size(argv);
1526 getitem = PyTuple_GetItem;
1527 }
1528 else {
1529 PyErr_SetString(PyExc_TypeError,
1530 "execve() arg 2 must be a tuple or list");
1531 goto fail_0;
1532 }
1533 if (!PyMapping_Check(env)) {
1534 PyErr_SetString(PyExc_TypeError,
1535 "execve() arg 3 must be a mapping object");
1536 goto fail_0;
1537 }
1538
1539 argvlist = PyMem_NEW(char *, argc+1);
1540 if (argvlist == NULL) {
1541 PyErr_NoMemory();
1542 goto fail_0;
1543 }
1544 for (i = 0; i < argc; i++) {
1545 if (!PyArg_Parse((*getitem)(argv, i),
1546 "et;execve() arg 2 must contain only strings",
1547 Py_FileSystemDefaultEncoding,
1548 &argvlist[i]))
1549 {
1550 lastarg = i;
1551 goto fail_1;
1552 }
1553 }
1554 lastarg = argc;
1555 argvlist[argc] = NULL;
1556
1557 i = PyMapping_Size(env);
1558 if (i < 0)
1559 goto fail_1;
1560 envlist = PyMem_NEW(char *, i + 1);
1561 if (envlist == NULL) {
1562 PyErr_NoMemory();
1563 goto fail_1;
1564 }
1565 envc = 0;
1566 keys = PyMapping_Keys(env);
1567 vals = PyMapping_Values(env);
1568 if (!keys || !vals)
1569 goto fail_2;
1570 if (!PyList_Check(keys) || !PyList_Check(vals)) {
1571 PyErr_SetString(PyExc_TypeError,
1572 "execve(): env.keys() or env.values() is not a list");
1573 goto fail_2;
1574 }
1575
1576 for (pos = 0; pos < i; pos++) {
1577 char *p, *k, *v;
1578 size_t len;
1579
1580 key = PyList_GetItem(keys, pos);
1581 val = PyList_GetItem(vals, pos);
1582 if (!key || !val)
1583 goto fail_2;
1584
1585 if (!PyArg_Parse(
1586 key,
1587 "s;execve() arg 3 contains a non-string key",
1588 &k) ||
1589 !PyArg_Parse(
1590 val,
1591 "s;execve() arg 3 contains a non-string value",
1592 &v))
1593 {
1594 goto fail_2;
1595 }
1596
1597 #if defined(PYOS_OS2)
1598 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1599 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1600 #endif
1601 len = PyString_Size(key) + PyString_Size(val) + 2;
1602 p = PyMem_NEW(char, len);
1603 if (p == NULL) {
1604 PyErr_NoMemory();
1605 goto fail_2;
1606 }
1607 PyOS_snprintf(p, len, "%s=%s", k, v);
1608 envlist[envc++] = p;
1609 #if defined(PYOS_OS2)
1610 }
1611 #endif
1612 }
1613 envlist[envc] = 0;
1614
1615 execve(path, argvlist, envlist);
1616
1617 /* If we get here it's definitely an error */
1618
1619 (void) posix_error();
1620
1621 fail_2:
1622 while (--envc >= 0)
1623 PyMem_DEL(envlist[envc]);
1624 PyMem_DEL(envlist);
1625 fail_1:
1626 free_string_array(argvlist, lastarg);
1627 Py_XDECREF(vals);
1628 Py_XDECREF(keys);
1629 fail_0:
1630 PyMem_Free(path);
1631 return NULL;
1632 }
1633 #endif /* HAVE_EXECV */
1634
1635
1636 #ifdef HAVE_SPAWNV
1637 PyDoc_STRVAR(posix_spawnv__doc__,
1638 "spawnv(mode, path, args)\n\n\
1639 Execute the program 'path' in a new process.\n\
1640 \n\
1641 mode: mode of process creation\n\
1642 path: path of executable file\n\
1643 args: tuple or list of strings");
1644
1645 static PyObject *
posix_spawnv(PyObject * self,PyObject * args)1646 posix_spawnv(PyObject *self, PyObject *args)
1647 {
1648 char *path;
1649 PyObject *argv;
1650 char **argvlist;
1651 int mode, i;
1652 Py_ssize_t argc;
1653 Py_intptr_t spawnval;
1654 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1655
1656 /* spawnv has three arguments: (mode, path, argv), where
1657 argv is a list or tuple of strings. */
1658
1659 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
1660 Py_FileSystemDefaultEncoding,
1661 &path, &argv))
1662 return NULL;
1663 if (PyList_Check(argv)) {
1664 argc = PyList_Size(argv);
1665 getitem = PyList_GetItem;
1666 }
1667 else if (PyTuple_Check(argv)) {
1668 argc = PyTuple_Size(argv);
1669 getitem = PyTuple_GetItem;
1670 }
1671 else {
1672 PyErr_SetString(PyExc_TypeError,
1673 "spawnv() arg 2 must be a tuple or list");
1674 PyMem_Free(path);
1675 return NULL;
1676 }
1677
1678 argvlist = PyMem_NEW(char *, argc+1);
1679 if (argvlist == NULL) {
1680 PyMem_Free(path);
1681 return PyErr_NoMemory();
1682 }
1683 for (i = 0; i < argc; i++) {
1684 if (!PyArg_Parse((*getitem)(argv, i), "et",
1685 Py_FileSystemDefaultEncoding,
1686 &argvlist[i])) {
1687 free_string_array(argvlist, i);
1688 PyErr_SetString(
1689 PyExc_TypeError,
1690 "spawnv() arg 2 must contain only strings");
1691 PyMem_Free(path);
1692 return NULL;
1693 }
1694 }
1695 argvlist[argc] = NULL;
1696
1697 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1698 Py_BEGIN_ALLOW_THREADS
1699 spawnval = spawnv(mode, path, argvlist);
1700 Py_END_ALLOW_THREADS
1701 #else
1702 if (mode == _OLD_P_OVERLAY)
1703 mode = _P_OVERLAY;
1704
1705 Py_BEGIN_ALLOW_THREADS
1706 spawnval = _spawnv(mode, path, argvlist);
1707 Py_END_ALLOW_THREADS
1708 #endif
1709
1710 free_string_array(argvlist, argc);
1711 PyMem_Free(path);
1712
1713 if (spawnval == -1)
1714 return posix_error();
1715 else
1716 #if SIZEOF_LONG == SIZEOF_VOID_P
1717 return Py_BuildValue("l", (long) spawnval);
1718 #else
1719 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
1720 #endif
1721 }
1722
1723
1724 PyDoc_STRVAR(posix_spawnve__doc__,
1725 "spawnve(mode, path, args, env)\n\n\
1726 Execute the program 'path' in a new process.\n\
1727 \n\
1728 mode: mode of process creation\n\
1729 path: path of executable file\n\
1730 args: tuple or list of arguments\n\
1731 env: dictionary of strings mapping to strings");
1732
1733 static PyObject *
posix_spawnve(PyObject * self,PyObject * args)1734 posix_spawnve(PyObject *self, PyObject *args)
1735 {
1736 char *path;
1737 PyObject *argv, *env;
1738 char **argvlist;
1739 char **envlist;
1740 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1741 int mode, pos, envc;
1742 Py_ssize_t argc, i;
1743 Py_intptr_t spawnval;
1744 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1745 Py_ssize_t lastarg = 0;
1746
1747 /* spawnve has four arguments: (mode, path, argv, env), where
1748 argv is a list or tuple of strings and env is a dictionary
1749 like posix.environ. */
1750
1751 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
1752 Py_FileSystemDefaultEncoding,
1753 &path, &argv, &env))
1754 return NULL;
1755 if (PyList_Check(argv)) {
1756 argc = PyList_Size(argv);
1757 getitem = PyList_GetItem;
1758 }
1759 else if (PyTuple_Check(argv)) {
1760 argc = PyTuple_Size(argv);
1761 getitem = PyTuple_GetItem;
1762 }
1763 else {
1764 PyErr_SetString(PyExc_TypeError,
1765 "spawnve() arg 2 must be a tuple or list");
1766 goto fail_0;
1767 }
1768 if (!PyMapping_Check(env)) {
1769 PyErr_SetString(PyExc_TypeError,
1770 "spawnve() arg 3 must be a mapping object");
1771 goto fail_0;
1772 }
1773
1774 argvlist = PyMem_NEW(char *, argc+1);
1775 if (argvlist == NULL) {
1776 PyErr_NoMemory();
1777 goto fail_0;
1778 }
1779 for (i = 0; i < argc; i++) {
1780 if (!PyArg_Parse((*getitem)(argv, i),
1781 "et;spawnve() arg 2 must contain only strings",
1782 Py_FileSystemDefaultEncoding,
1783 &argvlist[i]))
1784 {
1785 lastarg = i;
1786 goto fail_1;
1787 }
1788 }
1789 lastarg = argc;
1790 argvlist[argc] = NULL;
1791
1792 i = PyMapping_Size(env);
1793 if (i < 0)
1794 goto fail_1;
1795 envlist = PyMem_NEW(char *, i + 1);
1796 if (envlist == NULL) {
1797 PyErr_NoMemory();
1798 goto fail_1;
1799 }
1800 envc = 0;
1801 keys = PyMapping_Keys(env);
1802 vals = PyMapping_Values(env);
1803 if (!keys || !vals)
1804 goto fail_2;
1805 if (!PyList_Check(keys) || !PyList_Check(vals)) {
1806 PyErr_SetString(PyExc_TypeError,
1807 "spawnve(): env.keys() or env.values() is not a list");
1808 goto fail_2;
1809 }
1810
1811 for (pos = 0; pos < i; pos++) {
1812 char *p, *k, *v;
1813 size_t len;
1814
1815 key = PyList_GetItem(keys, pos);
1816 val = PyList_GetItem(vals, pos);
1817 if (!key || !val)
1818 goto fail_2;
1819
1820 if (!PyArg_Parse(
1821 key,
1822 "s;spawnve() arg 3 contains a non-string key",
1823 &k) ||
1824 !PyArg_Parse(
1825 val,
1826 "s;spawnve() arg 3 contains a non-string value",
1827 &v))
1828 {
1829 goto fail_2;
1830 }
1831 len = PyString_Size(key) + PyString_Size(val) + 2;
1832 p = PyMem_NEW(char, len);
1833 if (p == NULL) {
1834 PyErr_NoMemory();
1835 goto fail_2;
1836 }
1837 PyOS_snprintf(p, len, "%s=%s", k, v);
1838 envlist[envc++] = p;
1839 }
1840 envlist[envc] = 0;
1841
1842 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1843 Py_BEGIN_ALLOW_THREADS
1844 spawnval = spawnve(mode, path, argvlist, envlist);
1845 Py_END_ALLOW_THREADS
1846 #else
1847 if (mode == _OLD_P_OVERLAY)
1848 mode = _P_OVERLAY;
1849
1850 Py_BEGIN_ALLOW_THREADS
1851 spawnval = _spawnve(mode, path, argvlist, envlist);
1852 Py_END_ALLOW_THREADS
1853 #endif
1854
1855 if (spawnval == -1)
1856 (void) posix_error();
1857 else
1858 #if SIZEOF_LONG == SIZEOF_VOID_P
1859 res = Py_BuildValue("l", (long) spawnval);
1860 #else
1861 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
1862 #endif
1863
1864 fail_2:
1865 while (--envc >= 0)
1866 PyMem_DEL(envlist[envc]);
1867 PyMem_DEL(envlist);
1868 fail_1:
1869 free_string_array(argvlist, lastarg);
1870 Py_XDECREF(vals);
1871 Py_XDECREF(keys);
1872 fail_0:
1873 PyMem_Free(path);
1874 return res;
1875 }
1876
1877 /* OS/2 supports spawnvp & spawnvpe natively */
1878 #if defined(PYOS_OS2)
1879 PyDoc_STRVAR(posix_spawnvp__doc__,
1880 "spawnvp(mode, file, args)\n\n\
1881 Execute the program 'file' in a new process, using the environment\n\
1882 search path to find the file.\n\
1883 \n\
1884 mode: mode of process creation\n\
1885 file: executable file name\n\
1886 args: tuple or list of strings");
1887
1888 static PyObject *
posix_spawnvp(PyObject * self,PyObject * args)1889 posix_spawnvp(PyObject *self, PyObject *args)
1890 {
1891 char *path;
1892 PyObject *argv;
1893 char **argvlist;
1894 int mode, i, argc;
1895 Py_intptr_t spawnval;
1896 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1897
1898 /* spawnvp has three arguments: (mode, path, argv), where
1899 argv is a list or tuple of strings. */
1900
1901 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
1902 Py_FileSystemDefaultEncoding,
1903 &path, &argv))
1904 return NULL;
1905 if (PyList_Check(argv)) {
1906 argc = PyList_Size(argv);
1907 getitem = PyList_GetItem;
1908 }
1909 else if (PyTuple_Check(argv)) {
1910 argc = PyTuple_Size(argv);
1911 getitem = PyTuple_GetItem;
1912 }
1913 else {
1914 PyErr_SetString(PyExc_TypeError,
1915 "spawnvp() arg 2 must be a tuple or list");
1916 PyMem_Free(path);
1917 return NULL;
1918 }
1919
1920 argvlist = PyMem_NEW(char *, argc+1);
1921 if (argvlist == NULL) {
1922 PyMem_Free(path);
1923 return PyErr_NoMemory();
1924 }
1925 for (i = 0; i < argc; i++) {
1926 if (!PyArg_Parse((*getitem)(argv, i), "et",
1927 Py_FileSystemDefaultEncoding,
1928 &argvlist[i])) {
1929 free_string_array(argvlist, i);
1930 PyErr_SetString(
1931 PyExc_TypeError,
1932 "spawnvp() arg 2 must contain only strings");
1933 PyMem_Free(path);
1934 return NULL;
1935 }
1936 }
1937 argvlist[argc] = NULL;
1938
1939 Py_BEGIN_ALLOW_THREADS
1940 #if defined(PYCC_GCC)
1941 spawnval = spawnvp(mode, path, argvlist);
1942 #else
1943 spawnval = _spawnvp(mode, path, argvlist);
1944 #endif
1945 Py_END_ALLOW_THREADS
1946
1947 free_string_array(argvlist, argc);
1948 PyMem_Free(path);
1949
1950 if (spawnval == -1)
1951 return posix_error();
1952 else
1953 return Py_BuildValue("l", (long) spawnval);
1954 }
1955
1956
1957 PyDoc_STRVAR(posix_spawnvpe__doc__,
1958 "spawnvpe(mode, file, args, env)\n\n\
1959 Execute the program 'file' in a new process, using the environment\n\
1960 search path to find the file.\n\
1961 \n\
1962 mode: mode of process creation\n\
1963 file: executable file name\n\
1964 args: tuple or list of arguments\n\
1965 env: dictionary of strings mapping to strings");
1966
1967 static PyObject *
posix_spawnvpe(PyObject * self,PyObject * args)1968 posix_spawnvpe(PyObject *self, PyObject *args)
1969 {
1970 char *path;
1971 PyObject *argv, *env;
1972 char **argvlist;
1973 char **envlist;
1974 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1975 int mode, i, pos, argc, envc;
1976 Py_intptr_t spawnval;
1977 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1978 int lastarg = 0;
1979
1980 /* spawnvpe has four arguments: (mode, path, argv, env), where
1981 argv is a list or tuple of strings and env is a dictionary
1982 like posix.environ. */
1983
1984 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
1985 Py_FileSystemDefaultEncoding,
1986 &path, &argv, &env))
1987 return NULL;
1988 if (PyList_Check(argv)) {
1989 argc = PyList_Size(argv);
1990 getitem = PyList_GetItem;
1991 }
1992 else if (PyTuple_Check(argv)) {
1993 argc = PyTuple_Size(argv);
1994 getitem = PyTuple_GetItem;
1995 }
1996 else {
1997 PyErr_SetString(PyExc_TypeError,
1998 "spawnvpe() arg 2 must be a tuple or list");
1999 goto fail_0;
2000 }
2001 if (!PyMapping_Check(env)) {
2002 PyErr_SetString(PyExc_TypeError,
2003 "spawnvpe() arg 3 must be a mapping object");
2004 goto fail_0;
2005 }
2006
2007 argvlist = PyMem_NEW(char *, argc+1);
2008 if (argvlist == NULL) {
2009 PyErr_NoMemory();
2010 goto fail_0;
2011 }
2012 for (i = 0; i < argc; i++) {
2013 if (!PyArg_Parse((*getitem)(argv, i),
2014 "et;spawnvpe() arg 2 must contain only strings",
2015 Py_FileSystemDefaultEncoding,
2016 &argvlist[i]))
2017 {
2018 lastarg = i;
2019 goto fail_1;
2020 }
2021 }
2022 lastarg = argc;
2023 argvlist[argc] = NULL;
2024
2025 i = PyMapping_Size(env);
2026 if (i < 0)
2027 goto fail_1;
2028 envlist = PyMem_NEW(char *, i + 1);
2029 if (envlist == NULL) {
2030 PyErr_NoMemory();
2031 goto fail_1;
2032 }
2033 envc = 0;
2034 keys = PyMapping_Keys(env);
2035 vals = PyMapping_Values(env);
2036 if (!keys || !vals)
2037 goto fail_2;
2038 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2039 PyErr_SetString(PyExc_TypeError,
2040 "spawnvpe(): env.keys() or env.values() is not a list");
2041 goto fail_2;
2042 }
2043
2044 for (pos = 0; pos < i; pos++) {
2045 char *p, *k, *v;
2046 size_t len;
2047
2048 key = PyList_GetItem(keys, pos);
2049 val = PyList_GetItem(vals, pos);
2050 if (!key || !val)
2051 goto fail_2;
2052
2053 if (!PyArg_Parse(
2054 key,
2055 "s;spawnvpe() arg 3 contains a non-string key",
2056 &k) ||
2057 !PyArg_Parse(
2058 val,
2059 "s;spawnvpe() arg 3 contains a non-string value",
2060 &v))
2061 {
2062 goto fail_2;
2063 }
2064 len = PyString_Size(key) + PyString_Size(val) + 2;
2065 p = PyMem_NEW(char, len);
2066 if (p == NULL) {
2067 PyErr_NoMemory();
2068 goto fail_2;
2069 }
2070 PyOS_snprintf(p, len, "%s=%s", k, v);
2071 envlist[envc++] = p;
2072 }
2073 envlist[envc] = 0;
2074
2075 Py_BEGIN_ALLOW_THREADS
2076 #if defined(PYCC_GCC)
2077 spawnval = spawnvpe(mode, path, argvlist, envlist);
2078 #else
2079 spawnval = _spawnvpe(mode, path, argvlist, envlist);
2080 #endif
2081 Py_END_ALLOW_THREADS
2082
2083 if (spawnval == -1)
2084 (void) posix_error();
2085 else
2086 res = Py_BuildValue("l", (long) spawnval);
2087
2088 fail_2:
2089 while (--envc >= 0)
2090 PyMem_DEL(envlist[envc]);
2091 PyMem_DEL(envlist);
2092 fail_1:
2093 free_string_array(argvlist, lastarg);
2094 Py_XDECREF(vals);
2095 Py_XDECREF(keys);
2096 fail_0:
2097 PyMem_Free(path);
2098 return res;
2099 }
2100 #endif /* PYOS_OS2 */
2101 #endif /* HAVE_SPAWNV */
2102
2103
2104 #ifdef HAVE_FORK1
2105 PyDoc_STRVAR(posix_fork1__doc__,
2106 "fork1() -> pid\n\n\
2107 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2108 \n\
2109 Return 0 to child process and PID of child to parent process.");
2110
2111 static PyObject *
posix_fork1(PyObject * self,PyObject * noargs)2112 posix_fork1(PyObject *self, PyObject *noargs)
2113 {
2114 pid_t pid;
2115 int result = 0;
2116 _PyImport_AcquireLock();
2117 pid = fork1();
2118 if (pid == 0) {
2119 /* child: this clobbers and resets the import lock. */
2120 PyOS_AfterFork();
2121 } else {
2122 /* parent: release the import lock. */
2123 result = _PyImport_ReleaseLock();
2124 }
2125 if (pid == -1)
2126 return posix_error();
2127 if (result < 0) {
2128 /* Don't clobber the OSError if the fork failed. */
2129 PyErr_SetString(PyExc_RuntimeError,
2130 "not holding the import lock");
2131 return NULL;
2132 }
2133 return PyLong_FromPid(pid);
2134 }
2135 #endif
2136
2137
2138 #ifdef HAVE_FORK
2139 PyDoc_STRVAR(posix_fork__doc__,
2140 "fork() -> pid\n\n\
2141 Fork a child process.\n\
2142 Return 0 to child process and PID of child to parent process.");
2143
2144 static PyObject *
posix_fork(PyObject * self,PyObject * noargs)2145 posix_fork(PyObject *self, PyObject *noargs)
2146 {
2147 pid_t pid;
2148 int result = 0;
2149 _PyImport_AcquireLock();
2150 pid = fork();
2151 if (pid == 0) {
2152 /* child: this clobbers and resets the import lock. */
2153 PyOS_AfterFork();
2154 } else {
2155 /* parent: release the import lock. */
2156 result = _PyImport_ReleaseLock();
2157 }
2158 if (pid == -1)
2159 return posix_error();
2160 if (result < 0) {
2161 /* Don't clobber the OSError if the fork failed. */
2162 PyErr_SetString(PyExc_RuntimeError,
2163 "not holding the import lock");
2164 return NULL;
2165 }
2166 return PyLong_FromPid(pid);
2167 }
2168 #endif
2169
2170 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
2171 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2172 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
2173 #define DEV_PTY_FILE "/dev/ptc"
2174 #define HAVE_DEV_PTMX
2175 #else
2176 #define DEV_PTY_FILE "/dev/ptmx"
2177 #endif
2178
2179 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
2180 #ifdef HAVE_PTY_H
2181 #include <pty.h>
2182 #else
2183 #ifdef HAVE_LIBUTIL_H
2184 #include <libutil.h>
2185 #else
2186 #ifdef HAVE_UTIL_H
2187 #include <util.h>
2188 #endif /* HAVE_UTIL_H */
2189 #endif /* HAVE_LIBUTIL_H */
2190 #endif /* HAVE_PTY_H */
2191 #ifdef HAVE_STROPTS_H
2192 #include <stropts.h>
2193 #endif
2194 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
2195
2196 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
2197 PyDoc_STRVAR(posix_openpty__doc__,
2198 "openpty() -> (master_fd, slave_fd)\n\n\
2199 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
2200
2201 static PyObject *
posix_openpty(PyObject * self,PyObject * noargs)2202 posix_openpty(PyObject *self, PyObject *noargs)
2203 {
2204 int master_fd, slave_fd;
2205 #ifndef HAVE_OPENPTY
2206 char * slave_name;
2207 #endif
2208 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
2209 PyOS_sighandler_t sig_saved;
2210 #ifdef sun
2211 extern char *ptsname(int fildes);
2212 #endif
2213 #endif
2214
2215 #ifdef HAVE_OPENPTY
2216 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2217 return posix_error();
2218 #elif defined(HAVE__GETPTY)
2219 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2220 if (slave_name == NULL)
2221 return posix_error();
2222
2223 slave_fd = open(slave_name, O_RDWR);
2224 if (slave_fd < 0)
2225 return posix_error();
2226 #else
2227 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
2228 if (master_fd < 0)
2229 return posix_error();
2230 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
2231 /* change permission of slave */
2232 if (grantpt(master_fd) < 0) {
2233 PyOS_setsig(SIGCHLD, sig_saved);
2234 return posix_error();
2235 }
2236 /* unlock slave */
2237 if (unlockpt(master_fd) < 0) {
2238 PyOS_setsig(SIGCHLD, sig_saved);
2239 return posix_error();
2240 }
2241 PyOS_setsig(SIGCHLD, sig_saved);
2242 slave_name = ptsname(master_fd); /* get name of slave */
2243 if (slave_name == NULL)
2244 return posix_error();
2245 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2246 if (slave_fd < 0)
2247 return posix_error();
2248 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
2249 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2250 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
2251 #ifndef __hpux
2252 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
2253 #endif /* __hpux */
2254 #endif /* HAVE_CYGWIN */
2255 #endif /* HAVE_OPENPTY */
2256
2257 return Py_BuildValue("(ii)", master_fd, slave_fd);
2258
2259 }
2260 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
2261
2262 #ifdef HAVE_FORKPTY
2263 PyDoc_STRVAR(posix_forkpty__doc__,
2264 "forkpty() -> (pid, master_fd)\n\n\
2265 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2266 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
2267 To both, return fd of newly opened pseudo-terminal.\n");
2268
2269 static PyObject *
posix_forkpty(PyObject * self,PyObject * noargs)2270 posix_forkpty(PyObject *self, PyObject *noargs)
2271 {
2272 int master_fd = -1, result = 0;
2273 pid_t pid;
2274
2275 _PyImport_AcquireLock();
2276 pid = forkpty(&master_fd, NULL, NULL, NULL);
2277 if (pid == 0) {
2278 /* child: this clobbers and resets the import lock. */
2279 PyOS_AfterFork();
2280 } else {
2281 /* parent: release the import lock. */
2282 result = _PyImport_ReleaseLock();
2283 }
2284 if (pid == -1)
2285 return posix_error();
2286 if (result < 0) {
2287 /* Don't clobber the OSError if the fork failed. */
2288 PyErr_SetString(PyExc_RuntimeError,
2289 "not holding the import lock");
2290 return NULL;
2291 }
2292 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
2293 }
2294 #endif
2295
2296 #ifdef HAVE_GETEGID
2297 PyDoc_STRVAR(posix_getegid__doc__,
2298 "getegid() -> egid\n\n\
2299 Return the current process's effective group id.");
2300
2301 static PyObject *
posix_getegid(PyObject * self,PyObject * noargs)2302 posix_getegid(PyObject *self, PyObject *noargs)
2303 {
2304 return PyInt_FromLong((long)getegid());
2305 }
2306 #endif
2307
2308
2309 #ifdef HAVE_GETEUID
2310 PyDoc_STRVAR(posix_geteuid__doc__,
2311 "geteuid() -> euid\n\n\
2312 Return the current process's effective user id.");
2313
2314 static PyObject *
posix_geteuid(PyObject * self,PyObject * noargs)2315 posix_geteuid(PyObject *self, PyObject *noargs)
2316 {
2317 return PyInt_FromLong((long)geteuid());
2318 }
2319 #endif
2320
2321
2322 #ifdef HAVE_GETGID
2323 PyDoc_STRVAR(posix_getgid__doc__,
2324 "getgid() -> gid\n\n\
2325 Return the current process's group id.");
2326
2327 static PyObject *
posix_getgid(PyObject * self,PyObject * noargs)2328 posix_getgid(PyObject *self, PyObject *noargs)
2329 {
2330 return PyInt_FromLong((long)getgid());
2331 }
2332 #endif
2333
2334
2335 PyDoc_STRVAR(posix_getpid__doc__,
2336 "getpid() -> pid\n\n\
2337 Return the current process id");
2338
2339 static PyObject *
posix_getpid(PyObject * self,PyObject * noargs)2340 posix_getpid(PyObject *self, PyObject *noargs)
2341 {
2342 return PyLong_FromPid(getpid());
2343 }
2344
2345
2346 #ifdef HAVE_GETGROUPS
2347 PyDoc_STRVAR(posix_getgroups__doc__,
2348 "getgroups() -> list of group IDs\n\n\
2349 Return list of supplemental group IDs for the process.");
2350
2351 static PyObject *
posix_getgroups(PyObject * self,PyObject * noargs)2352 posix_getgroups(PyObject *self, PyObject *noargs)
2353 {
2354 PyObject *result = NULL;
2355
2356 #ifdef NGROUPS_MAX
2357 #define MAX_GROUPS NGROUPS_MAX
2358 #else
2359 /* defined to be 16 on Solaris7, so this should be a small number */
2360 #define MAX_GROUPS 64
2361 #endif
2362 gid_t grouplist[MAX_GROUPS];
2363
2364 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
2365 * This is a helper variable to store the intermediate result when
2366 * that happens.
2367 *
2368 * To keep the code readable the OSX behaviour is unconditional,
2369 * according to the POSIX spec this should be safe on all unix-y
2370 * systems.
2371 */
2372 gid_t* alt_grouplist = grouplist;
2373 int n;
2374
2375 n = getgroups(MAX_GROUPS, grouplist);
2376 if (n < 0) {
2377 if (errno == EINVAL) {
2378 n = getgroups(0, NULL);
2379 if (n == -1) {
2380 return posix_error();
2381 }
2382 if (n == 0) {
2383 /* Avoid malloc(0) */
2384 alt_grouplist = grouplist;
2385 } else {
2386 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
2387 if (alt_grouplist == NULL) {
2388 errno = EINVAL;
2389 return posix_error();
2390 }
2391 n = getgroups(n, alt_grouplist);
2392 if (n == -1) {
2393 PyMem_Free(alt_grouplist);
2394 return posix_error();
2395 }
2396 }
2397 } else {
2398 return posix_error();
2399 }
2400 }
2401 result = PyList_New(n);
2402 if (result != NULL) {
2403 int i;
2404 for (i = 0; i < n; ++i) {
2405 PyObject *o = PyInt_FromLong((long)alt_grouplist[i]);
2406 if (o == NULL) {
2407 Py_DECREF(result);
2408 result = NULL;
2409 break;
2410 }
2411 PyList_SET_ITEM(result, i, o);
2412 }
2413 }
2414
2415 if (alt_grouplist != grouplist) {
2416 PyMem_Free(alt_grouplist);
2417 }
2418
2419 return result;
2420 }
2421 #endif
2422
2423 #ifdef HAVE_INITGROUPS
2424 PyDoc_STRVAR(posix_initgroups__doc__,
2425 "initgroups(username, gid) -> None\n\n\
2426 Call the system initgroups() to initialize the group access list with all of\n\
2427 the groups of which the specified username is a member, plus the specified\n\
2428 group id.");
2429
2430 static PyObject *
posix_initgroups(PyObject * self,PyObject * args)2431 posix_initgroups(PyObject *self, PyObject *args)
2432 {
2433 char *username;
2434 long gid;
2435
2436 if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
2437 return NULL;
2438
2439 if (initgroups(username, (gid_t) gid) == -1)
2440 return PyErr_SetFromErrno(PyExc_OSError);
2441
2442 Py_INCREF(Py_None);
2443 return Py_None;
2444 }
2445 #endif
2446
2447 #ifdef HAVE_GETPGID
2448 PyDoc_STRVAR(posix_getpgid__doc__,
2449 "getpgid(pid) -> pgid\n\n\
2450 Call the system call getpgid().");
2451
2452 static PyObject *
posix_getpgid(PyObject * self,PyObject * args)2453 posix_getpgid(PyObject *self, PyObject *args)
2454 {
2455 pid_t pid, pgid;
2456 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
2457 return NULL;
2458 pgid = getpgid(pid);
2459 if (pgid < 0)
2460 return posix_error();
2461 return PyLong_FromPid(pgid);
2462 }
2463 #endif /* HAVE_GETPGID */
2464
2465
2466 #ifdef HAVE_GETPGRP
2467 PyDoc_STRVAR(posix_getpgrp__doc__,
2468 "getpgrp() -> pgrp\n\n\
2469 Return the current process group id.");
2470
2471 static PyObject *
posix_getpgrp(PyObject * self,PyObject * noargs)2472 posix_getpgrp(PyObject *self, PyObject *noargs)
2473 {
2474 #ifdef GETPGRP_HAVE_ARG
2475 return PyLong_FromPid(getpgrp(0));
2476 #else /* GETPGRP_HAVE_ARG */
2477 return PyLong_FromPid(getpgrp());
2478 #endif /* GETPGRP_HAVE_ARG */
2479 }
2480 #endif /* HAVE_GETPGRP */
2481
2482
2483 #ifdef HAVE_SETPGRP
2484 PyDoc_STRVAR(posix_setpgrp__doc__,
2485 "setpgrp()\n\n\
2486 Make this process the process group leader.");
2487
2488 static PyObject *
posix_setpgrp(PyObject * self,PyObject * noargs)2489 posix_setpgrp(PyObject *self, PyObject *noargs)
2490 {
2491 #ifdef SETPGRP_HAVE_ARG
2492 if (setpgrp(0, 0) < 0)
2493 #else /* SETPGRP_HAVE_ARG */
2494 if (setpgrp() < 0)
2495 #endif /* SETPGRP_HAVE_ARG */
2496 return posix_error();
2497 Py_INCREF(Py_None);
2498 return Py_None;
2499 }
2500
2501 #endif /* HAVE_SETPGRP */
2502
2503 #ifdef HAVE_GETPPID
2504 PyDoc_STRVAR(posix_getppid__doc__,
2505 "getppid() -> ppid\n\n\
2506 Return the parent's process id.");
2507
2508 static PyObject *
posix_getppid(PyObject * self,PyObject * noargs)2509 posix_getppid(PyObject *self, PyObject *noargs)
2510 {
2511 return PyLong_FromPid(getppid());
2512 }
2513 #endif
2514
2515
2516 #ifdef HAVE_GETLOGIN
2517 PyDoc_STRVAR(posix_getlogin__doc__,
2518 "getlogin() -> string\n\n\
2519 Return the actual login name.");
2520
2521 static PyObject *
posix_getlogin(PyObject * self,PyObject * noargs)2522 posix_getlogin(PyObject *self, PyObject *noargs)
2523 {
2524 PyObject *result = NULL;
2525 char *name;
2526 int old_errno = errno;
2527
2528 errno = 0;
2529 name = getlogin();
2530 if (name == NULL) {
2531 if (errno)
2532 posix_error();
2533 else
2534 PyErr_SetString(PyExc_OSError,
2535 "unable to determine login name");
2536 }
2537 else
2538 result = PyString_FromString(name);
2539 errno = old_errno;
2540
2541 return result;
2542 }
2543 #endif
2544
2545 #ifndef UEFI_C_SOURCE
2546 PyDoc_STRVAR(posix_getuid__doc__,
2547 "getuid() -> uid\n\n\
2548 Return the current process's user id.");
2549
2550 static PyObject *
posix_getuid(PyObject * self,PyObject * noargs)2551 posix_getuid(PyObject *self, PyObject *noargs)
2552 {
2553 return PyInt_FromLong((long)getuid());
2554 }
2555 #endif /* UEFI_C_SOURCE */
2556
2557 #ifdef HAVE_KILL
2558 PyDoc_STRVAR(posix_kill__doc__,
2559 "kill(pid, sig)\n\n\
2560 Kill a process with a signal.");
2561
2562 static PyObject *
posix_kill(PyObject * self,PyObject * args)2563 posix_kill(PyObject *self, PyObject *args)
2564 {
2565 pid_t pid;
2566 int sig;
2567 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
2568 return NULL;
2569 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
2570 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2571 APIRET rc;
2572 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
2573 return os2_error(rc);
2574
2575 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2576 APIRET rc;
2577 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
2578 return os2_error(rc);
2579
2580 } else
2581 return NULL; /* Unrecognized Signal Requested */
2582 #else
2583 if (kill(pid, sig) == -1)
2584 return posix_error();
2585 #endif
2586 Py_INCREF(Py_None);
2587 return Py_None;
2588 }
2589 #endif
2590
2591 #ifdef HAVE_KILLPG
2592 PyDoc_STRVAR(posix_killpg__doc__,
2593 "killpg(pgid, sig)\n\n\
2594 Kill a process group with a signal.");
2595
2596 static PyObject *
posix_killpg(PyObject * self,PyObject * args)2597 posix_killpg(PyObject *self, PyObject *args)
2598 {
2599 int sig;
2600 pid_t pgid;
2601 /* XXX some man pages make the `pgid` parameter an int, others
2602 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
2603 take the same type. Moreover, pid_t is always at least as wide as
2604 int (else compilation of this module fails), which is safe. */
2605 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
2606 return NULL;
2607 if (killpg(pgid, sig) == -1)
2608 return posix_error();
2609 Py_INCREF(Py_None);
2610 return Py_None;
2611 }
2612 #endif
2613
2614 #ifdef HAVE_PLOCK
2615
2616 #ifdef HAVE_SYS_LOCK_H
2617 #include <sys/lock.h>
2618 #endif
2619
2620 PyDoc_STRVAR(posix_plock__doc__,
2621 "plock(op)\n\n\
2622 Lock program segments into memory.");
2623
2624 static PyObject *
posix_plock(PyObject * self,PyObject * args)2625 posix_plock(PyObject *self, PyObject *args)
2626 {
2627 int op;
2628 if (!PyArg_ParseTuple(args, "i:plock", &op))
2629 return NULL;
2630 if (plock(op) == -1)
2631 return posix_error();
2632 Py_INCREF(Py_None);
2633 return Py_None;
2634 }
2635 #endif
2636
2637
2638 #ifdef HAVE_POPEN
2639 PyDoc_STRVAR(posix_popen__doc__,
2640 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
2641 Open a pipe to/from a command returning a file object.");
2642
2643 #if defined(PYOS_OS2)
2644 #if defined(PYCC_VACPP)
2645 static int
async_system(const char * command)2646 async_system(const char *command)
2647 {
2648 char errormsg[256], args[1024];
2649 RESULTCODES rcodes;
2650 APIRET rc;
2651
2652 char *shell = getenv("COMSPEC");
2653 if (!shell)
2654 shell = "cmd";
2655
2656 /* avoid overflowing the argument buffer */
2657 if (strlen(shell) + 3 + strlen(command) >= 1024)
2658 return ERROR_NOT_ENOUGH_MEMORY
2659
2660 args[0] = '\0';
2661 strcat(args, shell);
2662 strcat(args, "/c ");
2663 strcat(args, command);
2664
2665 /* execute asynchronously, inheriting the environment */
2666 rc = DosExecPgm(errormsg,
2667 sizeof(errormsg),
2668 EXEC_ASYNC,
2669 args,
2670 NULL,
2671 &rcodes,
2672 shell);
2673 return rc;
2674 }
2675
2676 static FILE *
popen(const char * command,const char * mode,int pipesize,int * err)2677 popen(const char *command, const char *mode, int pipesize, int *err)
2678 {
2679 int oldfd, tgtfd;
2680 HFILE pipeh[2];
2681 APIRET rc;
2682
2683 /* mode determines which of stdin or stdout is reconnected to
2684 * the pipe to the child
2685 */
2686 if (strchr(mode, 'r') != NULL) {
2687 tgt_fd = 1; /* stdout */
2688 } else if (strchr(mode, 'w')) {
2689 tgt_fd = 0; /* stdin */
2690 } else {
2691 *err = ERROR_INVALID_ACCESS;
2692 return NULL;
2693 }
2694
2695 /* setup the pipe */
2696 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
2697 *err = rc;
2698 return NULL;
2699 }
2700
2701 /* prevent other threads accessing stdio */
2702 DosEnterCritSec();
2703
2704 /* reconnect stdio and execute child */
2705 oldfd = dup(tgtfd);
2706 close(tgtfd);
2707 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
2708 DosClose(pipeh[tgtfd]);
2709 rc = async_system(command);
2710 }
2711
2712 /* restore stdio */
2713 dup2(oldfd, tgtfd);
2714 close(oldfd);
2715
2716 /* allow other threads access to stdio */
2717 DosExitCritSec();
2718
2719 /* if execution of child was successful return file stream */
2720 if (rc == NO_ERROR)
2721 return fdopen(pipeh[1 - tgtfd], mode);
2722 else {
2723 DosClose(pipeh[1 - tgtfd]);
2724 *err = rc;
2725 return NULL;
2726 }
2727 }
2728
2729 static PyObject *
posix_popen(PyObject * self,PyObject * args)2730 posix_popen(PyObject *self, PyObject *args)
2731 {
2732 char *name;
2733 char *mode = "r";
2734 int err, bufsize = -1;
2735 FILE *fp;
2736 PyObject *f;
2737 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2738 return NULL;
2739 Py_BEGIN_ALLOW_THREADS
2740 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
2741 Py_END_ALLOW_THREADS
2742 if (fp == NULL)
2743 return os2_error(err);
2744
2745 f = PyFile_FromFile(fp, name, mode, fclose);
2746 if (f != NULL)
2747 PyFile_SetBufSize(f, bufsize);
2748 return f;
2749 }
2750
2751 #elif defined(PYCC_GCC)
2752
2753 /* standard posix version of popen() support */
2754 static PyObject *
posix_popen(PyObject * self,PyObject * args)2755 posix_popen(PyObject *self, PyObject *args)
2756 {
2757 char *name;
2758 char *mode = "r";
2759 int bufsize = -1;
2760 FILE *fp;
2761 PyObject *f;
2762 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2763 return NULL;
2764 Py_BEGIN_ALLOW_THREADS
2765 fp = popen(name, mode);
2766 Py_END_ALLOW_THREADS
2767 if (fp == NULL)
2768 return posix_error();
2769 f = PyFile_FromFile(fp, name, mode, pclose);
2770 if (f != NULL)
2771 PyFile_SetBufSize(f, bufsize);
2772 return f;
2773 }
2774
2775 /* fork() under OS/2 has lots'o'warts
2776 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2777 * most of this code is a ripoff of the win32 code, but using the
2778 * capabilities of EMX's C library routines
2779 */
2780
2781 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2782 #define POPEN_1 1
2783 #define POPEN_2 2
2784 #define POPEN_3 3
2785 #define POPEN_4 4
2786
2787 static PyObject *_PyPopen(char *, int, int, int);
2788 static int _PyPclose(FILE *file);
2789
2790 /*
2791 * Internal dictionary mapping popen* file pointers to process handles,
2792 * for use when retrieving the process exit code. See _PyPclose() below
2793 * for more information on this dictionary's use.
2794 */
2795 static PyObject *_PyPopenProcs = NULL;
2796
2797 /* os2emx version of popen2()
2798 *
2799 * The result of this function is a pipe (file) connected to the
2800 * process's stdin, and a pipe connected to the process's stdout.
2801 */
2802
2803 static PyObject *
os2emx_popen2(PyObject * self,PyObject * args)2804 os2emx_popen2(PyObject *self, PyObject *args)
2805 {
2806 PyObject *f;
2807 int tm=0;
2808
2809 char *cmdstring;
2810 char *mode = "t";
2811 int bufsize = -1;
2812 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2813 return NULL;
2814
2815 if (*mode == 't')
2816 tm = O_TEXT;
2817 else if (*mode != 'b') {
2818 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2819 return NULL;
2820 } else
2821 tm = O_BINARY;
2822
2823 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2824
2825 return f;
2826 }
2827
2828 /*
2829 * Variation on os2emx.popen2
2830 *
2831 * The result of this function is 3 pipes - the process's stdin,
2832 * stdout and stderr
2833 */
2834
2835 static PyObject *
os2emx_popen3(PyObject * self,PyObject * args)2836 os2emx_popen3(PyObject *self, PyObject *args)
2837 {
2838 PyObject *f;
2839 int tm = 0;
2840
2841 char *cmdstring;
2842 char *mode = "t";
2843 int bufsize = -1;
2844 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2845 return NULL;
2846
2847 if (*mode == 't')
2848 tm = O_TEXT;
2849 else if (*mode != 'b') {
2850 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2851 return NULL;
2852 } else
2853 tm = O_BINARY;
2854
2855 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2856
2857 return f;
2858 }
2859
2860 /*
2861 * Variation on os2emx.popen2
2862 *
2863 * The result of this function is 2 pipes - the processes stdin,
2864 * and stdout+stderr combined as a single pipe.
2865 */
2866
2867 static PyObject *
os2emx_popen4(PyObject * self,PyObject * args)2868 os2emx_popen4(PyObject *self, PyObject *args)
2869 {
2870 PyObject *f;
2871 int tm = 0;
2872
2873 char *cmdstring;
2874 char *mode = "t";
2875 int bufsize = -1;
2876 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2877 return NULL;
2878
2879 if (*mode == 't')
2880 tm = O_TEXT;
2881 else if (*mode != 'b') {
2882 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2883 return NULL;
2884 } else
2885 tm = O_BINARY;
2886
2887 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2888
2889 return f;
2890 }
2891
2892 /* a couple of structures for convenient handling of multiple
2893 * file handles and pipes
2894 */
2895 struct file_ref
2896 {
2897 int handle;
2898 int flags;
2899 };
2900
2901 struct pipe_ref
2902 {
2903 int rd;
2904 int wr;
2905 };
2906
2907 /* The following code is derived from the win32 code */
2908
2909 static PyObject *
_PyPopen(char * cmdstring,int mode,int n,int bufsize)2910 _PyPopen(char *cmdstring, int mode, int n, int bufsize)
2911 {
2912 struct file_ref stdio[3];
2913 struct pipe_ref p_fd[3];
2914 FILE *p_s[3];
2915 int file_count, i, pipe_err;
2916 pid_t pipe_pid;
2917 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2918 PyObject *f, *p_f[3];
2919
2920 /* file modes for subsequent fdopen's on pipe handles */
2921 if (mode == O_TEXT)
2922 {
2923 rd_mode = "rt";
2924 wr_mode = "wt";
2925 }
2926 else
2927 {
2928 rd_mode = "rb";
2929 wr_mode = "wb";
2930 }
2931
2932 /* prepare shell references */
2933 if ((shell = getenv("EMXSHELL")) == NULL)
2934 if ((shell = getenv("COMSPEC")) == NULL)
2935 {
2936 errno = ENOENT;
2937 return posix_error();
2938 }
2939
2940 sh_name = _getname(shell);
2941 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2942 opt = "/c";
2943 else
2944 opt = "-c";
2945
2946 /* save current stdio fds + their flags, and set not inheritable */
2947 i = pipe_err = 0;
2948 while (pipe_err >= 0 && i < 3)
2949 {
2950 pipe_err = stdio[i].handle = dup(i);
2951 stdio[i].flags = fcntl(i, F_GETFD, 0);
2952 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2953 i++;
2954 }
2955 if (pipe_err < 0)
2956 {
2957 /* didn't get them all saved - clean up and bail out */
2958 int saved_err = errno;
2959 while (i-- > 0)
2960 {
2961 close(stdio[i].handle);
2962 }
2963 errno = saved_err;
2964 return posix_error();
2965 }
2966
2967 /* create pipe ends */
2968 file_count = 2;
2969 if (n == POPEN_3)
2970 file_count = 3;
2971 i = pipe_err = 0;
2972 while ((pipe_err == 0) && (i < file_count))
2973 pipe_err = pipe((int *)&p_fd[i++]);
2974 if (pipe_err < 0)
2975 {
2976 /* didn't get them all made - clean up and bail out */
2977 while (i-- > 0)
2978 {
2979 close(p_fd[i].wr);
2980 close(p_fd[i].rd);
2981 }
2982 errno = EPIPE;
2983 return posix_error();
2984 }
2985
2986 /* change the actual standard IO streams over temporarily,
2987 * making the retained pipe ends non-inheritable
2988 */
2989 pipe_err = 0;
2990
2991 /* - stdin */
2992 if (dup2(p_fd[0].rd, 0) == 0)
2993 {
2994 close(p_fd[0].rd);
2995 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2996 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2997 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2998 {
2999 close(p_fd[0].wr);
3000 pipe_err = -1;
3001 }
3002 }
3003 else
3004 {
3005 pipe_err = -1;
3006 }
3007
3008 /* - stdout */
3009 if (pipe_err == 0)
3010 {
3011 if (dup2(p_fd[1].wr, 1) == 1)
3012 {
3013 close(p_fd[1].wr);
3014 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3015 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3016 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3017 {
3018 close(p_fd[1].rd);
3019 pipe_err = -1;
3020 }
3021 }
3022 else
3023 {
3024 pipe_err = -1;
3025 }
3026 }
3027
3028 /* - stderr, as required */
3029 if (pipe_err == 0)
3030 switch (n)
3031 {
3032 case POPEN_3:
3033 {
3034 if (dup2(p_fd[2].wr, 2) == 2)
3035 {
3036 close(p_fd[2].wr);
3037 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3038 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3039 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3040 {
3041 close(p_fd[2].rd);
3042 pipe_err = -1;
3043 }
3044 }
3045 else
3046 {
3047 pipe_err = -1;
3048 }
3049 break;
3050 }
3051
3052 case POPEN_4:
3053 {
3054 if (dup2(1, 2) != 2)
3055 {
3056 pipe_err = -1;
3057 }
3058 break;
3059 }
3060 }
3061
3062 /* spawn the child process */
3063 if (pipe_err == 0)
3064 {
3065 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3066 if (pipe_pid == -1)
3067 {
3068 pipe_err = -1;
3069 }
3070 else
3071 {
3072 /* save the PID into the FILE structure
3073 * NOTE: this implementation doesn't actually
3074 * take advantage of this, but do it for
3075 * completeness - AIM Apr01
3076 */
3077 for (i = 0; i < file_count; i++)
3078 p_s[i]->_pid = pipe_pid;
3079 }
3080 }
3081
3082 /* reset standard IO to normal */
3083 for (i = 0; i < 3; i++)
3084 {
3085 dup2(stdio[i].handle, i);
3086 fcntl(i, F_SETFD, stdio[i].flags);
3087 close(stdio[i].handle);
3088 }
3089
3090 /* if any remnant problems, clean up and bail out */
3091 if (pipe_err < 0)
3092 {
3093 for (i = 0; i < 3; i++)
3094 {
3095 close(p_fd[i].rd);
3096 close(p_fd[i].wr);
3097 }
3098 errno = EPIPE;
3099 return posix_error_with_filename(cmdstring);
3100 }
3101
3102 /* build tuple of file objects to return */
3103 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3104 PyFile_SetBufSize(p_f[0], bufsize);
3105 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3106 PyFile_SetBufSize(p_f[1], bufsize);
3107 if (n == POPEN_3)
3108 {
3109 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3110 PyFile_SetBufSize(p_f[0], bufsize);
3111 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
3112 }
3113 else
3114 f = PyTuple_Pack(2, p_f[0], p_f[1]);
3115
3116 /*
3117 * Insert the files we've created into the process dictionary
3118 * all referencing the list with the process handle and the
3119 * initial number of files (see description below in _PyPclose).
3120 * Since if _PyPclose later tried to wait on a process when all
3121 * handles weren't closed, it could create a deadlock with the
3122 * child, we spend some energy here to try to ensure that we
3123 * either insert all file handles into the dictionary or none
3124 * at all. It's a little clumsy with the various popen modes
3125 * and variable number of files involved.
3126 */
3127 if (!_PyPopenProcs)
3128 {
3129 _PyPopenProcs = PyDict_New();
3130 }
3131
3132 if (_PyPopenProcs)
3133 {
3134 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3135 int ins_rc[3];
3136
3137 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3138 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3139
3140 procObj = PyList_New(2);
3141 pidObj = PyLong_FromPid(pipe_pid);
3142 intObj = PyInt_FromLong((long) file_count);
3143
3144 if (procObj && pidObj && intObj)
3145 {
3146 PyList_SetItem(procObj, 0, pidObj);
3147 PyList_SetItem(procObj, 1, intObj);
3148
3149 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3150 if (fileObj[0])
3151 {
3152 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3153 fileObj[0],
3154 procObj);
3155 }
3156 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3157 if (fileObj[1])
3158 {
3159 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3160 fileObj[1],
3161 procObj);
3162 }
3163 if (file_count >= 3)
3164 {
3165 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3166 if (fileObj[2])
3167 {
3168 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3169 fileObj[2],
3170 procObj);
3171 }
3172 }
3173
3174 if (ins_rc[0] < 0 || !fileObj[0] ||
3175 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3176 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3177 {
3178 /* Something failed - remove any dictionary
3179 * entries that did make it.
3180 */
3181 if (!ins_rc[0] && fileObj[0])
3182 {
3183 PyDict_DelItem(_PyPopenProcs,
3184 fileObj[0]);
3185 }
3186 if (!ins_rc[1] && fileObj[1])
3187 {
3188 PyDict_DelItem(_PyPopenProcs,
3189 fileObj[1]);
3190 }
3191 if (!ins_rc[2] && fileObj[2])
3192 {
3193 PyDict_DelItem(_PyPopenProcs,
3194 fileObj[2]);
3195 }
3196 }
3197 }
3198
3199 /*
3200 * Clean up our localized references for the dictionary keys
3201 * and value since PyDict_SetItem will Py_INCREF any copies
3202 * that got placed in the dictionary.
3203 */
3204 Py_XDECREF(procObj);
3205 Py_XDECREF(fileObj[0]);
3206 Py_XDECREF(fileObj[1]);
3207 Py_XDECREF(fileObj[2]);
3208 }
3209
3210 /* Child is launched. */
3211 return f;
3212 }
3213
3214 /*
3215 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3216 * exit code for the child process and return as a result of the close.
3217 *
3218 * This function uses the _PyPopenProcs dictionary in order to map the
3219 * input file pointer to information about the process that was
3220 * originally created by the popen* call that created the file pointer.
3221 * The dictionary uses the file pointer as a key (with one entry
3222 * inserted for each file returned by the original popen* call) and a
3223 * single list object as the value for all files from a single call.
3224 * The list object contains the Win32 process handle at [0], and a file
3225 * count at [1], which is initialized to the total number of file
3226 * handles using that list.
3227 *
3228 * This function closes whichever handle it is passed, and decrements
3229 * the file count in the dictionary for the process handle pointed to
3230 * by this file. On the last close (when the file count reaches zero),
3231 * this function will wait for the child process and then return its
3232 * exit code as the result of the close() operation. This permits the
3233 * files to be closed in any order - it is always the close() of the
3234 * final handle that will return the exit code.
3235 *
3236 * NOTE: This function is currently called with the GIL released.
3237 * hence we use the GILState API to manage our state.
3238 */
3239
_PyPclose(FILE * file)3240 static int _PyPclose(FILE *file)
3241 {
3242 int result;
3243 int exit_code;
3244 pid_t pipe_pid;
3245 PyObject *procObj, *pidObj, *intObj, *fileObj;
3246 int file_count;
3247 #ifdef WITH_THREAD
3248 PyGILState_STATE state;
3249 #endif
3250
3251 /* Close the file handle first, to ensure it can't block the
3252 * child from exiting if it's the last handle.
3253 */
3254 result = fclose(file);
3255
3256 #ifdef WITH_THREAD
3257 state = PyGILState_Ensure();
3258 #endif
3259 if (_PyPopenProcs)
3260 {
3261 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3262 (procObj = PyDict_GetItem(_PyPopenProcs,
3263 fileObj)) != NULL &&
3264 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3265 (intObj = PyList_GetItem(procObj,1)) != NULL)
3266 {
3267 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
3268 file_count = (int) PyInt_AsLong(intObj);
3269
3270 if (file_count > 1)
3271 {
3272 /* Still other files referencing process */
3273 file_count--;
3274 PyList_SetItem(procObj,1,
3275 PyInt_FromLong((long) file_count));
3276 }
3277 else
3278 {
3279 /* Last file for this process */
3280 if (result != EOF &&
3281 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3282 {
3283 /* extract exit status */
3284 if (WIFEXITED(exit_code))
3285 {
3286 result = WEXITSTATUS(exit_code);
3287 }
3288 else
3289 {
3290 errno = EPIPE;
3291 result = -1;
3292 }
3293 }
3294 else
3295 {
3296 /* Indicate failure - this will cause the file object
3297 * to raise an I/O error and translate the last
3298 * error code from errno. We do have a problem with
3299 * last errors that overlap the normal errno table,
3300 * but that's a consistent problem with the file object.
3301 */
3302 result = -1;
3303 }
3304 }
3305
3306 /* Remove this file pointer from dictionary */
3307 PyDict_DelItem(_PyPopenProcs, fileObj);
3308
3309 if (PyDict_Size(_PyPopenProcs) == 0)
3310 {
3311 Py_DECREF(_PyPopenProcs);
3312 _PyPopenProcs = NULL;
3313 }
3314
3315 } /* if object retrieval ok */
3316
3317 Py_XDECREF(fileObj);
3318 } /* if _PyPopenProcs */
3319
3320 #ifdef WITH_THREAD
3321 PyGILState_Release(state);
3322 #endif
3323 return result;
3324 }
3325
3326 #endif /* PYCC_??? */
3327
3328 #elif defined(MS_WINDOWS)
3329
3330 /*
3331 * Portable 'popen' replacement for Win32.
3332 *
3333 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3334 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
3335 * Return code handling by David Bolen <db3l@fitlinxx.com>.
3336 */
3337
3338 #include <malloc.h>
3339 #include <io.h>
3340 #include <fcntl.h>
3341
3342 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3343 #define POPEN_1 1
3344 #define POPEN_2 2
3345 #define POPEN_3 3
3346 #define POPEN_4 4
3347
3348 static PyObject *_PyPopen(char *, int, int);
3349 static int _PyPclose(FILE *file);
3350
3351 /*
3352 * Internal dictionary mapping popen* file pointers to process handles,
3353 * for use when retrieving the process exit code. See _PyPclose() below
3354 * for more information on this dictionary's use.
3355 */
3356 static PyObject *_PyPopenProcs = NULL;
3357
3358
3359 /* popen that works from a GUI.
3360 *
3361 * The result of this function is a pipe (file) connected to the
3362 * processes stdin or stdout, depending on the requested mode.
3363 */
3364
3365 static PyObject *
posix_popen(PyObject * self,PyObject * args)3366 posix_popen(PyObject *self, PyObject *args)
3367 {
3368 PyObject *f;
3369 int tm = 0;
3370
3371 char *cmdstring;
3372 char *mode = "r";
3373 int bufsize = -1;
3374 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
3375 return NULL;
3376
3377 if (*mode == 'r')
3378 tm = _O_RDONLY;
3379 else if (*mode != 'w') {
3380 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
3381 return NULL;
3382 } else
3383 tm = _O_WRONLY;
3384
3385 if (bufsize != -1) {
3386 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
3387 return NULL;
3388 }
3389
3390 if (*(mode+1) == 't')
3391 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3392 else if (*(mode+1) == 'b')
3393 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
3394 else
3395 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3396
3397 return f;
3398 }
3399
3400 /* Variation on win32pipe.popen
3401 *
3402 * The result of this function is a pipe (file) connected to the
3403 * process's stdin, and a pipe connected to the process's stdout.
3404 */
3405
3406 static PyObject *
win32_popen2(PyObject * self,PyObject * args)3407 win32_popen2(PyObject *self, PyObject *args)
3408 {
3409 PyObject *f;
3410 int tm=0;
3411
3412 char *cmdstring;
3413 char *mode = "t";
3414 int bufsize = -1;
3415 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3416 return NULL;
3417
3418 if (*mode == 't')
3419 tm = _O_TEXT;
3420 else if (*mode != 'b') {
3421 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
3422 return NULL;
3423 } else
3424 tm = _O_BINARY;
3425
3426 if (bufsize != -1) {
3427 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
3428 return NULL;
3429 }
3430
3431 f = _PyPopen(cmdstring, tm, POPEN_2);
3432
3433 return f;
3434 }
3435
3436 /*
3437 * Variation on <om win32pipe.popen>
3438 *
3439 * The result of this function is 3 pipes - the process's stdin,
3440 * stdout and stderr
3441 */
3442
3443 static PyObject *
win32_popen3(PyObject * self,PyObject * args)3444 win32_popen3(PyObject *self, PyObject *args)
3445 {
3446 PyObject *f;
3447 int tm = 0;
3448
3449 char *cmdstring;
3450 char *mode = "t";
3451 int bufsize = -1;
3452 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3453 return NULL;
3454
3455 if (*mode == 't')
3456 tm = _O_TEXT;
3457 else if (*mode != 'b') {
3458 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
3459 return NULL;
3460 } else
3461 tm = _O_BINARY;
3462
3463 if (bufsize != -1) {
3464 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
3465 return NULL;
3466 }
3467
3468 f = _PyPopen(cmdstring, tm, POPEN_3);
3469
3470 return f;
3471 }
3472
3473 /*
3474 * Variation on win32pipe.popen
3475 *
3476 * The result of this function is 2 pipes - the processes stdin,
3477 * and stdout+stderr combined as a single pipe.
3478 */
3479
3480 static PyObject *
win32_popen4(PyObject * self,PyObject * args)3481 win32_popen4(PyObject *self, PyObject *args)
3482 {
3483 PyObject *f;
3484 int tm = 0;
3485
3486 char *cmdstring;
3487 char *mode = "t";
3488 int bufsize = -1;
3489 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3490 return NULL;
3491
3492 if (*mode == 't')
3493 tm = _O_TEXT;
3494 else if (*mode != 'b') {
3495 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
3496 return NULL;
3497 } else
3498 tm = _O_BINARY;
3499
3500 if (bufsize != -1) {
3501 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
3502 return NULL;
3503 }
3504
3505 f = _PyPopen(cmdstring, tm, POPEN_4);
3506
3507 return f;
3508 }
3509
3510 static BOOL
_PyPopenCreateProcess(char * cmdstring,HANDLE hStdin,HANDLE hStdout,HANDLE hStderr,HANDLE * hProcess)3511 _PyPopenCreateProcess(char *cmdstring,
3512 HANDLE hStdin,
3513 HANDLE hStdout,
3514 HANDLE hStderr,
3515 HANDLE *hProcess)
3516 {
3517 PROCESS_INFORMATION piProcInfo;
3518 STARTUPINFO siStartInfo;
3519 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
3520 char *s1,*s2, *s3 = " /c ";
3521 const char *szConsoleSpawn = "w9xpopen.exe";
3522 int i;
3523 Py_ssize_t x;
3524
3525 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
3526 char *comshell;
3527
3528 s1 = (char *)alloca(i);
3529 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3530 /* x < i, so x fits into an integer */
3531 return (int)x;
3532
3533 /* Explicitly check if we are using COMMAND.COM. If we are
3534 * then use the w9xpopen hack.
3535 */
3536 comshell = s1 + x;
3537 while (comshell >= s1 && *comshell != '\\')
3538 --comshell;
3539 ++comshell;
3540
3541 if (GetVersion() < 0x80000000 &&
3542 _stricmp(comshell, "command.com") != 0) {
3543 /* NT/2000 and not using command.com. */
3544 x = i + strlen(s3) + strlen(cmdstring) + 1;
3545 s2 = (char *)alloca(x);
3546 ZeroMemory(s2, x);
3547 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
3548 }
3549 else {
3550 /*
3551 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3552 * the workaround listed in KB: Q150956
3553 */
3554 char modulepath[_MAX_PATH];
3555 struct stat statinfo;
3556 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3557 for (x = i = 0; modulepath[i]; i++)
3558 if (modulepath[i] == SEP)
3559 x = i+1;
3560 modulepath[x] = '\0';
3561 /* Create the full-name to w9xpopen, so we can test it exists */
3562 strncat(modulepath,
3563 szConsoleSpawn,
3564 (sizeof(modulepath)/sizeof(modulepath[0]))
3565 -strlen(modulepath));
3566 if (stat(modulepath, &statinfo) != 0) {
3567 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
3568 /* Eeek - file-not-found - possibly an embedding
3569 situation - see if we can locate it in sys.prefix
3570 */
3571 strncpy(modulepath,
3572 Py_GetExecPrefix(),
3573 mplen);
3574 modulepath[mplen-1] = '\0';
3575 if (modulepath[strlen(modulepath)-1] != '\\')
3576 strcat(modulepath, "\\");
3577 strncat(modulepath,
3578 szConsoleSpawn,
3579 mplen-strlen(modulepath));
3580 /* No where else to look - raise an easily identifiable
3581 error, rather than leaving Windows to report
3582 "file not found" - as the user is probably blissfully
3583 unaware this shim EXE is used, and it will confuse them.
3584 (well, it confused me for a while ;-)
3585 */
3586 if (stat(modulepath, &statinfo) != 0) {
3587 PyErr_Format(PyExc_RuntimeError,
3588 "Can not locate '%s' which is needed "
3589 "for popen to work with your shell "
3590 "or platform.",
3591 szConsoleSpawn);
3592 return FALSE;
3593 }
3594 }
3595 x = i + strlen(s3) + strlen(cmdstring) + 1 +
3596 strlen(modulepath) +
3597 strlen(szConsoleSpawn) + 1;
3598
3599 s2 = (char *)alloca(x);
3600 ZeroMemory(s2, x);
3601 /* To maintain correct argument passing semantics,
3602 we pass the command-line as it stands, and allow
3603 quoting to be applied. w9xpopen.exe will then
3604 use its argv vector, and re-quote the necessary
3605 args for the ultimate child process.
3606 */
3607 PyOS_snprintf(
3608 s2, x,
3609 "\"%s\" %s%s%s",
3610 modulepath,
3611 s1,
3612 s3,
3613 cmdstring);
3614 /* Not passing CREATE_NEW_CONSOLE has been known to
3615 cause random failures on win9x. Specifically a
3616 dialog:
3617 "Your program accessed mem currently in use at xxx"
3618 and a hopeful warning about the stability of your
3619 system.
3620 Cost is Ctrl+C won't kill children, but anyone
3621 who cares can have a go!
3622 */
3623 dwProcessFlags |= CREATE_NEW_CONSOLE;
3624 }
3625 }
3626
3627 /* Could be an else here to try cmd.exe / command.com in the path
3628 Now we'll just error out.. */
3629 else {
3630 PyErr_SetString(PyExc_RuntimeError,
3631 "Cannot locate a COMSPEC environment variable to "
3632 "use as the shell");
3633 return FALSE;
3634 }
3635
3636 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3637 siStartInfo.cb = sizeof(STARTUPINFO);
3638 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3639 siStartInfo.hStdInput = hStdin;
3640 siStartInfo.hStdOutput = hStdout;
3641 siStartInfo.hStdError = hStderr;
3642 siStartInfo.wShowWindow = SW_HIDE;
3643
3644 if (CreateProcess(NULL,
3645 s2,
3646 NULL,
3647 NULL,
3648 TRUE,
3649 dwProcessFlags,
3650 NULL,
3651 NULL,
3652 &siStartInfo,
3653 &piProcInfo) ) {
3654 /* Close the handles now so anyone waiting is woken. */
3655 CloseHandle(piProcInfo.hThread);
3656
3657 /* Return process handle */
3658 *hProcess = piProcInfo.hProcess;
3659 return TRUE;
3660 }
3661 win32_error("CreateProcess", s2);
3662 return FALSE;
3663 }
3664
3665 /* The following code is based off of KB: Q190351 */
3666
3667 static PyObject *
_PyPopen(char * cmdstring,int mode,int n)3668 _PyPopen(char *cmdstring, int mode, int n)
3669 {
3670 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3671 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
3672 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
3673
3674 SECURITY_ATTRIBUTES saAttr;
3675 BOOL fSuccess;
3676 int fd1, fd2, fd3;
3677 FILE *f1, *f2, *f3;
3678 long file_count;
3679 PyObject *f;
3680
3681 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3682 saAttr.bInheritHandle = TRUE;
3683 saAttr.lpSecurityDescriptor = NULL;
3684
3685 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3686 return win32_error("CreatePipe", NULL);
3687
3688 /* Create new output read handle and the input write handle. Set
3689 * the inheritance properties to FALSE. Otherwise, the child inherits
3690 * these handles; resulting in non-closeable handles to the pipes
3691 * being created. */
3692 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
3693 GetCurrentProcess(), &hChildStdinWrDup, 0,
3694 FALSE,
3695 DUPLICATE_SAME_ACCESS);
3696 if (!fSuccess)
3697 return win32_error("DuplicateHandle", NULL);
3698
3699 /* Close the inheritable version of ChildStdin
3700 that we're using. */
3701 CloseHandle(hChildStdinWr);
3702
3703 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3704 return win32_error("CreatePipe", NULL);
3705
3706 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
3707 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3708 FALSE, DUPLICATE_SAME_ACCESS);
3709 if (!fSuccess)
3710 return win32_error("DuplicateHandle", NULL);
3711
3712 /* Close the inheritable version of ChildStdout
3713 that we're using. */
3714 CloseHandle(hChildStdoutRd);
3715
3716 if (n != POPEN_4) {
3717 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3718 return win32_error("CreatePipe", NULL);
3719 fSuccess = DuplicateHandle(GetCurrentProcess(),
3720 hChildStderrRd,
3721 GetCurrentProcess(),
3722 &hChildStderrRdDup, 0,
3723 FALSE, DUPLICATE_SAME_ACCESS);
3724 if (!fSuccess)
3725 return win32_error("DuplicateHandle", NULL);
3726 /* Close the inheritable version of ChildStdErr that we're using. */
3727 CloseHandle(hChildStderrRd);
3728 }
3729
3730 switch (n) {
3731 case POPEN_1:
3732 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3733 case _O_WRONLY | _O_TEXT:
3734 /* Case for writing to child Stdin in text mode. */
3735 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
3736 f1 = _fdopen(fd1, "w");
3737 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
3738 PyFile_SetBufSize(f, 0);
3739 /* We don't care about these pipes anymore, so close them. */
3740 CloseHandle(hChildStdoutRdDup);
3741 CloseHandle(hChildStderrRdDup);
3742 break;
3743
3744 case _O_RDONLY | _O_TEXT:
3745 /* Case for reading from child Stdout in text mode. */
3746 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
3747 f1 = _fdopen(fd1, "r");
3748 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
3749 PyFile_SetBufSize(f, 0);
3750 /* We don't care about these pipes anymore, so close them. */
3751 CloseHandle(hChildStdinWrDup);
3752 CloseHandle(hChildStderrRdDup);
3753 break;
3754
3755 case _O_RDONLY | _O_BINARY:
3756 /* Case for readinig from child Stdout in binary mode. */
3757 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
3758 f1 = _fdopen(fd1, "rb");
3759 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
3760 PyFile_SetBufSize(f, 0);
3761 /* We don't care about these pipes anymore, so close them. */
3762 CloseHandle(hChildStdinWrDup);
3763 CloseHandle(hChildStderrRdDup);
3764 break;
3765
3766 case _O_WRONLY | _O_BINARY:
3767 /* Case for writing to child Stdin in binary mode. */
3768 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
3769 f1 = _fdopen(fd1, "wb");
3770 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
3771 PyFile_SetBufSize(f, 0);
3772 /* We don't care about these pipes anymore, so close them. */
3773 CloseHandle(hChildStdoutRdDup);
3774 CloseHandle(hChildStderrRdDup);
3775 break;
3776 }
3777 file_count = 1;
3778 break;
3779
3780 case POPEN_2:
3781 case POPEN_4:
3782 {
3783 char *m1, *m2;
3784 PyObject *p1, *p2;
3785
3786 if (mode & _O_TEXT) {
3787 m1 = "r";
3788 m2 = "w";
3789 } else {
3790 m1 = "rb";
3791 m2 = "wb";
3792 }
3793
3794 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
3795 f1 = _fdopen(fd1, m2);
3796 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
3797 f2 = _fdopen(fd2, m1);
3798 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
3799 PyFile_SetBufSize(p1, 0);
3800 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3801 PyFile_SetBufSize(p2, 0);
3802
3803 if (n != 4)
3804 CloseHandle(hChildStderrRdDup);
3805
3806 f = PyTuple_Pack(2,p1,p2);
3807 Py_XDECREF(p1);
3808 Py_XDECREF(p2);
3809 file_count = 2;
3810 break;
3811 }
3812
3813 case POPEN_3:
3814 {
3815 char *m1, *m2;
3816 PyObject *p1, *p2, *p3;
3817
3818 if (mode & _O_TEXT) {
3819 m1 = "r";
3820 m2 = "w";
3821 } else {
3822 m1 = "rb";
3823 m2 = "wb";
3824 }
3825
3826 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
3827 f1 = _fdopen(fd1, m2);
3828 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
3829 f2 = _fdopen(fd2, m1);
3830 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
3831 f3 = _fdopen(fd3, m1);
3832 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
3833 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3834 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
3835 PyFile_SetBufSize(p1, 0);
3836 PyFile_SetBufSize(p2, 0);
3837 PyFile_SetBufSize(p3, 0);
3838 f = PyTuple_Pack(3,p1,p2,p3);
3839 Py_XDECREF(p1);
3840 Py_XDECREF(p2);
3841 Py_XDECREF(p3);
3842 file_count = 3;
3843 break;
3844 }
3845 }
3846
3847 if (n == POPEN_4) {
3848 if (!_PyPopenCreateProcess(cmdstring,
3849 hChildStdinRd,
3850 hChildStdoutWr,
3851 hChildStdoutWr,
3852 &hProcess))
3853 return NULL;
3854 }
3855 else {
3856 if (!_PyPopenCreateProcess(cmdstring,
3857 hChildStdinRd,
3858 hChildStdoutWr,
3859 hChildStderrWr,
3860 &hProcess))
3861 return NULL;
3862 }
3863
3864 /*
3865 * Insert the files we've created into the process dictionary
3866 * all referencing the list with the process handle and the
3867 * initial number of files (see description below in _PyPclose).
3868 * Since if _PyPclose later tried to wait on a process when all
3869 * handles weren't closed, it could create a deadlock with the
3870 * child, we spend some energy here to try to ensure that we
3871 * either insert all file handles into the dictionary or none
3872 * at all. It's a little clumsy with the various popen modes
3873 * and variable number of files involved.
3874 */
3875 if (!_PyPopenProcs) {
3876 _PyPopenProcs = PyDict_New();
3877 }
3878
3879 if (_PyPopenProcs) {
3880 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3881 int ins_rc[3];
3882
3883 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3884 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3885
3886 procObj = PyList_New(2);
3887 hProcessObj = PyLong_FromVoidPtr(hProcess);
3888 intObj = PyInt_FromLong(file_count);
3889
3890 if (procObj && hProcessObj && intObj) {
3891 PyList_SetItem(procObj,0,hProcessObj);
3892 PyList_SetItem(procObj,1,intObj);
3893
3894 fileObj[0] = PyLong_FromVoidPtr(f1);
3895 if (fileObj[0]) {
3896 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3897 fileObj[0],
3898 procObj);
3899 }
3900 if (file_count >= 2) {
3901 fileObj[1] = PyLong_FromVoidPtr(f2);
3902 if (fileObj[1]) {
3903 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3904 fileObj[1],
3905 procObj);
3906 }
3907 }
3908 if (file_count >= 3) {
3909 fileObj[2] = PyLong_FromVoidPtr(f3);
3910 if (fileObj[2]) {
3911 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3912 fileObj[2],
3913 procObj);
3914 }
3915 }
3916
3917 if (ins_rc[0] < 0 || !fileObj[0] ||
3918 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3919 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3920 /* Something failed - remove any dictionary
3921 * entries that did make it.
3922 */
3923 if (!ins_rc[0] && fileObj[0]) {
3924 PyDict_DelItem(_PyPopenProcs,
3925 fileObj[0]);
3926 }
3927 if (!ins_rc[1] && fileObj[1]) {
3928 PyDict_DelItem(_PyPopenProcs,
3929 fileObj[1]);
3930 }
3931 if (!ins_rc[2] && fileObj[2]) {
3932 PyDict_DelItem(_PyPopenProcs,
3933 fileObj[2]);
3934 }
3935 }
3936 }
3937
3938 /*
3939 * Clean up our localized references for the dictionary keys
3940 * and value since PyDict_SetItem will Py_INCREF any copies
3941 * that got placed in the dictionary.
3942 */
3943 Py_XDECREF(procObj);
3944 Py_XDECREF(fileObj[0]);
3945 Py_XDECREF(fileObj[1]);
3946 Py_XDECREF(fileObj[2]);
3947 }
3948
3949 /* Child is launched. Close the parents copy of those pipe
3950 * handles that only the child should have open. You need to
3951 * make sure that no handles to the write end of the output pipe
3952 * are maintained in this process or else the pipe will not close
3953 * when the child process exits and the ReadFile will hang. */
3954
3955 if (!CloseHandle(hChildStdinRd))
3956 return win32_error("CloseHandle", NULL);
3957
3958 if (!CloseHandle(hChildStdoutWr))
3959 return win32_error("CloseHandle", NULL);
3960
3961 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3962 return win32_error("CloseHandle", NULL);
3963
3964 return f;
3965 }
3966
3967 /*
3968 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3969 * exit code for the child process and return as a result of the close.
3970 *
3971 * This function uses the _PyPopenProcs dictionary in order to map the
3972 * input file pointer to information about the process that was
3973 * originally created by the popen* call that created the file pointer.
3974 * The dictionary uses the file pointer as a key (with one entry
3975 * inserted for each file returned by the original popen* call) and a
3976 * single list object as the value for all files from a single call.
3977 * The list object contains the Win32 process handle at [0], and a file
3978 * count at [1], which is initialized to the total number of file
3979 * handles using that list.
3980 *
3981 * This function closes whichever handle it is passed, and decrements
3982 * the file count in the dictionary for the process handle pointed to
3983 * by this file. On the last close (when the file count reaches zero),
3984 * this function will wait for the child process and then return its
3985 * exit code as the result of the close() operation. This permits the
3986 * files to be closed in any order - it is always the close() of the
3987 * final handle that will return the exit code.
3988 *
3989 * NOTE: This function is currently called with the GIL released.
3990 * hence we use the GILState API to manage our state.
3991 */
3992
_PyPclose(FILE * file)3993 static int _PyPclose(FILE *file)
3994 {
3995 int result;
3996 DWORD exit_code;
3997 HANDLE hProcess;
3998 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3999 long file_count;
4000 #ifdef WITH_THREAD
4001 PyGILState_STATE state;
4002 #endif
4003
4004 /* Close the file handle first, to ensure it can't block the
4005 * child from exiting if it's the last handle.
4006 */
4007 result = fclose(file);
4008 #ifdef WITH_THREAD
4009 state = PyGILState_Ensure();
4010 #endif
4011 if (_PyPopenProcs) {
4012 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4013 (procObj = PyDict_GetItem(_PyPopenProcs,
4014 fileObj)) != NULL &&
4015 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4016 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4017
4018 hProcess = PyLong_AsVoidPtr(hProcessObj);
4019 file_count = PyInt_AsLong(intObj);
4020
4021 if (file_count > 1) {
4022 /* Still other files referencing process */
4023 file_count--;
4024 PyList_SetItem(procObj,1,
4025 PyInt_FromLong(file_count));
4026 } else {
4027 /* Last file for this process */
4028 if (result != EOF &&
4029 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4030 GetExitCodeProcess(hProcess, &exit_code)) {
4031 /* Possible truncation here in 16-bit environments, but
4032 * real exit codes are just the lower byte in any event.
4033 */
4034 result = exit_code;
4035 } else {
4036 /* Indicate failure - this will cause the file object
4037 * to raise an I/O error and translate the last Win32
4038 * error code from errno. We do have a problem with
4039 * last errors that overlap the normal errno table,
4040 * but that's a consistent problem with the file object.
4041 */
4042 if (result != EOF) {
4043 /* If the error wasn't from the fclose(), then
4044 * set errno for the file object error handling.
4045 */
4046 errno = GetLastError();
4047 }
4048 result = -1;
4049 }
4050
4051 /* Free up the native handle at this point */
4052 CloseHandle(hProcess);
4053 }
4054
4055 /* Remove this file pointer from dictionary */
4056 PyDict_DelItem(_PyPopenProcs, fileObj);
4057
4058 if (PyDict_Size(_PyPopenProcs) == 0) {
4059 Py_DECREF(_PyPopenProcs);
4060 _PyPopenProcs = NULL;
4061 }
4062
4063 } /* if object retrieval ok */
4064
4065 Py_XDECREF(fileObj);
4066 } /* if _PyPopenProcs */
4067
4068 #ifdef WITH_THREAD
4069 PyGILState_Release(state);
4070 #endif
4071 return result;
4072 }
4073
4074 #else /* which OS? */
4075 static PyObject *
posix_popen(PyObject * self,PyObject * args)4076 posix_popen(PyObject *self, PyObject *args)
4077 {
4078 char *name;
4079 char *mode = "r";
4080 int bufsize = -1;
4081 FILE *fp;
4082 PyObject *f;
4083 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4084 return NULL;
4085 /* Strip mode of binary or text modifiers */
4086 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4087 mode = "r";
4088 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4089 mode = "w";
4090 Py_BEGIN_ALLOW_THREADS
4091 fp = popen(name, mode);
4092 Py_END_ALLOW_THREADS
4093 if (fp == NULL)
4094 return posix_error();
4095 f = PyFile_FromFile(fp, name, mode, pclose);
4096 if (f != NULL)
4097 PyFile_SetBufSize(f, bufsize);
4098 return f;
4099 }
4100
4101 #endif /* PYOS_??? */
4102 #endif /* HAVE_POPEN */
4103
4104
4105 #ifdef HAVE_SETUID
4106 PyDoc_STRVAR(posix_setuid__doc__,
4107 "setuid(uid)\n\n\
4108 Set the current process's user id.");
4109
4110 static PyObject *
posix_setuid(PyObject * self,PyObject * args)4111 posix_setuid(PyObject *self, PyObject *args)
4112 {
4113 long uid_arg;
4114 uid_t uid;
4115 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
4116 return NULL;
4117 uid = uid_arg;
4118 if (uid != uid_arg) {
4119 PyErr_SetString(PyExc_OverflowError, "user id too big");
4120 return NULL;
4121 }
4122 if (setuid(uid) < 0)
4123 return posix_error();
4124 Py_INCREF(Py_None);
4125 return Py_None;
4126 }
4127 #endif /* HAVE_SETUID */
4128
4129
4130 #ifdef HAVE_SETEUID
4131 PyDoc_STRVAR(posix_seteuid__doc__,
4132 "seteuid(uid)\n\n\
4133 Set the current process's effective user id.");
4134
4135 static PyObject *
posix_seteuid(PyObject * self,PyObject * args)4136 posix_seteuid (PyObject *self, PyObject *args)
4137 {
4138 long euid_arg;
4139 uid_t euid;
4140 if (!PyArg_ParseTuple(args, "l", &euid_arg))
4141 return NULL;
4142 euid = euid_arg;
4143 if (euid != euid_arg) {
4144 PyErr_SetString(PyExc_OverflowError, "user id too big");
4145 return NULL;
4146 }
4147 if (seteuid(euid) < 0) {
4148 return posix_error();
4149 } else {
4150 Py_INCREF(Py_None);
4151 return Py_None;
4152 }
4153 }
4154 #endif /* HAVE_SETEUID */
4155
4156 #ifdef HAVE_SETEGID
4157 PyDoc_STRVAR(posix_setegid__doc__,
4158 "setegid(gid)\n\n\
4159 Set the current process's effective group id.");
4160
4161 static PyObject *
posix_setegid(PyObject * self,PyObject * args)4162 posix_setegid (PyObject *self, PyObject *args)
4163 {
4164 long egid_arg;
4165 gid_t egid;
4166 if (!PyArg_ParseTuple(args, "l", &egid_arg))
4167 return NULL;
4168 egid = egid_arg;
4169 if (egid != egid_arg) {
4170 PyErr_SetString(PyExc_OverflowError, "group id too big");
4171 return NULL;
4172 }
4173 if (setegid(egid) < 0) {
4174 return posix_error();
4175 } else {
4176 Py_INCREF(Py_None);
4177 return Py_None;
4178 }
4179 }
4180 #endif /* HAVE_SETEGID */
4181
4182 #ifdef HAVE_SETREUID
4183 PyDoc_STRVAR(posix_setreuid__doc__,
4184 "setreuid(ruid, euid)\n\n\
4185 Set the current process's real and effective user ids.");
4186
4187 static PyObject *
posix_setreuid(PyObject * self,PyObject * args)4188 posix_setreuid (PyObject *self, PyObject *args)
4189 {
4190 long ruid_arg, euid_arg;
4191 uid_t ruid, euid;
4192 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
4193 return NULL;
4194 if (ruid_arg == -1)
4195 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
4196 else
4197 ruid = ruid_arg; /* otherwise, assign from our long */
4198 if (euid_arg == -1)
4199 euid = (uid_t)-1;
4200 else
4201 euid = euid_arg;
4202 if ((euid_arg != -1 && euid != euid_arg) ||
4203 (ruid_arg != -1 && ruid != ruid_arg)) {
4204 PyErr_SetString(PyExc_OverflowError, "user id too big");
4205 return NULL;
4206 }
4207 if (setreuid(ruid, euid) < 0) {
4208 return posix_error();
4209 } else {
4210 Py_INCREF(Py_None);
4211 return Py_None;
4212 }
4213 }
4214 #endif /* HAVE_SETREUID */
4215
4216 #ifdef HAVE_SETREGID
4217 PyDoc_STRVAR(posix_setregid__doc__,
4218 "setregid(rgid, egid)\n\n\
4219 Set the current process's real and effective group ids.");
4220
4221 static PyObject *
posix_setregid(PyObject * self,PyObject * args)4222 posix_setregid (PyObject *self, PyObject *args)
4223 {
4224 long rgid_arg, egid_arg;
4225 gid_t rgid, egid;
4226 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
4227 return NULL;
4228 if (rgid_arg == -1)
4229 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
4230 else
4231 rgid = rgid_arg; /* otherwise, assign from our long */
4232 if (egid_arg == -1)
4233 egid = (gid_t)-1;
4234 else
4235 egid = egid_arg;
4236 if ((egid_arg != -1 && egid != egid_arg) ||
4237 (rgid_arg != -1 && rgid != rgid_arg)) {
4238 PyErr_SetString(PyExc_OverflowError, "group id too big");
4239 return NULL;
4240 }
4241 if (setregid(rgid, egid) < 0) {
4242 return posix_error();
4243 } else {
4244 Py_INCREF(Py_None);
4245 return Py_None;
4246 }
4247 }
4248 #endif /* HAVE_SETREGID */
4249
4250 #ifdef HAVE_SETGID
4251 PyDoc_STRVAR(posix_setgid__doc__,
4252 "setgid(gid)\n\n\
4253 Set the current process's group id.");
4254
4255 static PyObject *
posix_setgid(PyObject * self,PyObject * args)4256 posix_setgid(PyObject *self, PyObject *args)
4257 {
4258 long gid_arg;
4259 gid_t gid;
4260 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
4261 return NULL;
4262 gid = gid_arg;
4263 if (gid != gid_arg) {
4264 PyErr_SetString(PyExc_OverflowError, "group id too big");
4265 return NULL;
4266 }
4267 if (setgid(gid) < 0)
4268 return posix_error();
4269 Py_INCREF(Py_None);
4270 return Py_None;
4271 }
4272 #endif /* HAVE_SETGID */
4273
4274 #ifdef HAVE_SETGROUPS
4275 PyDoc_STRVAR(posix_setgroups__doc__,
4276 "setgroups(list)\n\n\
4277 Set the groups of the current process to list.");
4278
4279 static PyObject *
posix_setgroups(PyObject * self,PyObject * groups)4280 posix_setgroups(PyObject *self, PyObject *groups)
4281 {
4282 int i, len;
4283 gid_t grouplist[MAX_GROUPS];
4284
4285 if (!PySequence_Check(groups)) {
4286 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4287 return NULL;
4288 }
4289 len = PySequence_Size(groups);
4290 if (len > MAX_GROUPS) {
4291 PyErr_SetString(PyExc_ValueError, "too many groups");
4292 return NULL;
4293 }
4294 for(i = 0; i < len; i++) {
4295 PyObject *elem;
4296 elem = PySequence_GetItem(groups, i);
4297 if (!elem)
4298 return NULL;
4299 if (!PyInt_Check(elem)) {
4300 if (!PyLong_Check(elem)) {
4301 PyErr_SetString(PyExc_TypeError,
4302 "groups must be integers");
4303 Py_DECREF(elem);
4304 return NULL;
4305 } else {
4306 unsigned long x = PyLong_AsUnsignedLong(elem);
4307 if (PyErr_Occurred()) {
4308 PyErr_SetString(PyExc_TypeError,
4309 "group id too big");
4310 Py_DECREF(elem);
4311 return NULL;
4312 }
4313 grouplist[i] = x;
4314 /* read back to see if it fits in gid_t */
4315 if (grouplist[i] != x) {
4316 PyErr_SetString(PyExc_TypeError,
4317 "group id too big");
4318 Py_DECREF(elem);
4319 return NULL;
4320 }
4321 }
4322 } else {
4323 long x = PyInt_AsLong(elem);
4324 grouplist[i] = x;
4325 if (grouplist[i] != x) {
4326 PyErr_SetString(PyExc_TypeError,
4327 "group id too big");
4328 Py_DECREF(elem);
4329 return NULL;
4330 }
4331 }
4332 Py_DECREF(elem);
4333 }
4334
4335 if (setgroups(len, grouplist) < 0)
4336 return posix_error();
4337 Py_INCREF(Py_None);
4338 return Py_None;
4339 }
4340 #endif /* HAVE_SETGROUPS */
4341
4342 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
4343 static PyObject *
wait_helper(pid_t pid,int status,struct rusage * ru)4344 wait_helper(pid_t pid, int status, struct rusage *ru)
4345 {
4346 PyObject *result;
4347 static PyObject *struct_rusage;
4348
4349 if (pid == -1)
4350 return posix_error();
4351
4352 if (struct_rusage == NULL) {
4353 PyObject *m = PyImport_ImportModuleNoBlock("resource");
4354 if (m == NULL)
4355 return NULL;
4356 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
4357 Py_DECREF(m);
4358 if (struct_rusage == NULL)
4359 return NULL;
4360 }
4361
4362 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
4363 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
4364 if (!result)
4365 return NULL;
4366
4367 #ifndef doubletime
4368 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
4369 #endif
4370
4371 PyStructSequence_SET_ITEM(result, 0,
4372 PyFloat_FromDouble(doubletime(ru->ru_utime)));
4373 PyStructSequence_SET_ITEM(result, 1,
4374 PyFloat_FromDouble(doubletime(ru->ru_stime)));
4375 #define SET_INT(result, index, value)\
4376 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
4377 SET_INT(result, 2, ru->ru_maxrss);
4378 SET_INT(result, 3, ru->ru_ixrss);
4379 SET_INT(result, 4, ru->ru_idrss);
4380 SET_INT(result, 5, ru->ru_isrss);
4381 SET_INT(result, 6, ru->ru_minflt);
4382 SET_INT(result, 7, ru->ru_majflt);
4383 SET_INT(result, 8, ru->ru_nswap);
4384 SET_INT(result, 9, ru->ru_inblock);
4385 SET_INT(result, 10, ru->ru_oublock);
4386 SET_INT(result, 11, ru->ru_msgsnd);
4387 SET_INT(result, 12, ru->ru_msgrcv);
4388 SET_INT(result, 13, ru->ru_nsignals);
4389 SET_INT(result, 14, ru->ru_nvcsw);
4390 SET_INT(result, 15, ru->ru_nivcsw);
4391 #undef SET_INT
4392
4393 if (PyErr_Occurred()) {
4394 Py_DECREF(result);
4395 return NULL;
4396 }
4397
4398 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
4399 }
4400 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
4401
4402 #ifdef HAVE_WAIT3
4403 PyDoc_STRVAR(posix_wait3__doc__,
4404 "wait3(options) -> (pid, status, rusage)\n\n\
4405 Wait for completion of a child process.");
4406
4407 static PyObject *
posix_wait3(PyObject * self,PyObject * args)4408 posix_wait3(PyObject *self, PyObject *args)
4409 {
4410 pid_t pid;
4411 int options;
4412 struct rusage ru;
4413 WAIT_TYPE status;
4414 WAIT_STATUS_INT(status) = 0;
4415
4416 if (!PyArg_ParseTuple(args, "i:wait3", &options))
4417 return NULL;
4418
4419 Py_BEGIN_ALLOW_THREADS
4420 pid = wait3(&status, options, &ru);
4421 Py_END_ALLOW_THREADS
4422
4423 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4424 }
4425 #endif /* HAVE_WAIT3 */
4426
4427 #ifdef HAVE_WAIT4
4428 PyDoc_STRVAR(posix_wait4__doc__,
4429 "wait4(pid, options) -> (pid, status, rusage)\n\n\
4430 Wait for completion of a given child process.");
4431
4432 static PyObject *
posix_wait4(PyObject * self,PyObject * args)4433 posix_wait4(PyObject *self, PyObject *args)
4434 {
4435 pid_t pid;
4436 int options;
4437 struct rusage ru;
4438 WAIT_TYPE status;
4439 WAIT_STATUS_INT(status) = 0;
4440
4441 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
4442 return NULL;
4443
4444 Py_BEGIN_ALLOW_THREADS
4445 pid = wait4(pid, &status, options, &ru);
4446 Py_END_ALLOW_THREADS
4447
4448 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
4449 }
4450 #endif /* HAVE_WAIT4 */
4451
4452 #ifdef HAVE_WAITPID
4453 PyDoc_STRVAR(posix_waitpid__doc__,
4454 "waitpid(pid, options) -> (pid, status)\n\n\
4455 Wait for completion of a given child process.");
4456
4457 static PyObject *
posix_waitpid(PyObject * self,PyObject * args)4458 posix_waitpid(PyObject *self, PyObject *args)
4459 {
4460 pid_t pid;
4461 int options;
4462 WAIT_TYPE status;
4463 WAIT_STATUS_INT(status) = 0;
4464
4465 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
4466 return NULL;
4467 Py_BEGIN_ALLOW_THREADS
4468 pid = waitpid(pid, &status, options);
4469 Py_END_ALLOW_THREADS
4470 if (pid == -1)
4471 return posix_error();
4472
4473 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
4474 }
4475
4476 #elif defined(HAVE_CWAIT)
4477
4478 /* MS C has a variant of waitpid() that's usable for most purposes. */
4479 PyDoc_STRVAR(posix_waitpid__doc__,
4480 "waitpid(pid, options) -> (pid, status << 8)\n\n"
4481 "Wait for completion of a given process. options is ignored on Windows.");
4482
4483 static PyObject *
posix_waitpid(PyObject * self,PyObject * args)4484 posix_waitpid(PyObject *self, PyObject *args)
4485 {
4486 Py_intptr_t pid;
4487 int status, options;
4488
4489 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
4490 return NULL;
4491 Py_BEGIN_ALLOW_THREADS
4492 pid = _cwait(&status, pid, options);
4493 Py_END_ALLOW_THREADS
4494 if (pid == -1)
4495 return posix_error();
4496
4497 /* shift the status left a byte so this is more like the POSIX waitpid */
4498 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
4499 }
4500 #endif /* HAVE_WAITPID || HAVE_CWAIT */
4501
4502 #ifdef HAVE_WAIT
4503 PyDoc_STRVAR(posix_wait__doc__,
4504 "wait() -> (pid, status)\n\n\
4505 Wait for completion of a child process.");
4506
4507 static PyObject *
posix_wait(PyObject * self,PyObject * noargs)4508 posix_wait(PyObject *self, PyObject *noargs)
4509 {
4510 pid_t pid;
4511 WAIT_TYPE status;
4512 WAIT_STATUS_INT(status) = 0;
4513
4514 Py_BEGIN_ALLOW_THREADS
4515 pid = wait(&status);
4516 Py_END_ALLOW_THREADS
4517 if (pid == -1)
4518 return posix_error();
4519
4520 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
4521 }
4522 #endif
4523
4524
4525 PyDoc_STRVAR(posix_lstat__doc__,
4526 "lstat(path) -> stat result\n\n\
4527 Like stat(path), but do not follow symbolic links.");
4528
4529 static PyObject *
posix_lstat(PyObject * self,PyObject * args)4530 posix_lstat(PyObject *self, PyObject *args)
4531 {
4532 #ifdef HAVE_LSTAT
4533 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
4534 #else /* !HAVE_LSTAT */
4535 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4536 #endif /* !HAVE_LSTAT */
4537 }
4538
4539
4540 #ifdef HAVE_READLINK
4541 PyDoc_STRVAR(posix_readlink__doc__,
4542 "readlink(path) -> path\n\n\
4543 Return a string representing the path to which the symbolic link points.");
4544
4545 static PyObject *
posix_readlink(PyObject * self,PyObject * args)4546 posix_readlink(PyObject *self, PyObject *args)
4547 {
4548 PyObject* v;
4549 char buf[MAXPATHLEN];
4550 char *path;
4551 int n;
4552 #ifdef Py_USING_UNICODE
4553 int arg_is_unicode = 0;
4554 #endif
4555
4556 if (!PyArg_ParseTuple(args, "et:readlink",
4557 Py_FileSystemDefaultEncoding, &path))
4558 return NULL;
4559 #ifdef Py_USING_UNICODE
4560 v = PySequence_GetItem(args, 0);
4561 if (v == NULL) {
4562 PyMem_Free(path);
4563 return NULL;
4564 }
4565
4566 if (PyUnicode_Check(v)) {
4567 arg_is_unicode = 1;
4568 }
4569 Py_DECREF(v);
4570 #endif
4571
4572 Py_BEGIN_ALLOW_THREADS
4573 n = readlink(path, buf, (int) sizeof buf);
4574 Py_END_ALLOW_THREADS
4575 if (n < 0)
4576 return posix_error_with_allocated_filename(path);
4577
4578 PyMem_Free(path);
4579 v = PyString_FromStringAndSize(buf, n);
4580 #ifdef Py_USING_UNICODE
4581 if (arg_is_unicode) {
4582 PyObject *w;
4583
4584 w = PyUnicode_FromEncodedObject(v,
4585 Py_FileSystemDefaultEncoding,
4586 "strict");
4587 if (w != NULL) {
4588 Py_DECREF(v);
4589 v = w;
4590 }
4591 else {
4592 /* fall back to the original byte string, as
4593 discussed in patch #683592 */
4594 PyErr_Clear();
4595 }
4596 }
4597 #endif
4598 return v;
4599 }
4600 #endif /* HAVE_READLINK */
4601
4602
4603 #ifdef HAVE_SYMLINK
4604 PyDoc_STRVAR(posix_symlink__doc__,
4605 "symlink(src, dst)\n\n\
4606 Create a symbolic link pointing to src named dst.");
4607
4608 static PyObject *
posix_symlink(PyObject * self,PyObject * args)4609 posix_symlink(PyObject *self, PyObject *args)
4610 {
4611 return posix_2str(args, "etet:symlink", symlink);
4612 }
4613 #endif /* HAVE_SYMLINK */
4614
4615
4616 #ifdef HAVE_TIMES
4617 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
4618 static long
system_uptime(void)4619 system_uptime(void)
4620 {
4621 ULONG value = 0;
4622
4623 Py_BEGIN_ALLOW_THREADS
4624 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4625 Py_END_ALLOW_THREADS
4626
4627 return value;
4628 }
4629
4630 static PyObject *
posix_times(PyObject * self,PyObject * noargs)4631 posix_times(PyObject *self, PyObject *noargs)
4632 {
4633 /* Currently Only Uptime is Provided -- Others Later */
4634 return Py_BuildValue("ddddd",
4635 (double)0 /* t.tms_utime / HZ */,
4636 (double)0 /* t.tms_stime / HZ */,
4637 (double)0 /* t.tms_cutime / HZ */,
4638 (double)0 /* t.tms_cstime / HZ */,
4639 (double)system_uptime() / 1000);
4640 }
4641 #else /* not OS2 */
4642 #define NEED_TICKS_PER_SECOND
4643 static long ticks_per_second = -1;
4644 static PyObject *
posix_times(PyObject * self,PyObject * noargs)4645 posix_times(PyObject *self, PyObject *noargs)
4646 {
4647 struct tms t;
4648 clock_t c;
4649 errno = 0;
4650 c = times(&t);
4651 if (c == (clock_t) -1)
4652 return posix_error();
4653 return Py_BuildValue("ddddd",
4654 (double)t.tms_utime / ticks_per_second,
4655 (double)t.tms_stime / ticks_per_second,
4656 (double)t.tms_cutime / ticks_per_second,
4657 (double)t.tms_cstime / ticks_per_second,
4658 (double)c / ticks_per_second);
4659 }
4660 #endif /* not OS2 */
4661 #endif /* HAVE_TIMES */
4662
4663
4664 #ifdef HAVE_TIMES
4665 PyDoc_STRVAR(posix_times__doc__,
4666 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
4667 Return a tuple of floating point numbers indicating process times.");
4668 #endif
4669
4670
4671 #ifdef HAVE_GETSID
4672 PyDoc_STRVAR(posix_getsid__doc__,
4673 "getsid(pid) -> sid\n\n\
4674 Call the system call getsid().");
4675
4676 static PyObject *
posix_getsid(PyObject * self,PyObject * args)4677 posix_getsid(PyObject *self, PyObject *args)
4678 {
4679 pid_t pid;
4680 int sid;
4681 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
4682 return NULL;
4683 sid = getsid(pid);
4684 if (sid < 0)
4685 return posix_error();
4686 return PyInt_FromLong((long)sid);
4687 }
4688 #endif /* HAVE_GETSID */
4689
4690
4691 #ifdef HAVE_SETSID
4692 PyDoc_STRVAR(posix_setsid__doc__,
4693 "setsid()\n\n\
4694 Call the system call setsid().");
4695
4696 static PyObject *
posix_setsid(PyObject * self,PyObject * noargs)4697 posix_setsid(PyObject *self, PyObject *noargs)
4698 {
4699 if (setsid() < 0)
4700 return posix_error();
4701 Py_INCREF(Py_None);
4702 return Py_None;
4703 }
4704 #endif /* HAVE_SETSID */
4705
4706 #ifdef HAVE_SETPGID
4707 PyDoc_STRVAR(posix_setpgid__doc__,
4708 "setpgid(pid, pgrp)\n\n\
4709 Call the system call setpgid().");
4710
4711 static PyObject *
posix_setpgid(PyObject * self,PyObject * args)4712 posix_setpgid(PyObject *self, PyObject *args)
4713 {
4714 pid_t pid;
4715 int pgrp;
4716 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
4717 return NULL;
4718 if (setpgid(pid, pgrp) < 0)
4719 return posix_error();
4720 Py_INCREF(Py_None);
4721 return Py_None;
4722 }
4723 #endif /* HAVE_SETPGID */
4724
4725
4726 #ifdef HAVE_TCGETPGRP
4727 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
4728 "tcgetpgrp(fd) -> pgid\n\n\
4729 Return the process group associated with the terminal given by a fd.");
4730
4731 static PyObject *
posix_tcgetpgrp(PyObject * self,PyObject * args)4732 posix_tcgetpgrp(PyObject *self, PyObject *args)
4733 {
4734 int fd;
4735 pid_t pgid;
4736 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
4737 return NULL;
4738 pgid = tcgetpgrp(fd);
4739 if (pgid < 0)
4740 return posix_error();
4741 return PyLong_FromPid(pgid);
4742 }
4743 #endif /* HAVE_TCGETPGRP */
4744
4745
4746 #ifdef HAVE_TCSETPGRP
4747 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
4748 "tcsetpgrp(fd, pgid)\n\n\
4749 Set the process group associated with the terminal given by a fd.");
4750
4751 static PyObject *
posix_tcsetpgrp(PyObject * self,PyObject * args)4752 posix_tcsetpgrp(PyObject *self, PyObject *args)
4753 {
4754 int fd;
4755 pid_t pgid;
4756 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
4757 return NULL;
4758 if (tcsetpgrp(fd, pgid) < 0)
4759 return posix_error();
4760 Py_INCREF(Py_None);
4761 return Py_None;
4762 }
4763 #endif /* HAVE_TCSETPGRP */
4764
4765 /* Functions acting on file descriptors */
4766
4767 PyDoc_STRVAR(posix_open__doc__,
4768 "open(filename, flag [, mode=0777]) -> fd\n\n\
4769 Open a file (for low level IO).");
4770
4771 static PyObject *
posix_open(PyObject * self,PyObject * args)4772 posix_open(PyObject *self, PyObject *args)
4773 {
4774 char *file = NULL;
4775 int flag;
4776 int mode = 0777;
4777 int fd;
4778
4779 if (!PyArg_ParseTuple(args, "eti|i",
4780 Py_FileSystemDefaultEncoding, &file,
4781 &flag, &mode))
4782 return NULL;
4783
4784 Py_BEGIN_ALLOW_THREADS
4785 fd = open(file, flag, mode);
4786 Py_END_ALLOW_THREADS
4787 if (fd < 0)
4788 return posix_error_with_allocated_filename(file);
4789 PyMem_Free(file);
4790 return PyInt_FromLong((long)fd);
4791 }
4792
4793
4794 PyDoc_STRVAR(posix_close__doc__,
4795 "close(fd)\n\n\
4796 Close a file descriptor (for low level IO).");
4797
4798 static PyObject *
posix_close(PyObject * self,PyObject * args)4799 posix_close(PyObject *self, PyObject *args)
4800 {
4801 int fd, res;
4802 if (!PyArg_ParseTuple(args, "i:close", &fd))
4803 return NULL;
4804 if (!_PyVerify_fd(fd))
4805 return posix_error();
4806 Py_BEGIN_ALLOW_THREADS
4807 res = close(fd);
4808 Py_END_ALLOW_THREADS
4809 if (res < 0)
4810 return posix_error();
4811 Py_INCREF(Py_None);
4812 return Py_None;
4813 }
4814
4815
4816 PyDoc_STRVAR(posix_closerange__doc__,
4817 "closerange(fd_low, fd_high)\n\n\
4818 Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
4819
4820 static PyObject *
posix_closerange(PyObject * self,PyObject * args)4821 posix_closerange(PyObject *self, PyObject *args)
4822 {
4823 int fd_from, fd_to, i;
4824 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
4825 return NULL;
4826 Py_BEGIN_ALLOW_THREADS
4827 for (i = fd_from; i < fd_to; i++)
4828 if (_PyVerify_fd(i))
4829 close(i);
4830 Py_END_ALLOW_THREADS
4831 Py_RETURN_NONE;
4832 }
4833
4834
4835 PyDoc_STRVAR(posix_dup__doc__,
4836 "dup(fd) -> fd2\n\n\
4837 Return a duplicate of a file descriptor.");
4838
4839 static PyObject *
posix_dup(PyObject * self,PyObject * args)4840 posix_dup(PyObject *self, PyObject *args)
4841 {
4842 int fd;
4843 if (!PyArg_ParseTuple(args, "i:dup", &fd))
4844 return NULL;
4845 if (!_PyVerify_fd(fd))
4846 return posix_error();
4847 Py_BEGIN_ALLOW_THREADS
4848 fd = dup(fd);
4849 Py_END_ALLOW_THREADS
4850 if (fd < 0)
4851 return posix_error();
4852 return PyInt_FromLong((long)fd);
4853 }
4854
4855
4856 PyDoc_STRVAR(posix_dup2__doc__,
4857 "dup2(old_fd, new_fd)\n\n\
4858 Duplicate file descriptor.");
4859
4860 static PyObject *
posix_dup2(PyObject * self,PyObject * args)4861 posix_dup2(PyObject *self, PyObject *args)
4862 {
4863 int fd, fd2, res;
4864 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
4865 return NULL;
4866 if (!_PyVerify_fd_dup2(fd, fd2))
4867 return posix_error();
4868 Py_BEGIN_ALLOW_THREADS
4869 res = dup2(fd, fd2);
4870 Py_END_ALLOW_THREADS
4871 if (res < 0)
4872 return posix_error();
4873 Py_INCREF(Py_None);
4874 return Py_None;
4875 }
4876
4877
4878 PyDoc_STRVAR(posix_lseek__doc__,
4879 "lseek(fd, pos, how) -> newpos\n\n\
4880 Set the current position of a file descriptor.");
4881
4882 static PyObject *
posix_lseek(PyObject * self,PyObject * args)4883 posix_lseek(PyObject *self, PyObject *args)
4884 {
4885 int fd, how;
4886 off_t pos, res;
4887 PyObject *posobj;
4888 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
4889 return NULL;
4890 #ifdef SEEK_SET
4891 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4892 switch (how) {
4893 case 0: how = SEEK_SET; break;
4894 case 1: how = SEEK_CUR; break;
4895 case 2: how = SEEK_END; break;
4896 }
4897 #endif /* SEEK_END */
4898
4899 #if !defined(HAVE_LARGEFILE_SUPPORT)
4900 pos = PyInt_AsLong(posobj);
4901 #else
4902 pos = PyLong_Check(posobj) ?
4903 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4904 #endif
4905 if (PyErr_Occurred())
4906 return NULL;
4907
4908 if (!_PyVerify_fd(fd))
4909 return posix_error();
4910 Py_BEGIN_ALLOW_THREADS
4911 res = lseek(fd, pos, how);
4912 Py_END_ALLOW_THREADS
4913 if (res < 0)
4914 return posix_error();
4915
4916 #if !defined(HAVE_LARGEFILE_SUPPORT)
4917 return PyInt_FromLong(res);
4918 #else
4919 return PyLong_FromLongLong(res);
4920 #endif
4921 }
4922
4923
4924 PyDoc_STRVAR(posix_read__doc__,
4925 "read(fd, buffersize) -> string\n\n\
4926 Read a file descriptor.");
4927
4928 static PyObject *
posix_read(PyObject * self,PyObject * args)4929 posix_read(PyObject *self, PyObject *args)
4930 {
4931 int fd, size, n;
4932 PyObject *buffer;
4933 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
4934 return NULL;
4935 if (size < 0) {
4936 errno = EINVAL;
4937 return posix_error();
4938 }
4939 buffer = PyString_FromStringAndSize((char *)NULL, size);
4940 if (buffer == NULL)
4941 return NULL;
4942 if (!_PyVerify_fd(fd)) {
4943 Py_DECREF(buffer);
4944 return posix_error();
4945 }
4946 Py_BEGIN_ALLOW_THREADS
4947 n = read(fd, PyString_AsString(buffer), size);
4948 Py_END_ALLOW_THREADS
4949 if (n < 0) {
4950 Py_DECREF(buffer);
4951 return posix_error();
4952 }
4953 if (n != size)
4954 _PyString_Resize(&buffer, n);
4955 return buffer;
4956 }
4957
4958
4959 PyDoc_STRVAR(posix_write__doc__,
4960 "write(fd, string) -> byteswritten\n\n\
4961 Write a string to a file descriptor.");
4962
4963 static PyObject *
posix_write(PyObject * self,PyObject * args)4964 posix_write(PyObject *self, PyObject *args)
4965 {
4966 Py_buffer pbuf;
4967 int fd;
4968 Py_ssize_t size;
4969
4970 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
4971 return NULL;
4972 if (!_PyVerify_fd(fd)) {
4973 PyBuffer_Release(&pbuf);
4974 return posix_error();
4975 }
4976 Py_BEGIN_ALLOW_THREADS
4977 size = write(fd, pbuf.buf, (size_t)pbuf.len);
4978 Py_END_ALLOW_THREADS
4979 PyBuffer_Release(&pbuf);
4980 if (size < 0)
4981 return posix_error();
4982 return PyInt_FromSsize_t(size);
4983 }
4984
4985
4986 PyDoc_STRVAR(posix_fstat__doc__,
4987 "fstat(fd) -> stat result\n\n\
4988 Like stat(), but for an open file descriptor.");
4989
4990 static PyObject *
posix_fstat(PyObject * self,PyObject * args)4991 posix_fstat(PyObject *self, PyObject *args)
4992 {
4993 int fd;
4994 STRUCT_STAT st;
4995 int res;
4996 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
4997 return NULL;
4998 if (!_PyVerify_fd(fd))
4999 return posix_error();
5000 Py_BEGIN_ALLOW_THREADS
5001 res = FSTAT(fd, &st);
5002 Py_END_ALLOW_THREADS
5003 if (res != 0) {
5004 return posix_error();
5005 }
5006
5007 return _pystat_fromstructstat(&st);
5008 }
5009
5010
5011 PyDoc_STRVAR(posix_fdopen__doc__,
5012 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
5013 Return an open file object connected to a file descriptor.");
5014
5015 static PyObject *
posix_fdopen(PyObject * self,PyObject * args)5016 posix_fdopen(PyObject *self, PyObject *args)
5017 {
5018 int fd;
5019 char *orgmode = "r";
5020 int bufsize = -1;
5021 FILE *fp;
5022 PyObject *f;
5023 char *mode;
5024 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
5025 return NULL;
5026
5027 /* Sanitize mode. See fileobject.c */
5028 mode = PyMem_MALLOC(strlen(orgmode)+3);
5029 if (!mode) {
5030 PyErr_NoMemory();
5031 return NULL;
5032 }
5033 strcpy(mode, orgmode);
5034 if (_PyFile_SanitizeMode(mode)) {
5035 PyMem_FREE(mode);
5036 return NULL;
5037 }
5038 if (!_PyVerify_fd(fd))
5039 return posix_error();
5040 Py_BEGIN_ALLOW_THREADS
5041 #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
5042 if (mode[0] == 'a') {
5043 /* try to make sure the O_APPEND flag is set */
5044 int flags;
5045 flags = fcntl(fd, F_GETFL);
5046 if (flags != -1)
5047 fcntl(fd, F_SETFL, flags | O_APPEND);
5048 fp = fdopen(fd, mode);
5049 if (fp == NULL && flags != -1)
5050 /* restore old mode if fdopen failed */
5051 fcntl(fd, F_SETFL, flags);
5052 } else {
5053 fp = fdopen(fd, mode);
5054 }
5055 #else
5056 fp = fdopen(fd, mode);
5057 #endif
5058 Py_END_ALLOW_THREADS
5059 PyMem_FREE(mode);
5060 if (fp == NULL)
5061 return posix_error();
5062 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
5063 if (f != NULL)
5064 PyFile_SetBufSize(f, bufsize);
5065 return f;
5066 }
5067
5068 PyDoc_STRVAR(posix_isatty__doc__,
5069 "isatty(fd) -> bool\n\n\
5070 Return True if the file descriptor 'fd' is an open file descriptor\n\
5071 connected to the slave end of a terminal.");
5072
5073 static PyObject *
posix_isatty(PyObject * self,PyObject * args)5074 posix_isatty(PyObject *self, PyObject *args)
5075 {
5076 int fd;
5077 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5078 return NULL;
5079 if (!_PyVerify_fd(fd))
5080 return PyBool_FromLong(0);
5081 return PyBool_FromLong(isatty(fd));
5082 }
5083
5084 #ifdef HAVE_PIPE
5085 PyDoc_STRVAR(posix_pipe__doc__,
5086 "pipe() -> (read_end, write_end)\n\n\
5087 Create a pipe.");
5088
5089 static PyObject *
posix_pipe(PyObject * self,PyObject * noargs)5090 posix_pipe(PyObject *self, PyObject *noargs)
5091 {
5092 #if defined(PYOS_OS2)
5093 HFILE read, write;
5094 APIRET rc;
5095
5096 Py_BEGIN_ALLOW_THREADS
5097 rc = DosCreatePipe( &read, &write, 4096);
5098 Py_END_ALLOW_THREADS
5099 if (rc != NO_ERROR)
5100 return os2_error(rc);
5101
5102 return Py_BuildValue("(ii)", read, write);
5103 #else
5104 #if !defined(MS_WINDOWS)
5105 int fds[2];
5106 int res;
5107 Py_BEGIN_ALLOW_THREADS
5108 res = pipe(fds);
5109 Py_END_ALLOW_THREADS
5110 if (res != 0)
5111 return posix_error();
5112 return Py_BuildValue("(ii)", fds[0], fds[1]);
5113 #else /* MS_WINDOWS */
5114 HANDLE read, write;
5115 int read_fd, write_fd;
5116 BOOL ok;
5117 Py_BEGIN_ALLOW_THREADS
5118 ok = CreatePipe(&read, &write, NULL, 0);
5119 Py_END_ALLOW_THREADS
5120 if (!ok)
5121 return win32_error("CreatePipe", NULL);
5122 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5123 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5124 return Py_BuildValue("(ii)", read_fd, write_fd);
5125 #endif /* MS_WINDOWS */
5126 #endif
5127 }
5128 #endif /* HAVE_PIPE */
5129
5130
5131 #ifdef HAVE_MKFIFO
5132 PyDoc_STRVAR(posix_mkfifo__doc__,
5133 "mkfifo(filename [, mode=0666])\n\n\
5134 Create a FIFO (a POSIX named pipe).");
5135
5136 static PyObject *
posix_mkfifo(PyObject * self,PyObject * args)5137 posix_mkfifo(PyObject *self, PyObject *args)
5138 {
5139 char *filename;
5140 int mode = 0666;
5141 int res;
5142 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
5143 return NULL;
5144 Py_BEGIN_ALLOW_THREADS
5145 res = mkfifo(filename, mode);
5146 Py_END_ALLOW_THREADS
5147 if (res < 0)
5148 return posix_error();
5149 Py_INCREF(Py_None);
5150 return Py_None;
5151 }
5152 #endif
5153
5154
5155 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
5156 PyDoc_STRVAR(posix_mknod__doc__,
5157 "mknod(filename [, mode=0600, device])\n\n\
5158 Create a filesystem node (file, device special file or named pipe)\n\
5159 named filename. mode specifies both the permissions to use and the\n\
5160 type of node to be created, being combined (bitwise OR) with one of\n\
5161 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
5162 device defines the newly created device special file (probably using\n\
5163 os.makedev()), otherwise it is ignored.");
5164
5165
5166 static PyObject *
posix_mknod(PyObject * self,PyObject * args)5167 posix_mknod(PyObject *self, PyObject *args)
5168 {
5169 char *filename;
5170 int mode = 0600;
5171 int device = 0;
5172 int res;
5173 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
5174 return NULL;
5175 Py_BEGIN_ALLOW_THREADS
5176 res = mknod(filename, mode, device);
5177 Py_END_ALLOW_THREADS
5178 if (res < 0)
5179 return posix_error();
5180 Py_INCREF(Py_None);
5181 return Py_None;
5182 }
5183 #endif
5184
5185 #ifdef HAVE_DEVICE_MACROS
5186 PyDoc_STRVAR(posix_major__doc__,
5187 "major(device) -> major number\n\
5188 Extracts a device major number from a raw device number.");
5189
5190 static PyObject *
posix_major(PyObject * self,PyObject * args)5191 posix_major(PyObject *self, PyObject *args)
5192 {
5193 int device;
5194 if (!PyArg_ParseTuple(args, "i:major", &device))
5195 return NULL;
5196 return PyInt_FromLong((long)major(device));
5197 }
5198
5199 PyDoc_STRVAR(posix_minor__doc__,
5200 "minor(device) -> minor number\n\
5201 Extracts a device minor number from a raw device number.");
5202
5203 static PyObject *
posix_minor(PyObject * self,PyObject * args)5204 posix_minor(PyObject *self, PyObject *args)
5205 {
5206 int device;
5207 if (!PyArg_ParseTuple(args, "i:minor", &device))
5208 return NULL;
5209 return PyInt_FromLong((long)minor(device));
5210 }
5211
5212 PyDoc_STRVAR(posix_makedev__doc__,
5213 "makedev(major, minor) -> device number\n\
5214 Composes a raw device number from the major and minor device numbers.");
5215
5216 static PyObject *
posix_makedev(PyObject * self,PyObject * args)5217 posix_makedev(PyObject *self, PyObject *args)
5218 {
5219 int major, minor;
5220 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5221 return NULL;
5222 return PyInt_FromLong((long)makedev(major, minor));
5223 }
5224 #endif /* device macros */
5225
5226
5227 #ifdef HAVE_FTRUNCATE
5228 PyDoc_STRVAR(posix_ftruncate__doc__,
5229 "ftruncate(fd, length)\n\n\
5230 Truncate a file to a specified length.");
5231
5232 static PyObject *
posix_ftruncate(PyObject * self,PyObject * args)5233 posix_ftruncate(PyObject *self, PyObject *args)
5234 {
5235 int fd;
5236 off_t length;
5237 int res;
5238 PyObject *lenobj;
5239
5240 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5241 return NULL;
5242
5243 #if !defined(HAVE_LARGEFILE_SUPPORT)
5244 length = PyInt_AsLong(lenobj);
5245 #else
5246 length = PyLong_Check(lenobj) ?
5247 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5248 #endif
5249 if (PyErr_Occurred())
5250 return NULL;
5251
5252 Py_BEGIN_ALLOW_THREADS
5253 res = ftruncate(fd, length);
5254 Py_END_ALLOW_THREADS
5255 if (res < 0)
5256 return posix_error();
5257 Py_INCREF(Py_None);
5258 return Py_None;
5259 }
5260 #endif
5261
5262 #ifdef HAVE_PUTENV
5263 PyDoc_STRVAR(posix_putenv__doc__,
5264 "putenv(key, value)\n\n\
5265 Change or add an environment variable.");
5266
5267 /* Save putenv() parameters as values here, so we can collect them when they
5268 * get re-set with another call for the same key. */
5269 static PyObject *posix_putenv_garbage;
5270
5271 static PyObject *
posix_putenv(PyObject * self,PyObject * args)5272 posix_putenv(PyObject *self, PyObject *args)
5273 {
5274 char *s1, *s2;
5275 char *newenv;
5276 PyObject *newstr;
5277 size_t len;
5278
5279 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
5280 return NULL;
5281
5282 #if defined(PYOS_OS2)
5283 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5284 APIRET rc;
5285
5286 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5287 if (rc != NO_ERROR)
5288 return os2_error(rc);
5289
5290 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5291 APIRET rc;
5292
5293 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5294 if (rc != NO_ERROR)
5295 return os2_error(rc);
5296 } else {
5297 #endif
5298
5299 /* XXX This can leak memory -- not easy to fix :-( */
5300 len = strlen(s1) + strlen(s2) + 2;
5301 /* len includes space for a trailing \0; the size arg to
5302 PyString_FromStringAndSize does not count that */
5303 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
5304 if (newstr == NULL)
5305 return PyErr_NoMemory();
5306 newenv = PyString_AS_STRING(newstr);
5307 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
5308 if (putenv(newenv)) {
5309 Py_DECREF(newstr);
5310 posix_error();
5311 return NULL;
5312 }
5313 /* Install the first arg and newstr in posix_putenv_garbage;
5314 * this will cause previous value to be collected. This has to
5315 * happen after the real putenv() call because the old value
5316 * was still accessible until then. */
5317 if (PyDict_SetItem(posix_putenv_garbage,
5318 PyTuple_GET_ITEM(args, 0), newstr)) {
5319 /* really not much we can do; just leak */
5320 PyErr_Clear();
5321 }
5322 else {
5323 Py_DECREF(newstr);
5324 }
5325
5326 #if defined(PYOS_OS2)
5327 }
5328 #endif
5329 Py_INCREF(Py_None);
5330 return Py_None;
5331 }
5332 #endif /* putenv */
5333
5334 #ifdef HAVE_UNSETENV
5335 PyDoc_STRVAR(posix_unsetenv__doc__,
5336 "unsetenv(key)\n\n\
5337 Delete an environment variable.");
5338
5339 static PyObject *
posix_unsetenv(PyObject * self,PyObject * args)5340 posix_unsetenv(PyObject *self, PyObject *args)
5341 {
5342 char *s1;
5343
5344 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5345 return NULL;
5346
5347 unsetenv(s1);
5348
5349 /* Remove the key from posix_putenv_garbage;
5350 * this will cause it to be collected. This has to
5351 * happen after the real unsetenv() call because the
5352 * old value was still accessible until then.
5353 */
5354 if (PyDict_DelItem(posix_putenv_garbage,
5355 PyTuple_GET_ITEM(args, 0))) {
5356 /* really not much we can do; just leak */
5357 PyErr_Clear();
5358 }
5359
5360 Py_INCREF(Py_None);
5361 return Py_None;
5362 }
5363 #endif /* unsetenv */
5364
5365 PyDoc_STRVAR(posix_strerror__doc__,
5366 "strerror(code) -> string\n\n\
5367 Translate an error code to a message string.");
5368
5369 static PyObject *
posix_strerror(PyObject * self,PyObject * args)5370 posix_strerror(PyObject *self, PyObject *args)
5371 {
5372 int code;
5373 char *message;
5374 if (!PyArg_ParseTuple(args, "i:strerror", &code))
5375 return NULL;
5376 message = strerror(code);
5377 if (message == NULL) {
5378 PyErr_SetString(PyExc_ValueError,
5379 "strerror() argument out of range");
5380 return NULL;
5381 }
5382 return PyString_FromString(message);
5383 }
5384
5385
5386 #ifdef HAVE_SYS_WAIT_H
5387
5388 #ifdef WCOREDUMP
5389 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
5390 "WCOREDUMP(status) -> bool\n\n\
5391 Return True if the process returning 'status' was dumped to a core file.");
5392
5393 static PyObject *
posix_WCOREDUMP(PyObject * self,PyObject * args)5394 posix_WCOREDUMP(PyObject *self, PyObject *args)
5395 {
5396 WAIT_TYPE status;
5397 WAIT_STATUS_INT(status) = 0;
5398
5399 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
5400 return NULL;
5401
5402 return PyBool_FromLong(WCOREDUMP(status));
5403 }
5404 #endif /* WCOREDUMP */
5405
5406 #ifdef WIFCONTINUED
5407 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
5408 "WIFCONTINUED(status) -> bool\n\n\
5409 Return True if the process returning 'status' was continued from a\n\
5410 job control stop.");
5411
5412 static PyObject *
posix_WIFCONTINUED(PyObject * self,PyObject * args)5413 posix_WIFCONTINUED(PyObject *self, PyObject *args)
5414 {
5415 WAIT_TYPE status;
5416 WAIT_STATUS_INT(status) = 0;
5417
5418 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
5419 return NULL;
5420
5421 return PyBool_FromLong(WIFCONTINUED(status));
5422 }
5423 #endif /* WIFCONTINUED */
5424
5425 #ifdef WIFSTOPPED
5426 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
5427 "WIFSTOPPED(status) -> bool\n\n\
5428 Return True if the process returning 'status' was stopped.");
5429
5430 static PyObject *
posix_WIFSTOPPED(PyObject * self,PyObject * args)5431 posix_WIFSTOPPED(PyObject *self, PyObject *args)
5432 {
5433 WAIT_TYPE status;
5434 WAIT_STATUS_INT(status) = 0;
5435
5436 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
5437 return NULL;
5438
5439 return PyBool_FromLong(WIFSTOPPED(status));
5440 }
5441 #endif /* WIFSTOPPED */
5442
5443 #ifdef WIFSIGNALED
5444 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
5445 "WIFSIGNALED(status) -> bool\n\n\
5446 Return True if the process returning 'status' was terminated by a signal.");
5447
5448 static PyObject *
posix_WIFSIGNALED(PyObject * self,PyObject * args)5449 posix_WIFSIGNALED(PyObject *self, PyObject *args)
5450 {
5451 WAIT_TYPE status;
5452 WAIT_STATUS_INT(status) = 0;
5453
5454 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
5455 return NULL;
5456
5457 return PyBool_FromLong(WIFSIGNALED(status));
5458 }
5459 #endif /* WIFSIGNALED */
5460
5461 #ifdef WIFEXITED
5462 PyDoc_STRVAR(posix_WIFEXITED__doc__,
5463 "WIFEXITED(status) -> bool\n\n\
5464 Return true if the process returning 'status' exited using the exit()\n\
5465 system call.");
5466
5467 static PyObject *
posix_WIFEXITED(PyObject * self,PyObject * args)5468 posix_WIFEXITED(PyObject *self, PyObject *args)
5469 {
5470 WAIT_TYPE status;
5471 WAIT_STATUS_INT(status) = 0;
5472
5473 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
5474 return NULL;
5475
5476 return PyBool_FromLong(WIFEXITED(status));
5477 }
5478 #endif /* WIFEXITED */
5479
5480 #ifdef WEXITSTATUS
5481 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
5482 "WEXITSTATUS(status) -> integer\n\n\
5483 Return the process return code from 'status'.");
5484
5485 static PyObject *
posix_WEXITSTATUS(PyObject * self,PyObject * args)5486 posix_WEXITSTATUS(PyObject *self, PyObject *args)
5487 {
5488 WAIT_TYPE status;
5489 WAIT_STATUS_INT(status) = 0;
5490
5491 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
5492 return NULL;
5493
5494 return Py_BuildValue("i", WEXITSTATUS(status));
5495 }
5496 #endif /* WEXITSTATUS */
5497
5498 #ifdef WTERMSIG
5499 PyDoc_STRVAR(posix_WTERMSIG__doc__,
5500 "WTERMSIG(status) -> integer\n\n\
5501 Return the signal that terminated the process that provided the 'status'\n\
5502 value.");
5503
5504 static PyObject *
posix_WTERMSIG(PyObject * self,PyObject * args)5505 posix_WTERMSIG(PyObject *self, PyObject *args)
5506 {
5507 WAIT_TYPE status;
5508 WAIT_STATUS_INT(status) = 0;
5509
5510 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
5511 return NULL;
5512
5513 return Py_BuildValue("i", WTERMSIG(status));
5514 }
5515 #endif /* WTERMSIG */
5516
5517 #ifdef WSTOPSIG
5518 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
5519 "WSTOPSIG(status) -> integer\n\n\
5520 Return the signal that stopped the process that provided\n\
5521 the 'status' value.");
5522
5523 static PyObject *
posix_WSTOPSIG(PyObject * self,PyObject * args)5524 posix_WSTOPSIG(PyObject *self, PyObject *args)
5525 {
5526 WAIT_TYPE status;
5527 WAIT_STATUS_INT(status) = 0;
5528
5529 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
5530 return NULL;
5531
5532 return Py_BuildValue("i", WSTOPSIG(status));
5533 }
5534 #endif /* WSTOPSIG */
5535
5536 #endif /* HAVE_SYS_WAIT_H */
5537
5538
5539 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
5540 #ifdef _SCO_DS
5541 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5542 needed definitions in sys/statvfs.h */
5543 #define _SVID3
5544 #endif
5545 #include <sys/statvfs.h>
5546
5547 static PyObject*
_pystatvfs_fromstructstatvfs(struct statvfs st)5548 _pystatvfs_fromstructstatvfs(struct statvfs st) {
5549 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5550 if (v == NULL)
5551 return NULL;
5552
5553 #if !defined(HAVE_LARGEFILE_SUPPORT)
5554 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5555 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5556 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5557 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5558 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5559 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5560 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5561 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5562 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5563 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5564 #else
5565 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5566 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5567 PyStructSequence_SET_ITEM(v, 2,
5568 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
5569 PyStructSequence_SET_ITEM(v, 3,
5570 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
5571 PyStructSequence_SET_ITEM(v, 4,
5572 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
5573 PyStructSequence_SET_ITEM(v, 5,
5574 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
5575 PyStructSequence_SET_ITEM(v, 6,
5576 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
5577 PyStructSequence_SET_ITEM(v, 7,
5578 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
5579 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5580 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5581 #endif
5582
5583 return v;
5584 }
5585
5586 PyDoc_STRVAR(posix_fstatvfs__doc__,
5587 "fstatvfs(fd) -> statvfs result\n\n\
5588 Perform an fstatvfs system call on the given fd.");
5589
5590 static PyObject *
posix_fstatvfs(PyObject * self,PyObject * args)5591 posix_fstatvfs(PyObject *self, PyObject *args)
5592 {
5593 int fd, res;
5594 struct statvfs st;
5595
5596 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
5597 return NULL;
5598 Py_BEGIN_ALLOW_THREADS
5599 res = fstatvfs(fd, &st);
5600 Py_END_ALLOW_THREADS
5601 if (res != 0)
5602 return posix_error();
5603
5604 return _pystatvfs_fromstructstatvfs(st);
5605 }
5606 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
5607
5608
5609 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
5610 #include <sys/statvfs.h>
5611
5612 PyDoc_STRVAR(posix_statvfs__doc__,
5613 "statvfs(path) -> statvfs result\n\n\
5614 Perform a statvfs system call on the given path.");
5615
5616 static PyObject *
posix_statvfs(PyObject * self,PyObject * args)5617 posix_statvfs(PyObject *self, PyObject *args)
5618 {
5619 char *path;
5620 int res;
5621 struct statvfs st;
5622 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
5623 return NULL;
5624 Py_BEGIN_ALLOW_THREADS
5625 res = statvfs(path, &st);
5626 Py_END_ALLOW_THREADS
5627 if (res != 0)
5628 return posix_error_with_filename(path);
5629
5630 return _pystatvfs_fromstructstatvfs(st);
5631 }
5632 #endif /* HAVE_STATVFS */
5633
5634
5635 #ifdef HAVE_TEMPNAM
5636 PyDoc_STRVAR(posix_tempnam__doc__,
5637 "tempnam([dir[, prefix]]) -> string\n\n\
5638 Return a unique name for a temporary file.\n\
5639 The directory and a prefix may be specified as strings; they may be omitted\n\
5640 or None if not needed.");
5641
5642 static PyObject *
posix_tempnam(PyObject * self,PyObject * args)5643 posix_tempnam(PyObject *self, PyObject *args)
5644 {
5645 PyObject *result = NULL;
5646 char *dir = NULL;
5647 char *pfx = NULL;
5648 char *name;
5649
5650 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5651 return NULL;
5652
5653 if (PyErr_Warn(PyExc_RuntimeWarning,
5654 "tempnam is a potential security risk to your program") < 0)
5655 return NULL;
5656
5657 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
5658 "use the tempfile module", 1) < 0)
5659 return NULL;
5660
5661 name = tempnam(dir, pfx);
5662 if (name == NULL)
5663 return PyErr_NoMemory();
5664 result = PyString_FromString(name);
5665 free(name);
5666 return result;
5667 }
5668 #endif
5669
5670
5671 #ifdef HAVE_TMPFILE
5672 PyDoc_STRVAR(posix_tmpfile__doc__,
5673 "tmpfile() -> file object\n\n\
5674 Create a temporary file with no directory entries.");
5675
5676 static PyObject *
posix_tmpfile(PyObject * self,PyObject * noargs)5677 posix_tmpfile(PyObject *self, PyObject *noargs)
5678 {
5679 FILE *fp;
5680
5681 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
5682 "use the tempfile module", 1) < 0)
5683 return NULL;
5684
5685 fp = tmpfile();
5686 if (fp == NULL)
5687 return posix_error();
5688 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
5689 }
5690 #endif
5691
5692
5693 #ifdef HAVE_TMPNAM
5694 PyDoc_STRVAR(posix_tmpnam__doc__,
5695 "tmpnam() -> string\n\n\
5696 Return a unique name for a temporary file.");
5697
5698 static PyObject *
posix_tmpnam(PyObject * self,PyObject * noargs)5699 posix_tmpnam(PyObject *self, PyObject *noargs)
5700 {
5701 char buffer[L_tmpnam];
5702 char *name;
5703
5704 if (PyErr_Warn(PyExc_RuntimeWarning,
5705 "tmpnam is a potential security risk to your program") < 0)
5706 return NULL;
5707
5708 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
5709 "use the tempfile module", 1) < 0)
5710 return NULL;
5711
5712 #ifdef USE_TMPNAM_R
5713 name = tmpnam_r(buffer);
5714 #else
5715 name = tmpnam(buffer);
5716 #endif
5717 if (name == NULL) {
5718 PyObject *err = Py_BuildValue("is", 0,
5719 #ifdef USE_TMPNAM_R
5720 "unexpected NULL from tmpnam_r"
5721 #else
5722 "unexpected NULL from tmpnam"
5723 #endif
5724 );
5725 PyErr_SetObject(PyExc_OSError, err);
5726 Py_XDECREF(err);
5727 return NULL;
5728 }
5729 return PyString_FromString(buffer);
5730 }
5731 #endif
5732
5733
5734 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5735 * It maps strings representing configuration variable names to
5736 * integer values, allowing those functions to be called with the
5737 * magic names instead of polluting the module's namespace with tons of
5738 * rarely-used constants. There are three separate tables that use
5739 * these definitions.
5740 *
5741 * This code is always included, even if none of the interfaces that
5742 * need it are included. The #if hackery needed to avoid it would be
5743 * sufficiently pervasive that it's not worth the loss of readability.
5744 */
5745 struct constdef {
5746 char *name;
5747 long value;
5748 };
5749
5750 #ifndef UEFI_C_SOURCE
5751 static int
conv_confname(PyObject * arg,int * valuep,struct constdef * table,size_t tablesize)5752 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5753 size_t tablesize)
5754 {
5755 if (PyInt_Check(arg)) {
5756 *valuep = PyInt_AS_LONG(arg);
5757 return 1;
5758 }
5759 if (PyString_Check(arg)) {
5760 /* look up the value in the table using a binary search */
5761 size_t lo = 0;
5762 size_t mid;
5763 size_t hi = tablesize;
5764 int cmp;
5765 char *confname = PyString_AS_STRING(arg);
5766 while (lo < hi) {
5767 mid = (lo + hi) / 2;
5768 cmp = strcmp(confname, table[mid].name);
5769 if (cmp < 0)
5770 hi = mid;
5771 else if (cmp > 0)
5772 lo = mid + 1;
5773 else {
5774 *valuep = table[mid].value;
5775 return 1;
5776 }
5777 }
5778 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5779 }
5780 else
5781 PyErr_SetString(PyExc_TypeError,
5782 "configuration names must be strings or integers");
5783 return 0;
5784 }
5785 #endif /* UEFI_C_SOURCE */
5786
5787 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5788 static struct constdef posix_constants_pathconf[] = {
5789 #ifdef _PC_ABI_AIO_XFER_MAX
5790 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5791 #endif
5792 #ifdef _PC_ABI_ASYNC_IO
5793 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5794 #endif
5795 #ifdef _PC_ASYNC_IO
5796 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5797 #endif
5798 #ifdef _PC_CHOWN_RESTRICTED
5799 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5800 #endif
5801 #ifdef _PC_FILESIZEBITS
5802 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5803 #endif
5804 #ifdef _PC_LAST
5805 {"PC_LAST", _PC_LAST},
5806 #endif
5807 #ifdef _PC_LINK_MAX
5808 {"PC_LINK_MAX", _PC_LINK_MAX},
5809 #endif
5810 #ifdef _PC_MAX_CANON
5811 {"PC_MAX_CANON", _PC_MAX_CANON},
5812 #endif
5813 #ifdef _PC_MAX_INPUT
5814 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5815 #endif
5816 #ifdef _PC_NAME_MAX
5817 {"PC_NAME_MAX", _PC_NAME_MAX},
5818 #endif
5819 #ifdef _PC_NO_TRUNC
5820 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5821 #endif
5822 #ifdef _PC_PATH_MAX
5823 {"PC_PATH_MAX", _PC_PATH_MAX},
5824 #endif
5825 #ifdef _PC_PIPE_BUF
5826 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5827 #endif
5828 #ifdef _PC_PRIO_IO
5829 {"PC_PRIO_IO", _PC_PRIO_IO},
5830 #endif
5831 #ifdef _PC_SOCK_MAXBUF
5832 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5833 #endif
5834 #ifdef _PC_SYNC_IO
5835 {"PC_SYNC_IO", _PC_SYNC_IO},
5836 #endif
5837 #ifdef _PC_VDISABLE
5838 {"PC_VDISABLE", _PC_VDISABLE},
5839 #endif
5840 };
5841
5842 static int
conv_path_confname(PyObject * arg,int * valuep)5843 conv_path_confname(PyObject *arg, int *valuep)
5844 {
5845 return conv_confname(arg, valuep, posix_constants_pathconf,
5846 sizeof(posix_constants_pathconf)
5847 / sizeof(struct constdef));
5848 }
5849 #endif
5850
5851 #ifdef HAVE_FPATHCONF
5852 PyDoc_STRVAR(posix_fpathconf__doc__,
5853 "fpathconf(fd, name) -> integer\n\n\
5854 Return the configuration limit name for the file descriptor fd.\n\
5855 If there is no limit, return -1.");
5856
5857 static PyObject *
posix_fpathconf(PyObject * self,PyObject * args)5858 posix_fpathconf(PyObject *self, PyObject *args)
5859 {
5860 PyObject *result = NULL;
5861 int name, fd;
5862
5863 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5864 conv_path_confname, &name)) {
5865 long limit;
5866
5867 errno = 0;
5868 limit = fpathconf(fd, name);
5869 if (limit == -1 && errno != 0)
5870 posix_error();
5871 else
5872 result = PyInt_FromLong(limit);
5873 }
5874 return result;
5875 }
5876 #endif
5877
5878
5879 #ifdef HAVE_PATHCONF
5880 PyDoc_STRVAR(posix_pathconf__doc__,
5881 "pathconf(path, name) -> integer\n\n\
5882 Return the configuration limit name for the file or directory path.\n\
5883 If there is no limit, return -1.");
5884
5885 static PyObject *
posix_pathconf(PyObject * self,PyObject * args)5886 posix_pathconf(PyObject *self, PyObject *args)
5887 {
5888 PyObject *result = NULL;
5889 int name;
5890 char *path;
5891
5892 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5893 conv_path_confname, &name)) {
5894 long limit;
5895
5896 errno = 0;
5897 limit = pathconf(path, name);
5898 if (limit == -1 && errno != 0) {
5899 if (errno == EINVAL)
5900 /* could be a path or name problem */
5901 posix_error();
5902 else
5903 posix_error_with_filename(path);
5904 }
5905 else
5906 result = PyInt_FromLong(limit);
5907 }
5908 return result;
5909 }
5910 #endif
5911
5912 #ifdef HAVE_CONFSTR
5913 static struct constdef posix_constants_confstr[] = {
5914 #ifdef _CS_ARCHITECTURE
5915 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5916 #endif
5917 #ifdef _CS_HOSTNAME
5918 {"CS_HOSTNAME", _CS_HOSTNAME},
5919 #endif
5920 #ifdef _CS_HW_PROVIDER
5921 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5922 #endif
5923 #ifdef _CS_HW_SERIAL
5924 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5925 #endif
5926 #ifdef _CS_INITTAB_NAME
5927 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5928 #endif
5929 #ifdef _CS_LFS64_CFLAGS
5930 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5931 #endif
5932 #ifdef _CS_LFS64_LDFLAGS
5933 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5934 #endif
5935 #ifdef _CS_LFS64_LIBS
5936 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5937 #endif
5938 #ifdef _CS_LFS64_LINTFLAGS
5939 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5940 #endif
5941 #ifdef _CS_LFS_CFLAGS
5942 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5943 #endif
5944 #ifdef _CS_LFS_LDFLAGS
5945 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5946 #endif
5947 #ifdef _CS_LFS_LIBS
5948 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5949 #endif
5950 #ifdef _CS_LFS_LINTFLAGS
5951 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5952 #endif
5953 #ifdef _CS_MACHINE
5954 {"CS_MACHINE", _CS_MACHINE},
5955 #endif
5956 #ifdef _CS_PATH
5957 {"CS_PATH", _CS_PATH},
5958 #endif
5959 #ifdef _CS_RELEASE
5960 {"CS_RELEASE", _CS_RELEASE},
5961 #endif
5962 #ifdef _CS_SRPC_DOMAIN
5963 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5964 #endif
5965 #ifdef _CS_SYSNAME
5966 {"CS_SYSNAME", _CS_SYSNAME},
5967 #endif
5968 #ifdef _CS_VERSION
5969 {"CS_VERSION", _CS_VERSION},
5970 #endif
5971 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5972 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5973 #endif
5974 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5975 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5976 #endif
5977 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
5978 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5979 #endif
5980 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5981 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5982 #endif
5983 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5984 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5985 #endif
5986 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5987 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5988 #endif
5989 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5990 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5991 #endif
5992 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5993 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5994 #endif
5995 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5996 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5997 #endif
5998 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5999 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6000 #endif
6001 #ifdef _CS_XBS5_LP64_OFF64_LIBS
6002 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6003 #endif
6004 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6005 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6006 #endif
6007 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6008 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6009 #endif
6010 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6011 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6012 #endif
6013 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6014 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6015 #endif
6016 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6017 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6018 #endif
6019 #ifdef _MIPS_CS_AVAIL_PROCESSORS
6020 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6021 #endif
6022 #ifdef _MIPS_CS_BASE
6023 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6024 #endif
6025 #ifdef _MIPS_CS_HOSTID
6026 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6027 #endif
6028 #ifdef _MIPS_CS_HW_NAME
6029 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6030 #endif
6031 #ifdef _MIPS_CS_NUM_PROCESSORS
6032 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6033 #endif
6034 #ifdef _MIPS_CS_OSREL_MAJ
6035 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6036 #endif
6037 #ifdef _MIPS_CS_OSREL_MIN
6038 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6039 #endif
6040 #ifdef _MIPS_CS_OSREL_PATCH
6041 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6042 #endif
6043 #ifdef _MIPS_CS_OS_NAME
6044 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6045 #endif
6046 #ifdef _MIPS_CS_OS_PROVIDER
6047 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6048 #endif
6049 #ifdef _MIPS_CS_PROCESSORS
6050 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6051 #endif
6052 #ifdef _MIPS_CS_SERIAL
6053 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6054 #endif
6055 #ifdef _MIPS_CS_VENDOR
6056 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6057 #endif
6058 };
6059
6060 static int
conv_confstr_confname(PyObject * arg,int * valuep)6061 conv_confstr_confname(PyObject *arg, int *valuep)
6062 {
6063 return conv_confname(arg, valuep, posix_constants_confstr,
6064 sizeof(posix_constants_confstr)
6065 / sizeof(struct constdef));
6066 }
6067
6068 PyDoc_STRVAR(posix_confstr__doc__,
6069 "confstr(name) -> string\n\n\
6070 Return a string-valued system configuration variable.");
6071
6072 static PyObject *
posix_confstr(PyObject * self,PyObject * args)6073 posix_confstr(PyObject *self, PyObject *args)
6074 {
6075 PyObject *result = NULL;
6076 int name;
6077 char buffer[256];
6078
6079 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6080 int len;
6081
6082 errno = 0;
6083 len = confstr(name, buffer, sizeof(buffer));
6084 if (len == 0) {
6085 if (errno) {
6086 posix_error();
6087 }
6088 else {
6089 result = Py_None;
6090 Py_INCREF(Py_None);
6091 }
6092 }
6093 else {
6094 if ((unsigned int)len >= sizeof(buffer)) {
6095 result = PyString_FromStringAndSize(NULL, len-1);
6096 if (result != NULL)
6097 confstr(name, PyString_AS_STRING(result), len);
6098 }
6099 else
6100 result = PyString_FromStringAndSize(buffer, len-1);
6101 }
6102 }
6103 return result;
6104 }
6105 #endif
6106
6107
6108 #ifdef HAVE_SYSCONF
6109 static struct constdef posix_constants_sysconf[] = {
6110 #ifdef _SC_2_CHAR_TERM
6111 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6112 #endif
6113 #ifdef _SC_2_C_BIND
6114 {"SC_2_C_BIND", _SC_2_C_BIND},
6115 #endif
6116 #ifdef _SC_2_C_DEV
6117 {"SC_2_C_DEV", _SC_2_C_DEV},
6118 #endif
6119 #ifdef _SC_2_C_VERSION
6120 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6121 #endif
6122 #ifdef _SC_2_FORT_DEV
6123 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6124 #endif
6125 #ifdef _SC_2_FORT_RUN
6126 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6127 #endif
6128 #ifdef _SC_2_LOCALEDEF
6129 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6130 #endif
6131 #ifdef _SC_2_SW_DEV
6132 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6133 #endif
6134 #ifdef _SC_2_UPE
6135 {"SC_2_UPE", _SC_2_UPE},
6136 #endif
6137 #ifdef _SC_2_VERSION
6138 {"SC_2_VERSION", _SC_2_VERSION},
6139 #endif
6140 #ifdef _SC_ABI_ASYNCHRONOUS_IO
6141 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6142 #endif
6143 #ifdef _SC_ACL
6144 {"SC_ACL", _SC_ACL},
6145 #endif
6146 #ifdef _SC_AIO_LISTIO_MAX
6147 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6148 #endif
6149 #ifdef _SC_AIO_MAX
6150 {"SC_AIO_MAX", _SC_AIO_MAX},
6151 #endif
6152 #ifdef _SC_AIO_PRIO_DELTA_MAX
6153 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6154 #endif
6155 #ifdef _SC_ARG_MAX
6156 {"SC_ARG_MAX", _SC_ARG_MAX},
6157 #endif
6158 #ifdef _SC_ASYNCHRONOUS_IO
6159 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6160 #endif
6161 #ifdef _SC_ATEXIT_MAX
6162 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6163 #endif
6164 #ifdef _SC_AUDIT
6165 {"SC_AUDIT", _SC_AUDIT},
6166 #endif
6167 #ifdef _SC_AVPHYS_PAGES
6168 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6169 #endif
6170 #ifdef _SC_BC_BASE_MAX
6171 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6172 #endif
6173 #ifdef _SC_BC_DIM_MAX
6174 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6175 #endif
6176 #ifdef _SC_BC_SCALE_MAX
6177 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6178 #endif
6179 #ifdef _SC_BC_STRING_MAX
6180 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6181 #endif
6182 #ifdef _SC_CAP
6183 {"SC_CAP", _SC_CAP},
6184 #endif
6185 #ifdef _SC_CHARCLASS_NAME_MAX
6186 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6187 #endif
6188 #ifdef _SC_CHAR_BIT
6189 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6190 #endif
6191 #ifdef _SC_CHAR_MAX
6192 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6193 #endif
6194 #ifdef _SC_CHAR_MIN
6195 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6196 #endif
6197 #ifdef _SC_CHILD_MAX
6198 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6199 #endif
6200 #ifdef _SC_CLK_TCK
6201 {"SC_CLK_TCK", _SC_CLK_TCK},
6202 #endif
6203 #ifdef _SC_COHER_BLKSZ
6204 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6205 #endif
6206 #ifdef _SC_COLL_WEIGHTS_MAX
6207 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6208 #endif
6209 #ifdef _SC_DCACHE_ASSOC
6210 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6211 #endif
6212 #ifdef _SC_DCACHE_BLKSZ
6213 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6214 #endif
6215 #ifdef _SC_DCACHE_LINESZ
6216 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6217 #endif
6218 #ifdef _SC_DCACHE_SZ
6219 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6220 #endif
6221 #ifdef _SC_DCACHE_TBLKSZ
6222 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6223 #endif
6224 #ifdef _SC_DELAYTIMER_MAX
6225 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6226 #endif
6227 #ifdef _SC_EQUIV_CLASS_MAX
6228 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6229 #endif
6230 #ifdef _SC_EXPR_NEST_MAX
6231 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6232 #endif
6233 #ifdef _SC_FSYNC
6234 {"SC_FSYNC", _SC_FSYNC},
6235 #endif
6236 #ifdef _SC_GETGR_R_SIZE_MAX
6237 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6238 #endif
6239 #ifdef _SC_GETPW_R_SIZE_MAX
6240 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6241 #endif
6242 #ifdef _SC_ICACHE_ASSOC
6243 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6244 #endif
6245 #ifdef _SC_ICACHE_BLKSZ
6246 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6247 #endif
6248 #ifdef _SC_ICACHE_LINESZ
6249 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6250 #endif
6251 #ifdef _SC_ICACHE_SZ
6252 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6253 #endif
6254 #ifdef _SC_INF
6255 {"SC_INF", _SC_INF},
6256 #endif
6257 #ifdef _SC_INT_MAX
6258 {"SC_INT_MAX", _SC_INT_MAX},
6259 #endif
6260 #ifdef _SC_INT_MIN
6261 {"SC_INT_MIN", _SC_INT_MIN},
6262 #endif
6263 #ifdef _SC_IOV_MAX
6264 {"SC_IOV_MAX", _SC_IOV_MAX},
6265 #endif
6266 #ifdef _SC_IP_SECOPTS
6267 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6268 #endif
6269 #ifdef _SC_JOB_CONTROL
6270 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6271 #endif
6272 #ifdef _SC_KERN_POINTERS
6273 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6274 #endif
6275 #ifdef _SC_KERN_SIM
6276 {"SC_KERN_SIM", _SC_KERN_SIM},
6277 #endif
6278 #ifdef _SC_LINE_MAX
6279 {"SC_LINE_MAX", _SC_LINE_MAX},
6280 #endif
6281 #ifdef _SC_LOGIN_NAME_MAX
6282 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6283 #endif
6284 #ifdef _SC_LOGNAME_MAX
6285 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6286 #endif
6287 #ifdef _SC_LONG_BIT
6288 {"SC_LONG_BIT", _SC_LONG_BIT},
6289 #endif
6290 #ifdef _SC_MAC
6291 {"SC_MAC", _SC_MAC},
6292 #endif
6293 #ifdef _SC_MAPPED_FILES
6294 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6295 #endif
6296 #ifdef _SC_MAXPID
6297 {"SC_MAXPID", _SC_MAXPID},
6298 #endif
6299 #ifdef _SC_MB_LEN_MAX
6300 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6301 #endif
6302 #ifdef _SC_MEMLOCK
6303 {"SC_MEMLOCK", _SC_MEMLOCK},
6304 #endif
6305 #ifdef _SC_MEMLOCK_RANGE
6306 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6307 #endif
6308 #ifdef _SC_MEMORY_PROTECTION
6309 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6310 #endif
6311 #ifdef _SC_MESSAGE_PASSING
6312 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6313 #endif
6314 #ifdef _SC_MMAP_FIXED_ALIGNMENT
6315 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6316 #endif
6317 #ifdef _SC_MQ_OPEN_MAX
6318 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6319 #endif
6320 #ifdef _SC_MQ_PRIO_MAX
6321 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6322 #endif
6323 #ifdef _SC_NACLS_MAX
6324 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6325 #endif
6326 #ifdef _SC_NGROUPS_MAX
6327 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6328 #endif
6329 #ifdef _SC_NL_ARGMAX
6330 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6331 #endif
6332 #ifdef _SC_NL_LANGMAX
6333 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6334 #endif
6335 #ifdef _SC_NL_MSGMAX
6336 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6337 #endif
6338 #ifdef _SC_NL_NMAX
6339 {"SC_NL_NMAX", _SC_NL_NMAX},
6340 #endif
6341 #ifdef _SC_NL_SETMAX
6342 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6343 #endif
6344 #ifdef _SC_NL_TEXTMAX
6345 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6346 #endif
6347 #ifdef _SC_NPROCESSORS_CONF
6348 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6349 #endif
6350 #ifdef _SC_NPROCESSORS_ONLN
6351 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6352 #endif
6353 #ifdef _SC_NPROC_CONF
6354 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6355 #endif
6356 #ifdef _SC_NPROC_ONLN
6357 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6358 #endif
6359 #ifdef _SC_NZERO
6360 {"SC_NZERO", _SC_NZERO},
6361 #endif
6362 #ifdef _SC_OPEN_MAX
6363 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6364 #endif
6365 #ifdef _SC_PAGESIZE
6366 {"SC_PAGESIZE", _SC_PAGESIZE},
6367 #endif
6368 #ifdef _SC_PAGE_SIZE
6369 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6370 #endif
6371 #ifdef _SC_PASS_MAX
6372 {"SC_PASS_MAX", _SC_PASS_MAX},
6373 #endif
6374 #ifdef _SC_PHYS_PAGES
6375 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6376 #endif
6377 #ifdef _SC_PII
6378 {"SC_PII", _SC_PII},
6379 #endif
6380 #ifdef _SC_PII_INTERNET
6381 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6382 #endif
6383 #ifdef _SC_PII_INTERNET_DGRAM
6384 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6385 #endif
6386 #ifdef _SC_PII_INTERNET_STREAM
6387 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6388 #endif
6389 #ifdef _SC_PII_OSI
6390 {"SC_PII_OSI", _SC_PII_OSI},
6391 #endif
6392 #ifdef _SC_PII_OSI_CLTS
6393 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6394 #endif
6395 #ifdef _SC_PII_OSI_COTS
6396 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6397 #endif
6398 #ifdef _SC_PII_OSI_M
6399 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6400 #endif
6401 #ifdef _SC_PII_SOCKET
6402 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6403 #endif
6404 #ifdef _SC_PII_XTI
6405 {"SC_PII_XTI", _SC_PII_XTI},
6406 #endif
6407 #ifdef _SC_POLL
6408 {"SC_POLL", _SC_POLL},
6409 #endif
6410 #ifdef _SC_PRIORITIZED_IO
6411 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6412 #endif
6413 #ifdef _SC_PRIORITY_SCHEDULING
6414 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6415 #endif
6416 #ifdef _SC_REALTIME_SIGNALS
6417 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6418 #endif
6419 #ifdef _SC_RE_DUP_MAX
6420 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6421 #endif
6422 #ifdef _SC_RTSIG_MAX
6423 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6424 #endif
6425 #ifdef _SC_SAVED_IDS
6426 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6427 #endif
6428 #ifdef _SC_SCHAR_MAX
6429 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6430 #endif
6431 #ifdef _SC_SCHAR_MIN
6432 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6433 #endif
6434 #ifdef _SC_SELECT
6435 {"SC_SELECT", _SC_SELECT},
6436 #endif
6437 #ifdef _SC_SEMAPHORES
6438 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6439 #endif
6440 #ifdef _SC_SEM_NSEMS_MAX
6441 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6442 #endif
6443 #ifdef _SC_SEM_VALUE_MAX
6444 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6445 #endif
6446 #ifdef _SC_SHARED_MEMORY_OBJECTS
6447 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6448 #endif
6449 #ifdef _SC_SHRT_MAX
6450 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6451 #endif
6452 #ifdef _SC_SHRT_MIN
6453 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6454 #endif
6455 #ifdef _SC_SIGQUEUE_MAX
6456 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6457 #endif
6458 #ifdef _SC_SIGRT_MAX
6459 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6460 #endif
6461 #ifdef _SC_SIGRT_MIN
6462 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6463 #endif
6464 #ifdef _SC_SOFTPOWER
6465 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6466 #endif
6467 #ifdef _SC_SPLIT_CACHE
6468 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6469 #endif
6470 #ifdef _SC_SSIZE_MAX
6471 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6472 #endif
6473 #ifdef _SC_STACK_PROT
6474 {"SC_STACK_PROT", _SC_STACK_PROT},
6475 #endif
6476 #ifdef _SC_STREAM_MAX
6477 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6478 #endif
6479 #ifdef _SC_SYNCHRONIZED_IO
6480 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6481 #endif
6482 #ifdef _SC_THREADS
6483 {"SC_THREADS", _SC_THREADS},
6484 #endif
6485 #ifdef _SC_THREAD_ATTR_STACKADDR
6486 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6487 #endif
6488 #ifdef _SC_THREAD_ATTR_STACKSIZE
6489 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6490 #endif
6491 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6492 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6493 #endif
6494 #ifdef _SC_THREAD_KEYS_MAX
6495 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6496 #endif
6497 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
6498 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6499 #endif
6500 #ifdef _SC_THREAD_PRIO_INHERIT
6501 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6502 #endif
6503 #ifdef _SC_THREAD_PRIO_PROTECT
6504 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6505 #endif
6506 #ifdef _SC_THREAD_PROCESS_SHARED
6507 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6508 #endif
6509 #ifdef _SC_THREAD_SAFE_FUNCTIONS
6510 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6511 #endif
6512 #ifdef _SC_THREAD_STACK_MIN
6513 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6514 #endif
6515 #ifdef _SC_THREAD_THREADS_MAX
6516 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6517 #endif
6518 #ifdef _SC_TIMERS
6519 {"SC_TIMERS", _SC_TIMERS},
6520 #endif
6521 #ifdef _SC_TIMER_MAX
6522 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6523 #endif
6524 #ifdef _SC_TTY_NAME_MAX
6525 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6526 #endif
6527 #ifdef _SC_TZNAME_MAX
6528 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6529 #endif
6530 #ifdef _SC_T_IOV_MAX
6531 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6532 #endif
6533 #ifdef _SC_UCHAR_MAX
6534 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6535 #endif
6536 #ifdef _SC_UINT_MAX
6537 {"SC_UINT_MAX", _SC_UINT_MAX},
6538 #endif
6539 #ifdef _SC_UIO_MAXIOV
6540 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6541 #endif
6542 #ifdef _SC_ULONG_MAX
6543 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6544 #endif
6545 #ifdef _SC_USHRT_MAX
6546 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6547 #endif
6548 #ifdef _SC_VERSION
6549 {"SC_VERSION", _SC_VERSION},
6550 #endif
6551 #ifdef _SC_WORD_BIT
6552 {"SC_WORD_BIT", _SC_WORD_BIT},
6553 #endif
6554 #ifdef _SC_XBS5_ILP32_OFF32
6555 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6556 #endif
6557 #ifdef _SC_XBS5_ILP32_OFFBIG
6558 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6559 #endif
6560 #ifdef _SC_XBS5_LP64_OFF64
6561 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6562 #endif
6563 #ifdef _SC_XBS5_LPBIG_OFFBIG
6564 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6565 #endif
6566 #ifdef _SC_XOPEN_CRYPT
6567 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6568 #endif
6569 #ifdef _SC_XOPEN_ENH_I18N
6570 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6571 #endif
6572 #ifdef _SC_XOPEN_LEGACY
6573 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6574 #endif
6575 #ifdef _SC_XOPEN_REALTIME
6576 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6577 #endif
6578 #ifdef _SC_XOPEN_REALTIME_THREADS
6579 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6580 #endif
6581 #ifdef _SC_XOPEN_SHM
6582 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6583 #endif
6584 #ifdef _SC_XOPEN_UNIX
6585 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6586 #endif
6587 #ifdef _SC_XOPEN_VERSION
6588 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6589 #endif
6590 #ifdef _SC_XOPEN_XCU_VERSION
6591 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6592 #endif
6593 #ifdef _SC_XOPEN_XPG2
6594 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6595 #endif
6596 #ifdef _SC_XOPEN_XPG3
6597 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6598 #endif
6599 #ifdef _SC_XOPEN_XPG4
6600 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6601 #endif
6602 };
6603
6604 static int
conv_sysconf_confname(PyObject * arg,int * valuep)6605 conv_sysconf_confname(PyObject *arg, int *valuep)
6606 {
6607 return conv_confname(arg, valuep, posix_constants_sysconf,
6608 sizeof(posix_constants_sysconf)
6609 / sizeof(struct constdef));
6610 }
6611
6612 PyDoc_STRVAR(posix_sysconf__doc__,
6613 "sysconf(name) -> integer\n\n\
6614 Return an integer-valued system configuration variable.");
6615
6616 static PyObject *
posix_sysconf(PyObject * self,PyObject * args)6617 posix_sysconf(PyObject *self, PyObject *args)
6618 {
6619 PyObject *result = NULL;
6620 int name;
6621
6622 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6623 int value;
6624
6625 errno = 0;
6626 value = sysconf(name);
6627 if (value == -1 && errno != 0)
6628 posix_error();
6629 else
6630 result = PyInt_FromLong(value);
6631 }
6632 return result;
6633 }
6634 #endif
6635
6636
6637 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) || defined(HAVE_CONFSTR) || defined(HAVE_SYSCONF)
6638 /* This code is used to ensure that the tables of configuration value names
6639 * are in sorted order as required by conv_confname(), and also to build the
6640 * the exported dictionaries that are used to publish information about the
6641 * names available on the host platform.
6642 *
6643 * Sorting the table at runtime ensures that the table is properly ordered
6644 * when used, even for platforms we're not able to test on. It also makes
6645 * it easier to add additional entries to the tables.
6646 */
6647
6648 static int
cmp_constdefs(const void * v1,const void * v2)6649 cmp_constdefs(const void *v1, const void *v2)
6650 {
6651 const struct constdef *c1 =
6652 (const struct constdef *) v1;
6653 const struct constdef *c2 =
6654 (const struct constdef *) v2;
6655
6656 return strcmp(c1->name, c2->name);
6657 }
6658
6659 static int
setup_confname_table(struct constdef * table,size_t tablesize,char * tablename,PyObject * module)6660 setup_confname_table(struct constdef *table, size_t tablesize,
6661 char *tablename, PyObject *module)
6662 {
6663 PyObject *d = NULL;
6664 size_t i;
6665
6666 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6667 d = PyDict_New();
6668 if (d == NULL)
6669 return -1;
6670
6671 for (i=0; i < tablesize; ++i) {
6672 PyObject *o = PyInt_FromLong(table[i].value);
6673 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6674 Py_XDECREF(o);
6675 Py_DECREF(d);
6676 return -1;
6677 }
6678 Py_DECREF(o);
6679 }
6680 return PyModule_AddObject(module, tablename, d);
6681 }
6682 #endif /* HAVE_FPATHCONF || HAVE_PATHCONF || HAVE_CONFSTR || HAVE_SYSCONF */
6683
6684 /* Return -1 on failure, 0 on success. */
6685 static int
setup_confname_tables(PyObject * module)6686 setup_confname_tables(PyObject *module)
6687 {
6688 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6689 if (setup_confname_table(posix_constants_pathconf,
6690 sizeof(posix_constants_pathconf)
6691 / sizeof(struct constdef),
6692 "pathconf_names", module))
6693 return -1;
6694 #endif
6695 #ifdef HAVE_CONFSTR
6696 if (setup_confname_table(posix_constants_confstr,
6697 sizeof(posix_constants_confstr)
6698 / sizeof(struct constdef),
6699 "confstr_names", module))
6700 return -1;
6701 #endif
6702 #ifdef HAVE_SYSCONF
6703 if (setup_confname_table(posix_constants_sysconf,
6704 sizeof(posix_constants_sysconf)
6705 / sizeof(struct constdef),
6706 "sysconf_names", module))
6707 return -1;
6708 #endif
6709 return 0;
6710 }
6711
6712
6713 PyDoc_STRVAR(posix_abort__doc__,
6714 "abort() -> does not return!\n\n\
6715 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
6716 in the hardest way possible on the hosting operating system.");
6717
6718 static PyObject *
posix_abort(PyObject * self,PyObject * noargs)6719 posix_abort(PyObject *self, PyObject *noargs)
6720 {
6721 abort();
6722 /*NOTREACHED*/
6723 Py_FatalError("abort() called from Python code didn't abort!");
6724 return NULL;
6725 }
6726
6727 #ifdef HAVE_SETRESUID
6728 PyDoc_STRVAR(posix_setresuid__doc__,
6729 "setresuid(ruid, euid, suid)\n\n\
6730 Set the current process's real, effective, and saved user ids.");
6731
6732 static PyObject*
posix_setresuid(PyObject * self,PyObject * args)6733 posix_setresuid (PyObject *self, PyObject *args)
6734 {
6735 /* We assume uid_t is no larger than a long. */
6736 long ruid, euid, suid;
6737 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
6738 return NULL;
6739 if (setresuid(ruid, euid, suid) < 0)
6740 return posix_error();
6741 Py_RETURN_NONE;
6742 }
6743 #endif
6744
6745 #ifdef HAVE_SETRESGID
6746 PyDoc_STRVAR(posix_setresgid__doc__,
6747 "setresgid(rgid, egid, sgid)\n\n\
6748 Set the current process's real, effective, and saved group ids.");
6749
6750 static PyObject*
posix_setresgid(PyObject * self,PyObject * args)6751 posix_setresgid (PyObject *self, PyObject *args)
6752 {
6753 /* We assume uid_t is no larger than a long. */
6754 long rgid, egid, sgid;
6755 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
6756 return NULL;
6757 if (setresgid(rgid, egid, sgid) < 0)
6758 return posix_error();
6759 Py_RETURN_NONE;
6760 }
6761 #endif
6762
6763 #ifdef HAVE_GETRESUID
6764 PyDoc_STRVAR(posix_getresuid__doc__,
6765 "getresuid() -> (ruid, euid, suid)\n\n\
6766 Get tuple of the current process's real, effective, and saved user ids.");
6767
6768 static PyObject*
posix_getresuid(PyObject * self,PyObject * noargs)6769 posix_getresuid (PyObject *self, PyObject *noargs)
6770 {
6771 uid_t ruid, euid, suid;
6772 long l_ruid, l_euid, l_suid;
6773 if (getresuid(&ruid, &euid, &suid) < 0)
6774 return posix_error();
6775 /* Force the values into long's as we don't know the size of uid_t. */
6776 l_ruid = ruid;
6777 l_euid = euid;
6778 l_suid = suid;
6779 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
6780 }
6781 #endif
6782
6783 #ifdef HAVE_GETRESGID
6784 PyDoc_STRVAR(posix_getresgid__doc__,
6785 "getresgid() -> (rgid, egid, sgid)\n\n\
6786 Get tuple of the current process's real, effective, and saved group ids.");
6787
6788 static PyObject*
posix_getresgid(PyObject * self,PyObject * noargs)6789 posix_getresgid (PyObject *self, PyObject *noargs)
6790 {
6791 uid_t rgid, egid, sgid;
6792 long l_rgid, l_egid, l_sgid;
6793 if (getresgid(&rgid, &egid, &sgid) < 0)
6794 return posix_error();
6795 /* Force the values into long's as we don't know the size of uid_t. */
6796 l_rgid = rgid;
6797 l_egid = egid;
6798 l_sgid = sgid;
6799 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
6800 }
6801 #endif
6802
6803 static PyMethodDef posix_methods[] = {
6804 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6805 #ifdef HAVE_TTYNAME
6806 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6807 #endif
6808 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6809 #ifdef HAVE_CHFLAGS
6810 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
6811 #endif /* HAVE_CHFLAGS */
6812 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
6813 #ifdef HAVE_FCHMOD
6814 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
6815 #endif /* HAVE_FCHMOD */
6816 #ifdef HAVE_CHOWN
6817 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
6818 #endif /* HAVE_CHOWN */
6819 #ifdef HAVE_LCHMOD
6820 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
6821 #endif /* HAVE_LCHMOD */
6822 #ifdef HAVE_FCHOWN
6823 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
6824 #endif /* HAVE_FCHOWN */
6825 #ifdef HAVE_LCHFLAGS
6826 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
6827 #endif /* HAVE_LCHFLAGS */
6828 #ifdef HAVE_LCHOWN
6829 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6830 #endif /* HAVE_LCHOWN */
6831 #ifdef HAVE_CHROOT
6832 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6833 #endif
6834 #ifdef HAVE_CTERMID
6835 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
6836 #endif
6837 #ifdef HAVE_GETCWD
6838 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
6839 #ifdef Py_USING_UNICODE
6840 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
6841 #endif
6842 #endif
6843 #ifdef HAVE_LINK
6844 {"link", posix_link, METH_VARARGS, posix_link__doc__},
6845 #endif /* HAVE_LINK */
6846 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6847 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6848 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
6849 #ifdef HAVE_NICE
6850 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
6851 #endif /* HAVE_NICE */
6852 #ifdef HAVE_READLINK
6853 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
6854 #endif /* HAVE_READLINK */
6855 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6856 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6857 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
6858 //{"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
6859 #ifdef HAVE_SYMLINK
6860 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
6861 #endif /* HAVE_SYMLINK */
6862 #ifdef HAVE_SYSTEM
6863 {"system", posix_system, METH_VARARGS, posix_system__doc__},
6864 #endif
6865 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
6866 #ifdef HAVE_UNAME
6867 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
6868 #endif /* HAVE_UNAME */
6869 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6870 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6871 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
6872 #ifdef HAVE_TIMES
6873 {"times", posix_times, METH_NOARGS, posix_times__doc__},
6874 #endif /* HAVE_TIMES */
6875 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
6876 #ifdef HAVE_EXECV
6877 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6878 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
6879 #endif /* HAVE_EXECV */
6880 #ifdef HAVE_SPAWNV
6881 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6882 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
6883 #if defined(PYOS_OS2)
6884 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
6885 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
6886 #endif /* PYOS_OS2 */
6887 #endif /* HAVE_SPAWNV */
6888 #ifdef HAVE_FORK1
6889 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
6890 #endif /* HAVE_FORK1 */
6891 #ifdef HAVE_FORK
6892 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
6893 #endif /* HAVE_FORK */
6894 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
6895 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
6896 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
6897 #ifdef HAVE_FORKPTY
6898 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
6899 #endif /* HAVE_FORKPTY */
6900 #ifdef HAVE_GETEGID
6901 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
6902 #endif /* HAVE_GETEGID */
6903 #ifdef HAVE_GETEUID
6904 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
6905 #endif /* HAVE_GETEUID */
6906 #ifdef HAVE_GETGID
6907 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
6908 #endif /* HAVE_GETGID */
6909 #ifdef HAVE_GETGROUPS
6910 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
6911 #endif
6912 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
6913 #ifdef HAVE_GETPGRP
6914 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
6915 #endif /* HAVE_GETPGRP */
6916 #ifdef HAVE_GETPPID
6917 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
6918 #endif /* HAVE_GETPPID */
6919 #ifdef HAVE_GETUID
6920 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
6921 #endif /* HAVE_GETUID */
6922 #ifdef HAVE_GETLOGIN
6923 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
6924 #endif
6925 #ifdef HAVE_KILL
6926 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
6927 #endif /* HAVE_KILL */
6928 #ifdef HAVE_KILLPG
6929 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6930 #endif /* HAVE_KILLPG */
6931 #ifdef HAVE_PLOCK
6932 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
6933 #endif /* HAVE_PLOCK */
6934 #ifdef HAVE_POPEN
6935 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
6936 #ifdef MS_WINDOWS
6937 {"popen2", win32_popen2, METH_VARARGS},
6938 {"popen3", win32_popen3, METH_VARARGS},
6939 {"popen4", win32_popen4, METH_VARARGS},
6940 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
6941 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
6942 #else
6943 #if defined(PYOS_OS2) && defined(PYCC_GCC)
6944 {"popen2", os2emx_popen2, METH_VARARGS},
6945 {"popen3", os2emx_popen3, METH_VARARGS},
6946 {"popen4", os2emx_popen4, METH_VARARGS},
6947 #endif
6948 #endif
6949 #endif /* HAVE_POPEN */
6950 #ifdef HAVE_SETUID
6951 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
6952 #endif /* HAVE_SETUID */
6953 #ifdef HAVE_SETEUID
6954 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6955 #endif /* HAVE_SETEUID */
6956 #ifdef HAVE_SETEGID
6957 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6958 #endif /* HAVE_SETEGID */
6959 #ifdef HAVE_SETREUID
6960 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6961 #endif /* HAVE_SETREUID */
6962 #ifdef HAVE_SETREGID
6963 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6964 #endif /* HAVE_SETREGID */
6965 #ifdef HAVE_SETGID
6966 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
6967 #endif /* HAVE_SETGID */
6968 #ifdef HAVE_SETGROUPS
6969 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
6970 #endif /* HAVE_SETGROUPS */
6971 #ifdef HAVE_INITGROUPS
6972 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
6973 #endif /* HAVE_INITGROUPS */
6974 #ifdef HAVE_GETPGID
6975 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6976 #endif /* HAVE_GETPGID */
6977 #ifdef HAVE_SETPGRP
6978 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
6979 #endif /* HAVE_SETPGRP */
6980 #ifdef HAVE_WAIT
6981 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
6982 #endif /* HAVE_WAIT */
6983 #ifdef HAVE_WAIT3
6984 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
6985 #endif /* HAVE_WAIT3 */
6986 #ifdef HAVE_WAIT4
6987 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
6988 #endif /* HAVE_WAIT4 */
6989 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
6990 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
6991 #endif /* HAVE_WAITPID */
6992 #ifdef HAVE_GETSID
6993 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
6994 #endif /* HAVE_GETSID */
6995 #ifdef HAVE_SETSID
6996 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
6997 #endif /* HAVE_SETSID */
6998 #ifdef HAVE_SETPGID
6999 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
7000 #endif /* HAVE_SETPGID */
7001 #ifdef HAVE_TCGETPGRP
7002 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
7003 #endif /* HAVE_TCGETPGRP */
7004 #ifdef HAVE_TCSETPGRP
7005 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
7006 #endif /* HAVE_TCSETPGRP */
7007 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7008 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7009 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
7010 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7011 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7012 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7013 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7014 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7015 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7016 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
7017 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
7018 #ifdef HAVE_PIPE
7019 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
7020 #endif
7021 #ifdef HAVE_MKFIFO
7022 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
7023 #endif
7024 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
7025 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7026 #endif
7027 #ifdef HAVE_DEVICE_MACROS
7028 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7029 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7030 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7031 #endif
7032 #ifdef HAVE_FTRUNCATE
7033 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
7034 #endif
7035 #ifdef HAVE_PUTENV
7036 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
7037 #endif
7038 #ifdef HAVE_UNSETENV
7039 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7040 #endif
7041 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
7042 #ifdef HAVE_FCHDIR
7043 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7044 #endif
7045 #ifdef HAVE_FSYNC
7046 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
7047 #endif
7048 #ifdef HAVE_FDATASYNC
7049 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
7050 #endif
7051 #ifdef HAVE_SYS_WAIT_H
7052 #ifdef WCOREDUMP
7053 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7054 #endif /* WCOREDUMP */
7055 #ifdef WIFCONTINUED
7056 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7057 #endif /* WIFCONTINUED */
7058 #ifdef WIFSTOPPED
7059 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
7060 #endif /* WIFSTOPPED */
7061 #ifdef WIFSIGNALED
7062 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
7063 #endif /* WIFSIGNALED */
7064 #ifdef WIFEXITED
7065 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
7066 #endif /* WIFEXITED */
7067 #ifdef WEXITSTATUS
7068 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
7069 #endif /* WEXITSTATUS */
7070 #ifdef WTERMSIG
7071 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
7072 #endif /* WTERMSIG */
7073 #ifdef WSTOPSIG
7074 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
7075 #endif /* WSTOPSIG */
7076 #endif /* HAVE_SYS_WAIT_H */
7077 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
7078 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
7079 #endif
7080 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
7081 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
7082 #endif
7083 #ifdef HAVE_TMPFILE
7084 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
7085 #endif
7086 #ifdef HAVE_TEMPNAM
7087 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7088 #endif
7089 #ifdef HAVE_TMPNAM
7090 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
7091 #endif
7092 #ifdef HAVE_CONFSTR
7093 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7094 #endif
7095 #ifdef HAVE_SYSCONF
7096 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7097 #endif
7098 #ifdef HAVE_FPATHCONF
7099 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7100 #endif
7101 #ifdef HAVE_PATHCONF
7102 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7103 #endif
7104 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
7105 #ifdef HAVE_SETRESUID
7106 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
7107 #endif
7108 #ifdef HAVE_SETRESGID
7109 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
7110 #endif
7111 #ifdef HAVE_GETRESUID
7112 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
7113 #endif
7114 #ifdef HAVE_GETRESGID
7115 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
7116 #endif
7117
7118 {NULL, NULL} /* Sentinel */
7119 };
7120
7121
7122 static int
ins(PyObject * module,char * symbol,long value)7123 ins(PyObject *module, char *symbol, long value)
7124 {
7125 return PyModule_AddIntConstant(module, symbol, value);
7126 }
7127
7128 static int
all_ins(PyObject * d)7129 all_ins(PyObject *d)
7130 {
7131 #ifdef F_OK
7132 if (ins(d, "F_OK", (long)F_OK)) return -1;
7133 #endif
7134 #ifdef R_OK
7135 if (ins(d, "R_OK", (long)R_OK)) return -1;
7136 #endif
7137 #ifdef W_OK
7138 if (ins(d, "W_OK", (long)W_OK)) return -1;
7139 #endif
7140 #ifdef X_OK
7141 if (ins(d, "X_OK", (long)X_OK)) return -1;
7142 #endif
7143 #ifdef NGROUPS_MAX
7144 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7145 #endif
7146 #ifdef TMP_MAX
7147 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7148 #endif
7149 #ifdef WCONTINUED
7150 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7151 #endif
7152 #ifdef WNOHANG
7153 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
7154 #endif
7155 #ifdef WUNTRACED
7156 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7157 #endif
7158 #ifdef O_RDONLY
7159 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7160 #endif
7161 #ifdef O_WRONLY
7162 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7163 #endif
7164 #ifdef O_RDWR
7165 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7166 #endif
7167 #ifdef O_NDELAY
7168 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7169 #endif
7170 #ifdef O_NONBLOCK
7171 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7172 #endif
7173 #ifdef O_APPEND
7174 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7175 #endif
7176 #ifdef O_DSYNC
7177 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7178 #endif
7179 #ifdef O_RSYNC
7180 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7181 #endif
7182 #ifdef O_SYNC
7183 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7184 #endif
7185 #ifdef O_NOCTTY
7186 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7187 #endif
7188 #ifdef O_CREAT
7189 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7190 #endif
7191 #ifdef O_EXCL
7192 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7193 #endif
7194 #ifdef O_TRUNC
7195 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7196 #endif
7197 #ifdef O_BINARY
7198 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7199 #endif
7200 #ifdef O_TEXT
7201 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7202 #endif
7203 #ifdef O_LARGEFILE
7204 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7205 #endif
7206 #ifdef O_SHLOCK
7207 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7208 #endif
7209 #ifdef O_EXLOCK
7210 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7211 #endif
7212
7213 /* MS Windows */
7214 #ifdef O_NOINHERIT
7215 /* Don't inherit in child processes. */
7216 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7217 #endif
7218 #ifdef _O_SHORT_LIVED
7219 /* Optimize for short life (keep in memory). */
7220 /* MS forgot to define this one with a non-underscore form too. */
7221 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7222 #endif
7223 #ifdef O_TEMPORARY
7224 /* Automatically delete when last handle is closed. */
7225 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7226 #endif
7227 #ifdef O_RANDOM
7228 /* Optimize for random access. */
7229 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7230 #endif
7231 #ifdef O_SEQUENTIAL
7232 /* Optimize for sequential access. */
7233 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7234 #endif
7235
7236 /* GNU extensions. */
7237 #ifdef O_ASYNC
7238 /* Send a SIGIO signal whenever input or output
7239 becomes available on file descriptor */
7240 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
7241 #endif
7242 #ifdef O_DIRECT
7243 /* Direct disk access. */
7244 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7245 #endif
7246 #ifdef O_DIRECTORY
7247 /* Must be a directory. */
7248 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7249 #endif
7250 #ifdef O_NOFOLLOW
7251 /* Do not follow links. */
7252 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7253 #endif
7254 #ifdef O_NOATIME
7255 /* Do not update the access time. */
7256 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
7257 #endif
7258
7259 /* These come from sysexits.h */
7260 #ifdef EX_OK
7261 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
7262 #endif /* EX_OK */
7263 #ifdef EX_USAGE
7264 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
7265 #endif /* EX_USAGE */
7266 #ifdef EX_DATAERR
7267 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
7268 #endif /* EX_DATAERR */
7269 #ifdef EX_NOINPUT
7270 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
7271 #endif /* EX_NOINPUT */
7272 #ifdef EX_NOUSER
7273 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
7274 #endif /* EX_NOUSER */
7275 #ifdef EX_NOHOST
7276 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
7277 #endif /* EX_NOHOST */
7278 #ifdef EX_UNAVAILABLE
7279 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
7280 #endif /* EX_UNAVAILABLE */
7281 #ifdef EX_SOFTWARE
7282 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
7283 #endif /* EX_SOFTWARE */
7284 #ifdef EX_OSERR
7285 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
7286 #endif /* EX_OSERR */
7287 #ifdef EX_OSFILE
7288 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
7289 #endif /* EX_OSFILE */
7290 #ifdef EX_CANTCREAT
7291 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
7292 #endif /* EX_CANTCREAT */
7293 #ifdef EX_IOERR
7294 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
7295 #endif /* EX_IOERR */
7296 #ifdef EX_TEMPFAIL
7297 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
7298 #endif /* EX_TEMPFAIL */
7299 #ifdef EX_PROTOCOL
7300 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
7301 #endif /* EX_PROTOCOL */
7302 #ifdef EX_NOPERM
7303 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
7304 #endif /* EX_NOPERM */
7305 #ifdef EX_CONFIG
7306 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
7307 #endif /* EX_CONFIG */
7308 #ifdef EX_NOTFOUND
7309 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
7310 #endif /* EX_NOTFOUND */
7311
7312 #ifdef HAVE_SPAWNV
7313 #if defined(PYOS_OS2) && defined(PYCC_GCC)
7314 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7315 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7316 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7317 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7318 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7319 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7320 if (ins(d, "P_PM", (long)P_PM)) return -1;
7321 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7322 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7323 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7324 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7325 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7326 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7327 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7328 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7329 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7330 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7331 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7332 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7333 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7334 #else
7335 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7336 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7337 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7338 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7339 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
7340 #endif
7341 #endif
7342 return 0;
7343 }
7344
7345 #define INITFUNC initedk2
7346 #define MODNAME "edk2"
7347
7348 PyMODINIT_FUNC
INITFUNC(void)7349 INITFUNC(void)
7350 {
7351 PyObject *m;
7352
7353 #ifndef UEFI_C_SOURCE
7354 PyObject *v;
7355 #endif
7356
7357 m = Py_InitModule3(MODNAME,
7358 posix_methods,
7359 edk2__doc__);
7360 if (m == NULL)
7361 return;
7362
7363 #ifndef UEFI_C_SOURCE
7364 /* Initialize environ dictionary */
7365 v = convertenviron();
7366 Py_XINCREF(v);
7367 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
7368 return;
7369 Py_DECREF(v);
7370 #endif /* UEFI_C_SOURCE */
7371
7372 if (all_ins(m))
7373 return;
7374
7375 if (setup_confname_tables(m))
7376 return;
7377
7378 Py_INCREF(PyExc_OSError);
7379 PyModule_AddObject(m, "error", PyExc_OSError);
7380
7381 #ifdef HAVE_PUTENV
7382 if (posix_putenv_garbage == NULL)
7383 posix_putenv_garbage = PyDict_New();
7384 #endif
7385
7386 if (!initialized) {
7387 stat_result_desc.name = MODNAME ".stat_result";
7388 stat_result_desc.fields[2].name = PyStructSequence_UnnamedField;
7389 stat_result_desc.fields[3].name = PyStructSequence_UnnamedField;
7390 stat_result_desc.fields[4].name = PyStructSequence_UnnamedField;
7391 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7392 structseq_new = StatResultType.tp_new;
7393 StatResultType.tp_new = statresult_new;
7394
7395 //statvfs_result_desc.name = MODNAME ".statvfs_result";
7396 //PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
7397 #ifdef NEED_TICKS_PER_SECOND
7398 # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
7399 ticks_per_second = sysconf(_SC_CLK_TCK);
7400 # elif defined(HZ)
7401 ticks_per_second = HZ;
7402 # else
7403 ticks_per_second = 60; /* magic fallback value; may be bogus */
7404 # endif
7405 #endif
7406 }
7407 Py_INCREF((PyObject*) &StatResultType);
7408 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
7409 //Py_INCREF((PyObject*) &StatVFSResultType);
7410 //PyModule_AddObject(m, "statvfs_result",
7411 // (PyObject*) &StatVFSResultType);
7412 initialized = 1;
7413
7414 }
7415
7416 #ifdef __cplusplus
7417 }
7418 #endif
7419
7420
7421