]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/edk2module.c
AppPkg/.../Python-2.7.10: Remove irrelevant conditional code from edk2module.c.
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / PyMod-2.7.10 / Modules / edk2module.c
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 *
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 *
204 posix_error(void)
205 {
206 return PyErr_SetFromErrno(PyExc_OSError);
207 }
208 static PyObject *
209 posix_error_with_filename(char* name)
210 {
211 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
212 }
213
214
215 static PyObject *
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 *
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 *
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 *
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 *
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*
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
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*
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 PyDoc_STRVAR(posix_mkdir__doc__,
1064 "mkdir(path [, mode=0777])\n\n\
1065 Create a directory.");
1066
1067 static PyObject *
1068 posix_mkdir(PyObject *self, PyObject *args)
1069 {
1070 int res;
1071 char *path = NULL;
1072 int mode = 0777;
1073
1074 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1075 Py_FileSystemDefaultEncoding, &path, &mode))
1076 return NULL;
1077 Py_BEGIN_ALLOW_THREADS
1078 res = mkdir(path, mode);
1079 Py_END_ALLOW_THREADS
1080 if (res < 0)
1081 return posix_error_with_allocated_filename(path);
1082 PyMem_Free(path);
1083 Py_INCREF(Py_None);
1084 return Py_None;
1085 }
1086
1087
1088 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
1089 #if defined(HAVE_SYS_RESOURCE_H)
1090 #include <sys/resource.h>
1091 #endif
1092
1093
1094 #ifdef HAVE_NICE
1095 PyDoc_STRVAR(posix_nice__doc__,
1096 "nice(inc) -> new_priority\n\n\
1097 Decrease the priority of process by inc and return the new priority.");
1098
1099 static PyObject *
1100 posix_nice(PyObject *self, PyObject *args)
1101 {
1102 int increment, value;
1103
1104 if (!PyArg_ParseTuple(args, "i:nice", &increment))
1105 return NULL;
1106
1107 /* There are two flavours of 'nice': one that returns the new
1108 priority (as required by almost all standards out there) and the
1109 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1110 the use of getpriority() to get the new priority.
1111
1112 If we are of the nice family that returns the new priority, we
1113 need to clear errno before the call, and check if errno is filled
1114 before calling posix_error() on a returnvalue of -1, because the
1115 -1 may be the actual new priority! */
1116
1117 errno = 0;
1118 value = nice(increment);
1119 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
1120 if (value == 0)
1121 value = getpriority(PRIO_PROCESS, 0);
1122 #endif
1123 if (value == -1 && errno != 0)
1124 /* either nice() or getpriority() returned an error */
1125 return posix_error();
1126 return PyInt_FromLong((long) value);
1127 }
1128 #endif /* HAVE_NICE */
1129
1130 PyDoc_STRVAR(posix_rename__doc__,
1131 "rename(old, new)\n\n\
1132 Rename a file or directory.");
1133
1134 static PyObject *
1135 posix_rename(PyObject *self, PyObject *args)
1136 {
1137 return posix_2str(args, "etet:rename", rename);
1138 }
1139
1140
1141 PyDoc_STRVAR(posix_rmdir__doc__,
1142 "rmdir(path)\n\n\
1143 Remove a directory.");
1144
1145 static PyObject *
1146 posix_rmdir(PyObject *self, PyObject *args)
1147 {
1148 return posix_1str(args, "et:rmdir", rmdir);
1149 }
1150
1151
1152 PyDoc_STRVAR(posix_stat__doc__,
1153 "stat(path) -> stat result\n\n\
1154 Perform a stat system call on the given path.");
1155
1156 static PyObject *
1157 posix_stat(PyObject *self, PyObject *args)
1158 {
1159 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1160 }
1161
1162
1163 #ifdef HAVE_SYSTEM
1164 PyDoc_STRVAR(posix_system__doc__,
1165 "system(command) -> exit_status\n\n\
1166 Execute the command (a string) in a subshell.");
1167
1168 static PyObject *
1169 posix_system(PyObject *self, PyObject *args)
1170 {
1171 char *command;
1172 long sts;
1173 if (!PyArg_ParseTuple(args, "s:system", &command))
1174 return NULL;
1175 Py_BEGIN_ALLOW_THREADS
1176 sts = system(command);
1177 Py_END_ALLOW_THREADS
1178 return PyInt_FromLong(sts);
1179 }
1180 #endif
1181
1182
1183 PyDoc_STRVAR(posix_umask__doc__,
1184 "umask(new_mask) -> old_mask\n\n\
1185 Set the current numeric umask and return the previous umask.");
1186
1187 static PyObject *
1188 posix_umask(PyObject *self, PyObject *args)
1189 {
1190 int i;
1191 if (!PyArg_ParseTuple(args, "i:umask", &i))
1192 return NULL;
1193 i = (int)umask(i);
1194 if (i < 0)
1195 return posix_error();
1196 return PyInt_FromLong((long)i);
1197 }
1198
1199
1200 PyDoc_STRVAR(posix_unlink__doc__,
1201 "unlink(path)\n\n\
1202 Remove a file (same as remove(path)).");
1203
1204 PyDoc_STRVAR(posix_remove__doc__,
1205 "remove(path)\n\n\
1206 Remove a file (same as unlink(path)).");
1207
1208 static PyObject *
1209 posix_unlink(PyObject *self, PyObject *args)
1210 {
1211 return posix_1str(args, "et:remove", unlink);
1212 }
1213
1214
1215 static int
1216 extract_time(PyObject *t, time_t* sec, long* usec)
1217 {
1218 time_t intval;
1219 if (PyFloat_Check(t)) {
1220 double tval = PyFloat_AsDouble(t);
1221 PyObject *intobj = PyNumber_Long(t);
1222 if (!intobj)
1223 return -1;
1224 #if SIZEOF_TIME_T > SIZEOF_LONG
1225 intval = PyInt_AsUnsignedLongLongMask(intobj);
1226 #else
1227 intval = PyInt_AsLong(intobj);
1228 #endif
1229 Py_DECREF(intobj);
1230 if (intval == -1 && PyErr_Occurred())
1231 return -1;
1232 *sec = intval;
1233 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
1234 if (*usec < 0)
1235 /* If rounding gave us a negative number,
1236 truncate. */
1237 *usec = 0;
1238 return 0;
1239 }
1240 #if SIZEOF_TIME_T > SIZEOF_LONG
1241 intval = PyInt_AsUnsignedLongLongMask(t);
1242 #else
1243 intval = PyInt_AsLong(t);
1244 #endif
1245 if (intval == -1 && PyErr_Occurred())
1246 return -1;
1247 *sec = intval;
1248 *usec = 0;
1249 return 0;
1250 }
1251
1252 PyDoc_STRVAR(posix_utime__doc__,
1253 "utime(path, (atime, mtime))\n\
1254 utime(path, None)\n\n\
1255 Set the access and modified time of the file to the given values. If the\n\
1256 second form is used, set the access and modified times to the current time.");
1257
1258 static PyObject *
1259 posix_utime(PyObject *self, PyObject *args)
1260 {
1261 char *path = NULL;
1262 time_t atime, mtime;
1263 long ausec, musec;
1264 int res;
1265 PyObject* arg;
1266
1267 #if defined(HAVE_UTIMES)
1268 struct timeval buf[2];
1269 #define ATIME buf[0].tv_sec
1270 #define MTIME buf[1].tv_sec
1271 #elif defined(HAVE_UTIME_H)
1272 /* XXX should define struct utimbuf instead, above */
1273 struct utimbuf buf;
1274 #define ATIME buf.actime
1275 #define MTIME buf.modtime
1276 #define UTIME_ARG &buf
1277 #else /* HAVE_UTIMES */
1278 time_t buf[2];
1279 #define ATIME buf[0]
1280 #define MTIME buf[1]
1281 #define UTIME_ARG buf
1282 #endif /* HAVE_UTIMES */
1283
1284
1285 if (!PyArg_ParseTuple(args, "etO:utime",
1286 Py_FileSystemDefaultEncoding, &path, &arg))
1287 return NULL;
1288 if (arg == Py_None) {
1289 /* optional time values not given */
1290 Py_BEGIN_ALLOW_THREADS
1291 res = utime(path, NULL);
1292 Py_END_ALLOW_THREADS
1293 }
1294 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
1295 PyErr_SetString(PyExc_TypeError,
1296 "utime() arg 2 must be a tuple (atime, mtime)");
1297 PyMem_Free(path);
1298 return NULL;
1299 }
1300 else {
1301 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1302 &atime, &ausec) == -1) {
1303 PyMem_Free(path);
1304 return NULL;
1305 }
1306 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1307 &mtime, &musec) == -1) {
1308 PyMem_Free(path);
1309 return NULL;
1310 }
1311 ATIME = atime;
1312 MTIME = mtime;
1313 #ifdef HAVE_UTIMES
1314 buf[0].tv_usec = ausec;
1315 buf[1].tv_usec = musec;
1316 Py_BEGIN_ALLOW_THREADS
1317 res = utimes(path, buf);
1318 Py_END_ALLOW_THREADS
1319 #else
1320 Py_BEGIN_ALLOW_THREADS
1321 res = utime(path, UTIME_ARG);
1322 Py_END_ALLOW_THREADS
1323 #endif /* HAVE_UTIMES */
1324 }
1325 if (res < 0) {
1326 return posix_error_with_allocated_filename(path);
1327 }
1328 PyMem_Free(path);
1329 Py_INCREF(Py_None);
1330 return Py_None;
1331 #undef UTIME_ARG
1332 #undef ATIME
1333 #undef MTIME
1334 }
1335
1336
1337 /* Process operations */
1338
1339 PyDoc_STRVAR(posix__exit__doc__,
1340 "_exit(status)\n\n\
1341 Exit to the system with specified status, without normal exit processing.");
1342
1343 static PyObject *
1344 posix__exit(PyObject *self, PyObject *args)
1345 {
1346 int sts;
1347 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
1348 return NULL;
1349 _Exit(sts);
1350 return NULL; /* Make gcc -Wall happy */
1351 }
1352
1353 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
1354 static void
1355 free_string_array(char **array, Py_ssize_t count)
1356 {
1357 Py_ssize_t i;
1358 for (i = 0; i < count; i++)
1359 PyMem_Free(array[i]);
1360 PyMem_DEL(array);
1361 }
1362 #endif
1363
1364
1365 #ifdef HAVE_EXECV
1366 PyDoc_STRVAR(posix_execv__doc__,
1367 "execv(path, args)\n\n\
1368 Execute an executable path with arguments, replacing current process.\n\
1369 \n\
1370 path: path of executable file\n\
1371 args: tuple or list of strings");
1372
1373 static PyObject *
1374 posix_execv(PyObject *self, PyObject *args)
1375 {
1376 char *path;
1377 PyObject *argv;
1378 char **argvlist;
1379 Py_ssize_t i, argc;
1380 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1381
1382 /* execv has two arguments: (path, argv), where
1383 argv is a list or tuple of strings. */
1384
1385 if (!PyArg_ParseTuple(args, "etO:execv",
1386 Py_FileSystemDefaultEncoding,
1387 &path, &argv))
1388 return NULL;
1389 if (PyList_Check(argv)) {
1390 argc = PyList_Size(argv);
1391 getitem = PyList_GetItem;
1392 }
1393 else if (PyTuple_Check(argv)) {
1394 argc = PyTuple_Size(argv);
1395 getitem = PyTuple_GetItem;
1396 }
1397 else {
1398 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
1399 PyMem_Free(path);
1400 return NULL;
1401 }
1402 if (argc < 1) {
1403 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
1404 PyMem_Free(path);
1405 return NULL;
1406 }
1407
1408 argvlist = PyMem_NEW(char *, argc+1);
1409 if (argvlist == NULL) {
1410 PyMem_Free(path);
1411 return PyErr_NoMemory();
1412 }
1413 for (i = 0; i < argc; i++) {
1414 if (!PyArg_Parse((*getitem)(argv, i), "et",
1415 Py_FileSystemDefaultEncoding,
1416 &argvlist[i])) {
1417 free_string_array(argvlist, i);
1418 PyErr_SetString(PyExc_TypeError,
1419 "execv() arg 2 must contain only strings");
1420 PyMem_Free(path);
1421 return NULL;
1422
1423 }
1424 }
1425 argvlist[argc] = NULL;
1426
1427 execv(path, argvlist);
1428
1429 /* If we get here it's definitely an error */
1430
1431 free_string_array(argvlist, argc);
1432 PyMem_Free(path);
1433 return posix_error();
1434 }
1435
1436
1437 PyDoc_STRVAR(posix_execve__doc__,
1438 "execve(path, args, env)\n\n\
1439 Execute a path with arguments and environment, replacing current process.\n\
1440 \n\
1441 path: path of executable file\n\
1442 args: tuple or list of arguments\n\
1443 env: dictionary of strings mapping to strings");
1444
1445 static PyObject *
1446 posix_execve(PyObject *self, PyObject *args)
1447 {
1448 char *path;
1449 PyObject *argv, *env;
1450 char **argvlist;
1451 char **envlist;
1452 PyObject *key, *val, *keys=NULL, *vals=NULL;
1453 Py_ssize_t i, pos, argc, envc;
1454 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1455 Py_ssize_t lastarg = 0;
1456
1457 /* execve has three arguments: (path, argv, env), where
1458 argv is a list or tuple of strings and env is a dictionary
1459 like posix.environ. */
1460
1461 if (!PyArg_ParseTuple(args, "etOO:execve",
1462 Py_FileSystemDefaultEncoding,
1463 &path, &argv, &env))
1464 return NULL;
1465 if (PyList_Check(argv)) {
1466 argc = PyList_Size(argv);
1467 getitem = PyList_GetItem;
1468 }
1469 else if (PyTuple_Check(argv)) {
1470 argc = PyTuple_Size(argv);
1471 getitem = PyTuple_GetItem;
1472 }
1473 else {
1474 PyErr_SetString(PyExc_TypeError,
1475 "execve() arg 2 must be a tuple or list");
1476 goto fail_0;
1477 }
1478 if (!PyMapping_Check(env)) {
1479 PyErr_SetString(PyExc_TypeError,
1480 "execve() arg 3 must be a mapping object");
1481 goto fail_0;
1482 }
1483
1484 argvlist = PyMem_NEW(char *, argc+1);
1485 if (argvlist == NULL) {
1486 PyErr_NoMemory();
1487 goto fail_0;
1488 }
1489 for (i = 0; i < argc; i++) {
1490 if (!PyArg_Parse((*getitem)(argv, i),
1491 "et;execve() arg 2 must contain only strings",
1492 Py_FileSystemDefaultEncoding,
1493 &argvlist[i]))
1494 {
1495 lastarg = i;
1496 goto fail_1;
1497 }
1498 }
1499 lastarg = argc;
1500 argvlist[argc] = NULL;
1501
1502 i = PyMapping_Size(env);
1503 if (i < 0)
1504 goto fail_1;
1505 envlist = PyMem_NEW(char *, i + 1);
1506 if (envlist == NULL) {
1507 PyErr_NoMemory();
1508 goto fail_1;
1509 }
1510 envc = 0;
1511 keys = PyMapping_Keys(env);
1512 vals = PyMapping_Values(env);
1513 if (!keys || !vals)
1514 goto fail_2;
1515 if (!PyList_Check(keys) || !PyList_Check(vals)) {
1516 PyErr_SetString(PyExc_TypeError,
1517 "execve(): env.keys() or env.values() is not a list");
1518 goto fail_2;
1519 }
1520
1521 for (pos = 0; pos < i; pos++) {
1522 char *p, *k, *v;
1523 size_t len;
1524
1525 key = PyList_GetItem(keys, pos);
1526 val = PyList_GetItem(vals, pos);
1527 if (!key || !val)
1528 goto fail_2;
1529
1530 if (!PyArg_Parse(
1531 key,
1532 "s;execve() arg 3 contains a non-string key",
1533 &k) ||
1534 !PyArg_Parse(
1535 val,
1536 "s;execve() arg 3 contains a non-string value",
1537 &v))
1538 {
1539 goto fail_2;
1540 }
1541
1542 #if defined(PYOS_OS2)
1543 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1544 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1545 #endif
1546 len = PyString_Size(key) + PyString_Size(val) + 2;
1547 p = PyMem_NEW(char, len);
1548 if (p == NULL) {
1549 PyErr_NoMemory();
1550 goto fail_2;
1551 }
1552 PyOS_snprintf(p, len, "%s=%s", k, v);
1553 envlist[envc++] = p;
1554 #if defined(PYOS_OS2)
1555 }
1556 #endif
1557 }
1558 envlist[envc] = 0;
1559
1560 execve(path, argvlist, envlist);
1561
1562 /* If we get here it's definitely an error */
1563
1564 (void) posix_error();
1565
1566 fail_2:
1567 while (--envc >= 0)
1568 PyMem_DEL(envlist[envc]);
1569 PyMem_DEL(envlist);
1570 fail_1:
1571 free_string_array(argvlist, lastarg);
1572 Py_XDECREF(vals);
1573 Py_XDECREF(keys);
1574 fail_0:
1575 PyMem_Free(path);
1576 return NULL;
1577 }
1578 #endif /* HAVE_EXECV */
1579
1580
1581 #ifdef HAVE_SPAWNV
1582 PyDoc_STRVAR(posix_spawnv__doc__,
1583 "spawnv(mode, path, args)\n\n\
1584 Execute the program 'path' in a new process.\n\
1585 \n\
1586 mode: mode of process creation\n\
1587 path: path of executable file\n\
1588 args: tuple or list of strings");
1589
1590 static PyObject *
1591 posix_spawnv(PyObject *self, PyObject *args)
1592 {
1593 char *path;
1594 PyObject *argv;
1595 char **argvlist;
1596 int mode, i;
1597 Py_ssize_t argc;
1598 Py_intptr_t spawnval;
1599 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1600
1601 /* spawnv has three arguments: (mode, path, argv), where
1602 argv is a list or tuple of strings. */
1603
1604 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
1605 Py_FileSystemDefaultEncoding,
1606 &path, &argv))
1607 return NULL;
1608 if (PyList_Check(argv)) {
1609 argc = PyList_Size(argv);
1610 getitem = PyList_GetItem;
1611 }
1612 else if (PyTuple_Check(argv)) {
1613 argc = PyTuple_Size(argv);
1614 getitem = PyTuple_GetItem;
1615 }
1616 else {
1617 PyErr_SetString(PyExc_TypeError,
1618 "spawnv() arg 2 must be a tuple or list");
1619 PyMem_Free(path);
1620 return NULL;
1621 }
1622
1623 argvlist = PyMem_NEW(char *, argc+1);
1624 if (argvlist == NULL) {
1625 PyMem_Free(path);
1626 return PyErr_NoMemory();
1627 }
1628 for (i = 0; i < argc; i++) {
1629 if (!PyArg_Parse((*getitem)(argv, i), "et",
1630 Py_FileSystemDefaultEncoding,
1631 &argvlist[i])) {
1632 free_string_array(argvlist, i);
1633 PyErr_SetString(
1634 PyExc_TypeError,
1635 "spawnv() arg 2 must contain only strings");
1636 PyMem_Free(path);
1637 return NULL;
1638 }
1639 }
1640 argvlist[argc] = NULL;
1641
1642 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1643 Py_BEGIN_ALLOW_THREADS
1644 spawnval = spawnv(mode, path, argvlist);
1645 Py_END_ALLOW_THREADS
1646 #else
1647 if (mode == _OLD_P_OVERLAY)
1648 mode = _P_OVERLAY;
1649
1650 Py_BEGIN_ALLOW_THREADS
1651 spawnval = _spawnv(mode, path, argvlist);
1652 Py_END_ALLOW_THREADS
1653 #endif
1654
1655 free_string_array(argvlist, argc);
1656 PyMem_Free(path);
1657
1658 if (spawnval == -1)
1659 return posix_error();
1660 else
1661 #if SIZEOF_LONG == SIZEOF_VOID_P
1662 return Py_BuildValue("l", (long) spawnval);
1663 #else
1664 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
1665 #endif
1666 }
1667
1668
1669 PyDoc_STRVAR(posix_spawnve__doc__,
1670 "spawnve(mode, path, args, env)\n\n\
1671 Execute the program 'path' in a new process.\n\
1672 \n\
1673 mode: mode of process creation\n\
1674 path: path of executable file\n\
1675 args: tuple or list of arguments\n\
1676 env: dictionary of strings mapping to strings");
1677
1678 static PyObject *
1679 posix_spawnve(PyObject *self, PyObject *args)
1680 {
1681 char *path;
1682 PyObject *argv, *env;
1683 char **argvlist;
1684 char **envlist;
1685 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1686 int mode, pos, envc;
1687 Py_ssize_t argc, i;
1688 Py_intptr_t spawnval;
1689 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1690 Py_ssize_t lastarg = 0;
1691
1692 /* spawnve has four arguments: (mode, path, argv, env), where
1693 argv is a list or tuple of strings and env is a dictionary
1694 like posix.environ. */
1695
1696 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
1697 Py_FileSystemDefaultEncoding,
1698 &path, &argv, &env))
1699 return NULL;
1700 if (PyList_Check(argv)) {
1701 argc = PyList_Size(argv);
1702 getitem = PyList_GetItem;
1703 }
1704 else if (PyTuple_Check(argv)) {
1705 argc = PyTuple_Size(argv);
1706 getitem = PyTuple_GetItem;
1707 }
1708 else {
1709 PyErr_SetString(PyExc_TypeError,
1710 "spawnve() arg 2 must be a tuple or list");
1711 goto fail_0;
1712 }
1713 if (!PyMapping_Check(env)) {
1714 PyErr_SetString(PyExc_TypeError,
1715 "spawnve() arg 3 must be a mapping object");
1716 goto fail_0;
1717 }
1718
1719 argvlist = PyMem_NEW(char *, argc+1);
1720 if (argvlist == NULL) {
1721 PyErr_NoMemory();
1722 goto fail_0;
1723 }
1724 for (i = 0; i < argc; i++) {
1725 if (!PyArg_Parse((*getitem)(argv, i),
1726 "et;spawnve() arg 2 must contain only strings",
1727 Py_FileSystemDefaultEncoding,
1728 &argvlist[i]))
1729 {
1730 lastarg = i;
1731 goto fail_1;
1732 }
1733 }
1734 lastarg = argc;
1735 argvlist[argc] = NULL;
1736
1737 i = PyMapping_Size(env);
1738 if (i < 0)
1739 goto fail_1;
1740 envlist = PyMem_NEW(char *, i + 1);
1741 if (envlist == NULL) {
1742 PyErr_NoMemory();
1743 goto fail_1;
1744 }
1745 envc = 0;
1746 keys = PyMapping_Keys(env);
1747 vals = PyMapping_Values(env);
1748 if (!keys || !vals)
1749 goto fail_2;
1750 if (!PyList_Check(keys) || !PyList_Check(vals)) {
1751 PyErr_SetString(PyExc_TypeError,
1752 "spawnve(): env.keys() or env.values() is not a list");
1753 goto fail_2;
1754 }
1755
1756 for (pos = 0; pos < i; pos++) {
1757 char *p, *k, *v;
1758 size_t len;
1759
1760 key = PyList_GetItem(keys, pos);
1761 val = PyList_GetItem(vals, pos);
1762 if (!key || !val)
1763 goto fail_2;
1764
1765 if (!PyArg_Parse(
1766 key,
1767 "s;spawnve() arg 3 contains a non-string key",
1768 &k) ||
1769 !PyArg_Parse(
1770 val,
1771 "s;spawnve() arg 3 contains a non-string value",
1772 &v))
1773 {
1774 goto fail_2;
1775 }
1776 len = PyString_Size(key) + PyString_Size(val) + 2;
1777 p = PyMem_NEW(char, len);
1778 if (p == NULL) {
1779 PyErr_NoMemory();
1780 goto fail_2;
1781 }
1782 PyOS_snprintf(p, len, "%s=%s", k, v);
1783 envlist[envc++] = p;
1784 }
1785 envlist[envc] = 0;
1786
1787 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1788 Py_BEGIN_ALLOW_THREADS
1789 spawnval = spawnve(mode, path, argvlist, envlist);
1790 Py_END_ALLOW_THREADS
1791 #else
1792 if (mode == _OLD_P_OVERLAY)
1793 mode = _P_OVERLAY;
1794
1795 Py_BEGIN_ALLOW_THREADS
1796 spawnval = _spawnve(mode, path, argvlist, envlist);
1797 Py_END_ALLOW_THREADS
1798 #endif
1799
1800 if (spawnval == -1)
1801 (void) posix_error();
1802 else
1803 #if SIZEOF_LONG == SIZEOF_VOID_P
1804 res = Py_BuildValue("l", (long) spawnval);
1805 #else
1806 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
1807 #endif
1808
1809 fail_2:
1810 while (--envc >= 0)
1811 PyMem_DEL(envlist[envc]);
1812 PyMem_DEL(envlist);
1813 fail_1:
1814 free_string_array(argvlist, lastarg);
1815 Py_XDECREF(vals);
1816 Py_XDECREF(keys);
1817 fail_0:
1818 PyMem_Free(path);
1819 return res;
1820 }
1821
1822 /* OS/2 supports spawnvp & spawnvpe natively */
1823 #if defined(PYOS_OS2)
1824 PyDoc_STRVAR(posix_spawnvp__doc__,
1825 "spawnvp(mode, file, args)\n\n\
1826 Execute the program 'file' in a new process, using the environment\n\
1827 search path to find the file.\n\
1828 \n\
1829 mode: mode of process creation\n\
1830 file: executable file name\n\
1831 args: tuple or list of strings");
1832
1833 static PyObject *
1834 posix_spawnvp(PyObject *self, PyObject *args)
1835 {
1836 char *path;
1837 PyObject *argv;
1838 char **argvlist;
1839 int mode, i, argc;
1840 Py_intptr_t spawnval;
1841 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1842
1843 /* spawnvp has three arguments: (mode, path, argv), where
1844 argv is a list or tuple of strings. */
1845
1846 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
1847 Py_FileSystemDefaultEncoding,
1848 &path, &argv))
1849 return NULL;
1850 if (PyList_Check(argv)) {
1851 argc = PyList_Size(argv);
1852 getitem = PyList_GetItem;
1853 }
1854 else if (PyTuple_Check(argv)) {
1855 argc = PyTuple_Size(argv);
1856 getitem = PyTuple_GetItem;
1857 }
1858 else {
1859 PyErr_SetString(PyExc_TypeError,
1860 "spawnvp() arg 2 must be a tuple or list");
1861 PyMem_Free(path);
1862 return NULL;
1863 }
1864
1865 argvlist = PyMem_NEW(char *, argc+1);
1866 if (argvlist == NULL) {
1867 PyMem_Free(path);
1868 return PyErr_NoMemory();
1869 }
1870 for (i = 0; i < argc; i++) {
1871 if (!PyArg_Parse((*getitem)(argv, i), "et",
1872 Py_FileSystemDefaultEncoding,
1873 &argvlist[i])) {
1874 free_string_array(argvlist, i);
1875 PyErr_SetString(
1876 PyExc_TypeError,
1877 "spawnvp() arg 2 must contain only strings");
1878 PyMem_Free(path);
1879 return NULL;
1880 }
1881 }
1882 argvlist[argc] = NULL;
1883
1884 Py_BEGIN_ALLOW_THREADS
1885 #if defined(PYCC_GCC)
1886 spawnval = spawnvp(mode, path, argvlist);
1887 #else
1888 spawnval = _spawnvp(mode, path, argvlist);
1889 #endif
1890 Py_END_ALLOW_THREADS
1891
1892 free_string_array(argvlist, argc);
1893 PyMem_Free(path);
1894
1895 if (spawnval == -1)
1896 return posix_error();
1897 else
1898 return Py_BuildValue("l", (long) spawnval);
1899 }
1900
1901
1902 PyDoc_STRVAR(posix_spawnvpe__doc__,
1903 "spawnvpe(mode, file, args, env)\n\n\
1904 Execute the program 'file' in a new process, using the environment\n\
1905 search path to find the file.\n\
1906 \n\
1907 mode: mode of process creation\n\
1908 file: executable file name\n\
1909 args: tuple or list of arguments\n\
1910 env: dictionary of strings mapping to strings");
1911
1912 static PyObject *
1913 posix_spawnvpe(PyObject *self, PyObject *args)
1914 {
1915 char *path;
1916 PyObject *argv, *env;
1917 char **argvlist;
1918 char **envlist;
1919 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1920 int mode, i, pos, argc, envc;
1921 Py_intptr_t spawnval;
1922 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1923 int lastarg = 0;
1924
1925 /* spawnvpe has four arguments: (mode, path, argv, env), where
1926 argv is a list or tuple of strings and env is a dictionary
1927 like posix.environ. */
1928
1929 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
1930 Py_FileSystemDefaultEncoding,
1931 &path, &argv, &env))
1932 return NULL;
1933 if (PyList_Check(argv)) {
1934 argc = PyList_Size(argv);
1935 getitem = PyList_GetItem;
1936 }
1937 else if (PyTuple_Check(argv)) {
1938 argc = PyTuple_Size(argv);
1939 getitem = PyTuple_GetItem;
1940 }
1941 else {
1942 PyErr_SetString(PyExc_TypeError,
1943 "spawnvpe() arg 2 must be a tuple or list");
1944 goto fail_0;
1945 }
1946 if (!PyMapping_Check(env)) {
1947 PyErr_SetString(PyExc_TypeError,
1948 "spawnvpe() arg 3 must be a mapping object");
1949 goto fail_0;
1950 }
1951
1952 argvlist = PyMem_NEW(char *, argc+1);
1953 if (argvlist == NULL) {
1954 PyErr_NoMemory();
1955 goto fail_0;
1956 }
1957 for (i = 0; i < argc; i++) {
1958 if (!PyArg_Parse((*getitem)(argv, i),
1959 "et;spawnvpe() arg 2 must contain only strings",
1960 Py_FileSystemDefaultEncoding,
1961 &argvlist[i]))
1962 {
1963 lastarg = i;
1964 goto fail_1;
1965 }
1966 }
1967 lastarg = argc;
1968 argvlist[argc] = NULL;
1969
1970 i = PyMapping_Size(env);
1971 if (i < 0)
1972 goto fail_1;
1973 envlist = PyMem_NEW(char *, i + 1);
1974 if (envlist == NULL) {
1975 PyErr_NoMemory();
1976 goto fail_1;
1977 }
1978 envc = 0;
1979 keys = PyMapping_Keys(env);
1980 vals = PyMapping_Values(env);
1981 if (!keys || !vals)
1982 goto fail_2;
1983 if (!PyList_Check(keys) || !PyList_Check(vals)) {
1984 PyErr_SetString(PyExc_TypeError,
1985 "spawnvpe(): env.keys() or env.values() is not a list");
1986 goto fail_2;
1987 }
1988
1989 for (pos = 0; pos < i; pos++) {
1990 char *p, *k, *v;
1991 size_t len;
1992
1993 key = PyList_GetItem(keys, pos);
1994 val = PyList_GetItem(vals, pos);
1995 if (!key || !val)
1996 goto fail_2;
1997
1998 if (!PyArg_Parse(
1999 key,
2000 "s;spawnvpe() arg 3 contains a non-string key",
2001 &k) ||
2002 !PyArg_Parse(
2003 val,
2004 "s;spawnvpe() arg 3 contains a non-string value",
2005 &v))
2006 {
2007 goto fail_2;
2008 }
2009 len = PyString_Size(key) + PyString_Size(val) + 2;
2010 p = PyMem_NEW(char, len);
2011 if (p == NULL) {
2012 PyErr_NoMemory();
2013 goto fail_2;
2014 }
2015 PyOS_snprintf(p, len, "%s=%s", k, v);
2016 envlist[envc++] = p;
2017 }
2018 envlist[envc] = 0;
2019
2020 Py_BEGIN_ALLOW_THREADS
2021 #if defined(PYCC_GCC)
2022 spawnval = spawnvpe(mode, path, argvlist, envlist);
2023 #else
2024 spawnval = _spawnvpe(mode, path, argvlist, envlist);
2025 #endif
2026 Py_END_ALLOW_THREADS
2027
2028 if (spawnval == -1)
2029 (void) posix_error();
2030 else
2031 res = Py_BuildValue("l", (long) spawnval);
2032
2033 fail_2:
2034 while (--envc >= 0)
2035 PyMem_DEL(envlist[envc]);
2036 PyMem_DEL(envlist);
2037 fail_1:
2038 free_string_array(argvlist, lastarg);
2039 Py_XDECREF(vals);
2040 Py_XDECREF(keys);
2041 fail_0:
2042 PyMem_Free(path);
2043 return res;
2044 }
2045 #endif /* PYOS_OS2 */
2046 #endif /* HAVE_SPAWNV */
2047
2048
2049 #ifdef HAVE_FORK1
2050 PyDoc_STRVAR(posix_fork1__doc__,
2051 "fork1() -> pid\n\n\
2052 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2053 \n\
2054 Return 0 to child process and PID of child to parent process.");
2055
2056 static PyObject *
2057 posix_fork1(PyObject *self, PyObject *noargs)
2058 {
2059 pid_t pid;
2060 int result = 0;
2061 _PyImport_AcquireLock();
2062 pid = fork1();
2063 if (pid == 0) {
2064 /* child: this clobbers and resets the import lock. */
2065 PyOS_AfterFork();
2066 } else {
2067 /* parent: release the import lock. */
2068 result = _PyImport_ReleaseLock();
2069 }
2070 if (pid == -1)
2071 return posix_error();
2072 if (result < 0) {
2073 /* Don't clobber the OSError if the fork failed. */
2074 PyErr_SetString(PyExc_RuntimeError,
2075 "not holding the import lock");
2076 return NULL;
2077 }
2078 return PyLong_FromPid(pid);
2079 }
2080 #endif
2081
2082
2083 #ifdef HAVE_FORK
2084 PyDoc_STRVAR(posix_fork__doc__,
2085 "fork() -> pid\n\n\
2086 Fork a child process.\n\
2087 Return 0 to child process and PID of child to parent process.");
2088
2089 static PyObject *
2090 posix_fork(PyObject *self, PyObject *noargs)
2091 {
2092 pid_t pid;
2093 int result = 0;
2094 _PyImport_AcquireLock();
2095 pid = fork();
2096 if (pid == 0) {
2097 /* child: this clobbers and resets the import lock. */
2098 PyOS_AfterFork();
2099 } else {
2100 /* parent: release the import lock. */
2101 result = _PyImport_ReleaseLock();
2102 }
2103 if (pid == -1)
2104 return posix_error();
2105 if (result < 0) {
2106 /* Don't clobber the OSError if the fork failed. */
2107 PyErr_SetString(PyExc_RuntimeError,
2108 "not holding the import lock");
2109 return NULL;
2110 }
2111 return PyLong_FromPid(pid);
2112 }
2113 #endif
2114
2115 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
2116 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2117 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
2118 #define DEV_PTY_FILE "/dev/ptc"
2119 #define HAVE_DEV_PTMX
2120 #else
2121 #define DEV_PTY_FILE "/dev/ptmx"
2122 #endif
2123
2124 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
2125 #ifdef HAVE_PTY_H
2126 #include <pty.h>
2127 #else
2128 #ifdef HAVE_LIBUTIL_H
2129 #include <libutil.h>
2130 #else
2131 #ifdef HAVE_UTIL_H
2132 #include <util.h>
2133 #endif /* HAVE_UTIL_H */
2134 #endif /* HAVE_LIBUTIL_H */
2135 #endif /* HAVE_PTY_H */
2136 #ifdef HAVE_STROPTS_H
2137 #include <stropts.h>
2138 #endif
2139 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
2140
2141 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
2142 PyDoc_STRVAR(posix_openpty__doc__,
2143 "openpty() -> (master_fd, slave_fd)\n\n\
2144 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
2145
2146 static PyObject *
2147 posix_openpty(PyObject *self, PyObject *noargs)
2148 {
2149 int master_fd, slave_fd;
2150 #ifndef HAVE_OPENPTY
2151 char * slave_name;
2152 #endif
2153 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
2154 PyOS_sighandler_t sig_saved;
2155 #ifdef sun
2156 extern char *ptsname(int fildes);
2157 #endif
2158 #endif
2159
2160 #ifdef HAVE_OPENPTY
2161 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2162 return posix_error();
2163 #elif defined(HAVE__GETPTY)
2164 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2165 if (slave_name == NULL)
2166 return posix_error();
2167
2168 slave_fd = open(slave_name, O_RDWR);
2169 if (slave_fd < 0)
2170 return posix_error();
2171 #else
2172 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
2173 if (master_fd < 0)
2174 return posix_error();
2175 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
2176 /* change permission of slave */
2177 if (grantpt(master_fd) < 0) {
2178 PyOS_setsig(SIGCHLD, sig_saved);
2179 return posix_error();
2180 }
2181 /* unlock slave */
2182 if (unlockpt(master_fd) < 0) {
2183 PyOS_setsig(SIGCHLD, sig_saved);
2184 return posix_error();
2185 }
2186 PyOS_setsig(SIGCHLD, sig_saved);
2187 slave_name = ptsname(master_fd); /* get name of slave */
2188 if (slave_name == NULL)
2189 return posix_error();
2190 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2191 if (slave_fd < 0)
2192 return posix_error();
2193 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
2194 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2195 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
2196 #ifndef __hpux
2197 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
2198 #endif /* __hpux */
2199 #endif /* HAVE_CYGWIN */
2200 #endif /* HAVE_OPENPTY */
2201
2202 return Py_BuildValue("(ii)", master_fd, slave_fd);
2203
2204 }
2205 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
2206
2207 #ifdef HAVE_FORKPTY
2208 PyDoc_STRVAR(posix_forkpty__doc__,
2209 "forkpty() -> (pid, master_fd)\n\n\
2210 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2211 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
2212 To both, return fd of newly opened pseudo-terminal.\n");
2213
2214 static PyObject *
2215 posix_forkpty(PyObject *self, PyObject *noargs)
2216 {
2217 int master_fd = -1, result = 0;
2218 pid_t pid;
2219
2220 _PyImport_AcquireLock();
2221 pid = forkpty(&master_fd, NULL, NULL, NULL);
2222 if (pid == 0) {
2223 /* child: this clobbers and resets the import lock. */
2224 PyOS_AfterFork();
2225 } else {
2226 /* parent: release the import lock. */
2227 result = _PyImport_ReleaseLock();
2228 }
2229 if (pid == -1)
2230 return posix_error();
2231 if (result < 0) {
2232 /* Don't clobber the OSError if the fork failed. */
2233 PyErr_SetString(PyExc_RuntimeError,
2234 "not holding the import lock");
2235 return NULL;
2236 }
2237 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
2238 }
2239 #endif
2240
2241 PyDoc_STRVAR(posix_getpid__doc__,
2242 "getpid() -> pid\n\n\
2243 Return the current process id");
2244
2245 static PyObject *
2246 posix_getpid(PyObject *self, PyObject *noargs)
2247 {
2248 return PyLong_FromPid(getpid());
2249 }
2250
2251 #ifdef HAVE_GETLOGIN
2252 PyDoc_STRVAR(posix_getlogin__doc__,
2253 "getlogin() -> string\n\n\
2254 Return the actual login name.");
2255
2256 static PyObject *
2257 posix_getlogin(PyObject *self, PyObject *noargs)
2258 {
2259 PyObject *result = NULL;
2260 char *name;
2261 int old_errno = errno;
2262
2263 errno = 0;
2264 name = getlogin();
2265 if (name == NULL) {
2266 if (errno)
2267 posix_error();
2268 else
2269 PyErr_SetString(PyExc_OSError,
2270 "unable to determine login name");
2271 }
2272 else
2273 result = PyString_FromString(name);
2274 errno = old_errno;
2275
2276 return result;
2277 }
2278 #endif
2279
2280 #ifdef HAVE_KILL
2281 PyDoc_STRVAR(posix_kill__doc__,
2282 "kill(pid, sig)\n\n\
2283 Kill a process with a signal.");
2284
2285 static PyObject *
2286 posix_kill(PyObject *self, PyObject *args)
2287 {
2288 pid_t pid;
2289 int sig;
2290 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
2291 return NULL;
2292 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
2293 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2294 APIRET rc;
2295 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
2296 return os2_error(rc);
2297
2298 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2299 APIRET rc;
2300 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
2301 return os2_error(rc);
2302
2303 } else
2304 return NULL; /* Unrecognized Signal Requested */
2305 #else
2306 if (kill(pid, sig) == -1)
2307 return posix_error();
2308 #endif
2309 Py_INCREF(Py_None);
2310 return Py_None;
2311 }
2312 #endif
2313
2314 #ifdef HAVE_PLOCK
2315
2316 #ifdef HAVE_SYS_LOCK_H
2317 #include <sys/lock.h>
2318 #endif
2319
2320 PyDoc_STRVAR(posix_plock__doc__,
2321 "plock(op)\n\n\
2322 Lock program segments into memory.");
2323
2324 static PyObject *
2325 posix_plock(PyObject *self, PyObject *args)
2326 {
2327 int op;
2328 if (!PyArg_ParseTuple(args, "i:plock", &op))
2329 return NULL;
2330 if (plock(op) == -1)
2331 return posix_error();
2332 Py_INCREF(Py_None);
2333 return Py_None;
2334 }
2335 #endif
2336
2337
2338 #ifdef HAVE_POPEN
2339 PyDoc_STRVAR(posix_popen__doc__,
2340 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
2341 Open a pipe to/from a command returning a file object.");
2342
2343 /* standard posix version of popen() support */
2344 static PyObject *
2345 posix_popen(PyObject *self, PyObject *args)
2346 {
2347 char *name;
2348 char *mode = "r";
2349 int bufsize = -1;
2350 FILE *fp;
2351 PyObject *f;
2352 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2353 return NULL;
2354 /* Strip mode of binary or text modifiers */
2355 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
2356 mode = "r";
2357 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
2358 mode = "w";
2359 Py_BEGIN_ALLOW_THREADS
2360 fp = popen(name, mode);
2361 Py_END_ALLOW_THREADS
2362 if (fp == NULL)
2363 return posix_error();
2364 f = PyFile_FromFile(fp, name, mode, pclose);
2365 if (f != NULL)
2366 PyFile_SetBufSize(f, bufsize);
2367 return f;
2368 }
2369
2370 #endif /* HAVE_POPEN */
2371
2372 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
2373 static PyObject *
2374 wait_helper(pid_t pid, int status, struct rusage *ru)
2375 {
2376 PyObject *result;
2377 static PyObject *struct_rusage;
2378
2379 if (pid == -1)
2380 return posix_error();
2381
2382 if (struct_rusage == NULL) {
2383 PyObject *m = PyImport_ImportModuleNoBlock("resource");
2384 if (m == NULL)
2385 return NULL;
2386 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
2387 Py_DECREF(m);
2388 if (struct_rusage == NULL)
2389 return NULL;
2390 }
2391
2392 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
2393 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
2394 if (!result)
2395 return NULL;
2396
2397 #ifndef doubletime
2398 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
2399 #endif
2400
2401 PyStructSequence_SET_ITEM(result, 0,
2402 PyFloat_FromDouble(doubletime(ru->ru_utime)));
2403 PyStructSequence_SET_ITEM(result, 1,
2404 PyFloat_FromDouble(doubletime(ru->ru_stime)));
2405 #define SET_INT(result, index, value)\
2406 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
2407 SET_INT(result, 2, ru->ru_maxrss);
2408 SET_INT(result, 3, ru->ru_ixrss);
2409 SET_INT(result, 4, ru->ru_idrss);
2410 SET_INT(result, 5, ru->ru_isrss);
2411 SET_INT(result, 6, ru->ru_minflt);
2412 SET_INT(result, 7, ru->ru_majflt);
2413 SET_INT(result, 8, ru->ru_nswap);
2414 SET_INT(result, 9, ru->ru_inblock);
2415 SET_INT(result, 10, ru->ru_oublock);
2416 SET_INT(result, 11, ru->ru_msgsnd);
2417 SET_INT(result, 12, ru->ru_msgrcv);
2418 SET_INT(result, 13, ru->ru_nsignals);
2419 SET_INT(result, 14, ru->ru_nvcsw);
2420 SET_INT(result, 15, ru->ru_nivcsw);
2421 #undef SET_INT
2422
2423 if (PyErr_Occurred()) {
2424 Py_DECREF(result);
2425 return NULL;
2426 }
2427
2428 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
2429 }
2430 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
2431
2432 #ifdef HAVE_WAIT3
2433 PyDoc_STRVAR(posix_wait3__doc__,
2434 "wait3(options) -> (pid, status, rusage)\n\n\
2435 Wait for completion of a child process.");
2436
2437 static PyObject *
2438 posix_wait3(PyObject *self, PyObject *args)
2439 {
2440 pid_t pid;
2441 int options;
2442 struct rusage ru;
2443 WAIT_TYPE status;
2444 WAIT_STATUS_INT(status) = 0;
2445
2446 if (!PyArg_ParseTuple(args, "i:wait3", &options))
2447 return NULL;
2448
2449 Py_BEGIN_ALLOW_THREADS
2450 pid = wait3(&status, options, &ru);
2451 Py_END_ALLOW_THREADS
2452
2453 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
2454 }
2455 #endif /* HAVE_WAIT3 */
2456
2457 #ifdef HAVE_WAIT4
2458 PyDoc_STRVAR(posix_wait4__doc__,
2459 "wait4(pid, options) -> (pid, status, rusage)\n\n\
2460 Wait for completion of a given child process.");
2461
2462 static PyObject *
2463 posix_wait4(PyObject *self, PyObject *args)
2464 {
2465 pid_t pid;
2466 int options;
2467 struct rusage ru;
2468 WAIT_TYPE status;
2469 WAIT_STATUS_INT(status) = 0;
2470
2471 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
2472 return NULL;
2473
2474 Py_BEGIN_ALLOW_THREADS
2475 pid = wait4(pid, &status, options, &ru);
2476 Py_END_ALLOW_THREADS
2477
2478 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
2479 }
2480 #endif /* HAVE_WAIT4 */
2481
2482 #ifdef HAVE_WAITPID
2483 PyDoc_STRVAR(posix_waitpid__doc__,
2484 "waitpid(pid, options) -> (pid, status)\n\n\
2485 Wait for completion of a given child process.");
2486
2487 static PyObject *
2488 posix_waitpid(PyObject *self, PyObject *args)
2489 {
2490 pid_t pid;
2491 int options;
2492 WAIT_TYPE status;
2493 WAIT_STATUS_INT(status) = 0;
2494
2495 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
2496 return NULL;
2497 Py_BEGIN_ALLOW_THREADS
2498 pid = waitpid(pid, &status, options);
2499 Py_END_ALLOW_THREADS
2500 if (pid == -1)
2501 return posix_error();
2502
2503 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
2504 }
2505
2506 #elif defined(HAVE_CWAIT)
2507
2508 /* MS C has a variant of waitpid() that's usable for most purposes. */
2509 PyDoc_STRVAR(posix_waitpid__doc__,
2510 "waitpid(pid, options) -> (pid, status << 8)\n\n"
2511 "Wait for completion of a given process. options is ignored on Windows.");
2512
2513 static PyObject *
2514 posix_waitpid(PyObject *self, PyObject *args)
2515 {
2516 Py_intptr_t pid;
2517 int status, options;
2518
2519 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
2520 return NULL;
2521 Py_BEGIN_ALLOW_THREADS
2522 pid = _cwait(&status, pid, options);
2523 Py_END_ALLOW_THREADS
2524 if (pid == -1)
2525 return posix_error();
2526
2527 /* shift the status left a byte so this is more like the POSIX waitpid */
2528 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
2529 }
2530 #endif /* HAVE_WAITPID || HAVE_CWAIT */
2531
2532 #ifdef HAVE_WAIT
2533 PyDoc_STRVAR(posix_wait__doc__,
2534 "wait() -> (pid, status)\n\n\
2535 Wait for completion of a child process.");
2536
2537 static PyObject *
2538 posix_wait(PyObject *self, PyObject *noargs)
2539 {
2540 pid_t pid;
2541 WAIT_TYPE status;
2542 WAIT_STATUS_INT(status) = 0;
2543
2544 Py_BEGIN_ALLOW_THREADS
2545 pid = wait(&status);
2546 Py_END_ALLOW_THREADS
2547 if (pid == -1)
2548 return posix_error();
2549
2550 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
2551 }
2552 #endif
2553
2554
2555 PyDoc_STRVAR(posix_lstat__doc__,
2556 "lstat(path) -> stat result\n\n\
2557 Like stat(path), but do not follow symbolic links.");
2558
2559 static PyObject *
2560 posix_lstat(PyObject *self, PyObject *args)
2561 {
2562 #ifdef HAVE_LSTAT
2563 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
2564 #else /* !HAVE_LSTAT */
2565 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
2566 #endif /* !HAVE_LSTAT */
2567 }
2568
2569
2570 #ifdef HAVE_READLINK
2571 PyDoc_STRVAR(posix_readlink__doc__,
2572 "readlink(path) -> path\n\n\
2573 Return a string representing the path to which the symbolic link points.");
2574
2575 static PyObject *
2576 posix_readlink(PyObject *self, PyObject *args)
2577 {
2578 PyObject* v;
2579 char buf[MAXPATHLEN];
2580 char *path;
2581 int n;
2582 #ifdef Py_USING_UNICODE
2583 int arg_is_unicode = 0;
2584 #endif
2585
2586 if (!PyArg_ParseTuple(args, "et:readlink",
2587 Py_FileSystemDefaultEncoding, &path))
2588 return NULL;
2589 #ifdef Py_USING_UNICODE
2590 v = PySequence_GetItem(args, 0);
2591 if (v == NULL) {
2592 PyMem_Free(path);
2593 return NULL;
2594 }
2595
2596 if (PyUnicode_Check(v)) {
2597 arg_is_unicode = 1;
2598 }
2599 Py_DECREF(v);
2600 #endif
2601
2602 Py_BEGIN_ALLOW_THREADS
2603 n = readlink(path, buf, (int) sizeof buf);
2604 Py_END_ALLOW_THREADS
2605 if (n < 0)
2606 return posix_error_with_allocated_filename(path);
2607
2608 PyMem_Free(path);
2609 v = PyString_FromStringAndSize(buf, n);
2610 #ifdef Py_USING_UNICODE
2611 if (arg_is_unicode) {
2612 PyObject *w;
2613
2614 w = PyUnicode_FromEncodedObject(v,
2615 Py_FileSystemDefaultEncoding,
2616 "strict");
2617 if (w != NULL) {
2618 Py_DECREF(v);
2619 v = w;
2620 }
2621 else {
2622 /* fall back to the original byte string, as
2623 discussed in patch #683592 */
2624 PyErr_Clear();
2625 }
2626 }
2627 #endif
2628 return v;
2629 }
2630 #endif /* HAVE_READLINK */
2631
2632
2633 #ifdef HAVE_SYMLINK
2634 PyDoc_STRVAR(posix_symlink__doc__,
2635 "symlink(src, dst)\n\n\
2636 Create a symbolic link pointing to src named dst.");
2637
2638 static PyObject *
2639 posix_symlink(PyObject *self, PyObject *args)
2640 {
2641 return posix_2str(args, "etet:symlink", symlink);
2642 }
2643 #endif /* HAVE_SYMLINK */
2644
2645
2646 #ifdef HAVE_TIMES
2647 #define NEED_TICKS_PER_SECOND
2648 static long ticks_per_second = -1;
2649 static PyObject *
2650 posix_times(PyObject *self, PyObject *noargs)
2651 {
2652 struct tms t;
2653 clock_t c;
2654 errno = 0;
2655 c = times(&t);
2656 if (c == (clock_t) -1)
2657 return posix_error();
2658 return Py_BuildValue("ddddd",
2659 (double)t.tms_utime / ticks_per_second,
2660 (double)t.tms_stime / ticks_per_second,
2661 (double)t.tms_cutime / ticks_per_second,
2662 (double)t.tms_cstime / ticks_per_second,
2663 (double)c / ticks_per_second);
2664 }
2665 #endif /* HAVE_TIMES */
2666
2667
2668 #ifdef HAVE_TIMES
2669 PyDoc_STRVAR(posix_times__doc__,
2670 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
2671 Return a tuple of floating point numbers indicating process times.");
2672 #endif
2673
2674
2675 #ifdef HAVE_GETSID
2676 PyDoc_STRVAR(posix_getsid__doc__,
2677 "getsid(pid) -> sid\n\n\
2678 Call the system call getsid().");
2679
2680 static PyObject *
2681 posix_getsid(PyObject *self, PyObject *args)
2682 {
2683 pid_t pid;
2684 int sid;
2685 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
2686 return NULL;
2687 sid = getsid(pid);
2688 if (sid < 0)
2689 return posix_error();
2690 return PyInt_FromLong((long)sid);
2691 }
2692 #endif /* HAVE_GETSID */
2693
2694
2695 #ifdef HAVE_SETSID
2696 PyDoc_STRVAR(posix_setsid__doc__,
2697 "setsid()\n\n\
2698 Call the system call setsid().");
2699
2700 static PyObject *
2701 posix_setsid(PyObject *self, PyObject *noargs)
2702 {
2703 if (setsid() < 0)
2704 return posix_error();
2705 Py_INCREF(Py_None);
2706 return Py_None;
2707 }
2708 #endif /* HAVE_SETSID */
2709
2710 #ifdef HAVE_SETPGID
2711 PyDoc_STRVAR(posix_setpgid__doc__,
2712 "setpgid(pid, pgrp)\n\n\
2713 Call the system call setpgid().");
2714
2715 static PyObject *
2716 posix_setpgid(PyObject *self, PyObject *args)
2717 {
2718 pid_t pid;
2719 int pgrp;
2720 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
2721 return NULL;
2722 if (setpgid(pid, pgrp) < 0)
2723 return posix_error();
2724 Py_INCREF(Py_None);
2725 return Py_None;
2726 }
2727 #endif /* HAVE_SETPGID */
2728
2729
2730 #ifdef HAVE_TCGETPGRP
2731 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
2732 "tcgetpgrp(fd) -> pgid\n\n\
2733 Return the process group associated with the terminal given by a fd.");
2734
2735 static PyObject *
2736 posix_tcgetpgrp(PyObject *self, PyObject *args)
2737 {
2738 int fd;
2739 pid_t pgid;
2740 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
2741 return NULL;
2742 pgid = tcgetpgrp(fd);
2743 if (pgid < 0)
2744 return posix_error();
2745 return PyLong_FromPid(pgid);
2746 }
2747 #endif /* HAVE_TCGETPGRP */
2748
2749
2750 #ifdef HAVE_TCSETPGRP
2751 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
2752 "tcsetpgrp(fd, pgid)\n\n\
2753 Set the process group associated with the terminal given by a fd.");
2754
2755 static PyObject *
2756 posix_tcsetpgrp(PyObject *self, PyObject *args)
2757 {
2758 int fd;
2759 pid_t pgid;
2760 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
2761 return NULL;
2762 if (tcsetpgrp(fd, pgid) < 0)
2763 return posix_error();
2764 Py_INCREF(Py_None);
2765 return Py_None;
2766 }
2767 #endif /* HAVE_TCSETPGRP */
2768
2769 /* Functions acting on file descriptors */
2770
2771 PyDoc_STRVAR(posix_open__doc__,
2772 "open(filename, flag [, mode=0777]) -> fd\n\n\
2773 Open a file (for low level IO).");
2774
2775 static PyObject *
2776 posix_open(PyObject *self, PyObject *args)
2777 {
2778 char *file = NULL;
2779 int flag;
2780 int mode = 0777;
2781 int fd;
2782
2783 if (!PyArg_ParseTuple(args, "eti|i",
2784 Py_FileSystemDefaultEncoding, &file,
2785 &flag, &mode))
2786 return NULL;
2787
2788 Py_BEGIN_ALLOW_THREADS
2789 fd = open(file, flag, mode);
2790 Py_END_ALLOW_THREADS
2791 if (fd < 0)
2792 return posix_error_with_allocated_filename(file);
2793 PyMem_Free(file);
2794 return PyInt_FromLong((long)fd);
2795 }
2796
2797
2798 PyDoc_STRVAR(posix_close__doc__,
2799 "close(fd)\n\n\
2800 Close a file descriptor (for low level IO).");
2801
2802 static PyObject *
2803 posix_close(PyObject *self, PyObject *args)
2804 {
2805 int fd, res;
2806 if (!PyArg_ParseTuple(args, "i:close", &fd))
2807 return NULL;
2808 if (!_PyVerify_fd(fd))
2809 return posix_error();
2810 Py_BEGIN_ALLOW_THREADS
2811 res = close(fd);
2812 Py_END_ALLOW_THREADS
2813 if (res < 0)
2814 return posix_error();
2815 Py_INCREF(Py_None);
2816 return Py_None;
2817 }
2818
2819
2820 PyDoc_STRVAR(posix_closerange__doc__,
2821 "closerange(fd_low, fd_high)\n\n\
2822 Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
2823
2824 static PyObject *
2825 posix_closerange(PyObject *self, PyObject *args)
2826 {
2827 int fd_from, fd_to, i;
2828 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
2829 return NULL;
2830 Py_BEGIN_ALLOW_THREADS
2831 for (i = fd_from; i < fd_to; i++)
2832 if (_PyVerify_fd(i))
2833 close(i);
2834 Py_END_ALLOW_THREADS
2835 Py_RETURN_NONE;
2836 }
2837
2838
2839 PyDoc_STRVAR(posix_dup__doc__,
2840 "dup(fd) -> fd2\n\n\
2841 Return a duplicate of a file descriptor.");
2842
2843 static PyObject *
2844 posix_dup(PyObject *self, PyObject *args)
2845 {
2846 int fd;
2847 if (!PyArg_ParseTuple(args, "i:dup", &fd))
2848 return NULL;
2849 if (!_PyVerify_fd(fd))
2850 return posix_error();
2851 Py_BEGIN_ALLOW_THREADS
2852 fd = dup(fd);
2853 Py_END_ALLOW_THREADS
2854 if (fd < 0)
2855 return posix_error();
2856 return PyInt_FromLong((long)fd);
2857 }
2858
2859
2860 PyDoc_STRVAR(posix_dup2__doc__,
2861 "dup2(old_fd, new_fd)\n\n\
2862 Duplicate file descriptor.");
2863
2864 static PyObject *
2865 posix_dup2(PyObject *self, PyObject *args)
2866 {
2867 int fd, fd2, res;
2868 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
2869 return NULL;
2870 if (!_PyVerify_fd_dup2(fd, fd2))
2871 return posix_error();
2872 Py_BEGIN_ALLOW_THREADS
2873 res = dup2(fd, fd2);
2874 Py_END_ALLOW_THREADS
2875 if (res < 0)
2876 return posix_error();
2877 Py_INCREF(Py_None);
2878 return Py_None;
2879 }
2880
2881
2882 PyDoc_STRVAR(posix_lseek__doc__,
2883 "lseek(fd, pos, how) -> newpos\n\n\
2884 Set the current position of a file descriptor.");
2885
2886 static PyObject *
2887 posix_lseek(PyObject *self, PyObject *args)
2888 {
2889 int fd, how;
2890 off_t pos, res;
2891 PyObject *posobj;
2892 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
2893 return NULL;
2894 #ifdef SEEK_SET
2895 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
2896 switch (how) {
2897 case 0: how = SEEK_SET; break;
2898 case 1: how = SEEK_CUR; break;
2899 case 2: how = SEEK_END; break;
2900 }
2901 #endif /* SEEK_END */
2902
2903 #if !defined(HAVE_LARGEFILE_SUPPORT)
2904 pos = PyInt_AsLong(posobj);
2905 #else
2906 pos = PyLong_Check(posobj) ?
2907 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
2908 #endif
2909 if (PyErr_Occurred())
2910 return NULL;
2911
2912 if (!_PyVerify_fd(fd))
2913 return posix_error();
2914 Py_BEGIN_ALLOW_THREADS
2915 res = lseek(fd, pos, how);
2916 Py_END_ALLOW_THREADS
2917 if (res < 0)
2918 return posix_error();
2919
2920 #if !defined(HAVE_LARGEFILE_SUPPORT)
2921 return PyInt_FromLong(res);
2922 #else
2923 return PyLong_FromLongLong(res);
2924 #endif
2925 }
2926
2927
2928 PyDoc_STRVAR(posix_read__doc__,
2929 "read(fd, buffersize) -> string\n\n\
2930 Read a file descriptor.");
2931
2932 static PyObject *
2933 posix_read(PyObject *self, PyObject *args)
2934 {
2935 int fd, size, n;
2936 PyObject *buffer;
2937 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
2938 return NULL;
2939 if (size < 0) {
2940 errno = EINVAL;
2941 return posix_error();
2942 }
2943 buffer = PyString_FromStringAndSize((char *)NULL, size);
2944 if (buffer == NULL)
2945 return NULL;
2946 if (!_PyVerify_fd(fd)) {
2947 Py_DECREF(buffer);
2948 return posix_error();
2949 }
2950 Py_BEGIN_ALLOW_THREADS
2951 n = read(fd, PyString_AsString(buffer), size);
2952 Py_END_ALLOW_THREADS
2953 if (n < 0) {
2954 Py_DECREF(buffer);
2955 return posix_error();
2956 }
2957 if (n != size)
2958 _PyString_Resize(&buffer, n);
2959 return buffer;
2960 }
2961
2962
2963 PyDoc_STRVAR(posix_write__doc__,
2964 "write(fd, string) -> byteswritten\n\n\
2965 Write a string to a file descriptor.");
2966
2967 static PyObject *
2968 posix_write(PyObject *self, PyObject *args)
2969 {
2970 Py_buffer pbuf;
2971 int fd;
2972 Py_ssize_t size;
2973
2974 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
2975 return NULL;
2976 if (!_PyVerify_fd(fd)) {
2977 PyBuffer_Release(&pbuf);
2978 return posix_error();
2979 }
2980 Py_BEGIN_ALLOW_THREADS
2981 size = write(fd, pbuf.buf, (size_t)pbuf.len);
2982 Py_END_ALLOW_THREADS
2983 PyBuffer_Release(&pbuf);
2984 if (size < 0)
2985 return posix_error();
2986 return PyInt_FromSsize_t(size);
2987 }
2988
2989
2990 PyDoc_STRVAR(posix_fstat__doc__,
2991 "fstat(fd) -> stat result\n\n\
2992 Like stat(), but for an open file descriptor.");
2993
2994 static PyObject *
2995 posix_fstat(PyObject *self, PyObject *args)
2996 {
2997 int fd;
2998 STRUCT_STAT st;
2999 int res;
3000 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
3001 return NULL;
3002 if (!_PyVerify_fd(fd))
3003 return posix_error();
3004 Py_BEGIN_ALLOW_THREADS
3005 res = FSTAT(fd, &st);
3006 Py_END_ALLOW_THREADS
3007 if (res != 0) {
3008 return posix_error();
3009 }
3010
3011 return _pystat_fromstructstat(&st);
3012 }
3013
3014
3015 PyDoc_STRVAR(posix_fdopen__doc__,
3016 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
3017 Return an open file object connected to a file descriptor.");
3018
3019 static PyObject *
3020 posix_fdopen(PyObject *self, PyObject *args)
3021 {
3022 int fd;
3023 char *orgmode = "r";
3024 int bufsize = -1;
3025 FILE *fp;
3026 PyObject *f;
3027 char *mode;
3028 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
3029 return NULL;
3030
3031 /* Sanitize mode. See fileobject.c */
3032 mode = PyMem_MALLOC(strlen(orgmode)+3);
3033 if (!mode) {
3034 PyErr_NoMemory();
3035 return NULL;
3036 }
3037 strcpy(mode, orgmode);
3038 if (_PyFile_SanitizeMode(mode)) {
3039 PyMem_FREE(mode);
3040 return NULL;
3041 }
3042 if (!_PyVerify_fd(fd))
3043 return posix_error();
3044 Py_BEGIN_ALLOW_THREADS
3045 #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
3046 if (mode[0] == 'a') {
3047 /* try to make sure the O_APPEND flag is set */
3048 int flags;
3049 flags = fcntl(fd, F_GETFL);
3050 if (flags != -1)
3051 fcntl(fd, F_SETFL, flags | O_APPEND);
3052 fp = fdopen(fd, mode);
3053 if (fp == NULL && flags != -1)
3054 /* restore old mode if fdopen failed */
3055 fcntl(fd, F_SETFL, flags);
3056 } else {
3057 fp = fdopen(fd, mode);
3058 }
3059 #else
3060 fp = fdopen(fd, mode);
3061 #endif
3062 Py_END_ALLOW_THREADS
3063 PyMem_FREE(mode);
3064 if (fp == NULL)
3065 return posix_error();
3066 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
3067 if (f != NULL)
3068 PyFile_SetBufSize(f, bufsize);
3069 return f;
3070 }
3071
3072 PyDoc_STRVAR(posix_isatty__doc__,
3073 "isatty(fd) -> bool\n\n\
3074 Return True if the file descriptor 'fd' is an open file descriptor\n\
3075 connected to the slave end of a terminal.");
3076
3077 static PyObject *
3078 posix_isatty(PyObject *self, PyObject *args)
3079 {
3080 int fd;
3081 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3082 return NULL;
3083 if (!_PyVerify_fd(fd))
3084 return PyBool_FromLong(0);
3085 return PyBool_FromLong(isatty(fd));
3086 }
3087
3088 #ifdef HAVE_PIPE
3089 PyDoc_STRVAR(posix_pipe__doc__,
3090 "pipe() -> (read_end, write_end)\n\n\
3091 Create a pipe.");
3092
3093 static PyObject *
3094 posix_pipe(PyObject *self, PyObject *noargs)
3095 {
3096 int fds[2];
3097 int res;
3098 Py_BEGIN_ALLOW_THREADS
3099 res = pipe(fds);
3100 Py_END_ALLOW_THREADS
3101 if (res != 0)
3102 return posix_error();
3103 return Py_BuildValue("(ii)", fds[0], fds[1]);
3104 }
3105 #endif /* HAVE_PIPE */
3106
3107
3108 #ifdef HAVE_MKFIFO
3109 PyDoc_STRVAR(posix_mkfifo__doc__,
3110 "mkfifo(filename [, mode=0666])\n\n\
3111 Create a FIFO (a POSIX named pipe).");
3112
3113 static PyObject *
3114 posix_mkfifo(PyObject *self, PyObject *args)
3115 {
3116 char *filename;
3117 int mode = 0666;
3118 int res;
3119 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
3120 return NULL;
3121 Py_BEGIN_ALLOW_THREADS
3122 res = mkfifo(filename, mode);
3123 Py_END_ALLOW_THREADS
3124 if (res < 0)
3125 return posix_error();
3126 Py_INCREF(Py_None);
3127 return Py_None;
3128 }
3129 #endif
3130
3131
3132 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
3133 PyDoc_STRVAR(posix_mknod__doc__,
3134 "mknod(filename [, mode=0600, device])\n\n\
3135 Create a filesystem node (file, device special file or named pipe)\n\
3136 named filename. mode specifies both the permissions to use and the\n\
3137 type of node to be created, being combined (bitwise OR) with one of\n\
3138 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
3139 device defines the newly created device special file (probably using\n\
3140 os.makedev()), otherwise it is ignored.");
3141
3142
3143 static PyObject *
3144 posix_mknod(PyObject *self, PyObject *args)
3145 {
3146 char *filename;
3147 int mode = 0600;
3148 int device = 0;
3149 int res;
3150 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
3151 return NULL;
3152 Py_BEGIN_ALLOW_THREADS
3153 res = mknod(filename, mode, device);
3154 Py_END_ALLOW_THREADS
3155 if (res < 0)
3156 return posix_error();
3157 Py_INCREF(Py_None);
3158 return Py_None;
3159 }
3160 #endif
3161
3162 #ifdef HAVE_DEVICE_MACROS
3163 PyDoc_STRVAR(posix_major__doc__,
3164 "major(device) -> major number\n\
3165 Extracts a device major number from a raw device number.");
3166
3167 static PyObject *
3168 posix_major(PyObject *self, PyObject *args)
3169 {
3170 int device;
3171 if (!PyArg_ParseTuple(args, "i:major", &device))
3172 return NULL;
3173 return PyInt_FromLong((long)major(device));
3174 }
3175
3176 PyDoc_STRVAR(posix_minor__doc__,
3177 "minor(device) -> minor number\n\
3178 Extracts a device minor number from a raw device number.");
3179
3180 static PyObject *
3181 posix_minor(PyObject *self, PyObject *args)
3182 {
3183 int device;
3184 if (!PyArg_ParseTuple(args, "i:minor", &device))
3185 return NULL;
3186 return PyInt_FromLong((long)minor(device));
3187 }
3188
3189 PyDoc_STRVAR(posix_makedev__doc__,
3190 "makedev(major, minor) -> device number\n\
3191 Composes a raw device number from the major and minor device numbers.");
3192
3193 static PyObject *
3194 posix_makedev(PyObject *self, PyObject *args)
3195 {
3196 int major, minor;
3197 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
3198 return NULL;
3199 return PyInt_FromLong((long)makedev(major, minor));
3200 }
3201 #endif /* device macros */
3202
3203
3204 #ifdef HAVE_FTRUNCATE
3205 PyDoc_STRVAR(posix_ftruncate__doc__,
3206 "ftruncate(fd, length)\n\n\
3207 Truncate a file to a specified length.");
3208
3209 static PyObject *
3210 posix_ftruncate(PyObject *self, PyObject *args)
3211 {
3212 int fd;
3213 off_t length;
3214 int res;
3215 PyObject *lenobj;
3216
3217 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
3218 return NULL;
3219
3220 #if !defined(HAVE_LARGEFILE_SUPPORT)
3221 length = PyInt_AsLong(lenobj);
3222 #else
3223 length = PyLong_Check(lenobj) ?
3224 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3225 #endif
3226 if (PyErr_Occurred())
3227 return NULL;
3228
3229 Py_BEGIN_ALLOW_THREADS
3230 res = ftruncate(fd, length);
3231 Py_END_ALLOW_THREADS
3232 if (res < 0)
3233 return posix_error();
3234 Py_INCREF(Py_None);
3235 return Py_None;
3236 }
3237 #endif
3238
3239 #ifdef HAVE_PUTENV
3240 PyDoc_STRVAR(posix_putenv__doc__,
3241 "putenv(key, value)\n\n\
3242 Change or add an environment variable.");
3243
3244 /* Save putenv() parameters as values here, so we can collect them when they
3245 * get re-set with another call for the same key. */
3246 static PyObject *posix_putenv_garbage;
3247
3248 static PyObject *
3249 posix_putenv(PyObject *self, PyObject *args)
3250 {
3251 char *s1, *s2;
3252 char *newenv;
3253 PyObject *newstr;
3254 size_t len;
3255
3256 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
3257 return NULL;
3258
3259 /* XXX This can leak memory -- not easy to fix :-( */
3260 len = strlen(s1) + strlen(s2) + 2;
3261 /* len includes space for a trailing \0; the size arg to
3262 PyString_FromStringAndSize does not count that */
3263 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
3264 if (newstr == NULL)
3265 return PyErr_NoMemory();
3266 newenv = PyString_AS_STRING(newstr);
3267 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
3268 if (putenv(newenv)) {
3269 Py_DECREF(newstr);
3270 posix_error();
3271 return NULL;
3272 }
3273 /* Install the first arg and newstr in posix_putenv_garbage;
3274 * this will cause previous value to be collected. This has to
3275 * happen after the real putenv() call because the old value
3276 * was still accessible until then. */
3277 if (PyDict_SetItem(posix_putenv_garbage,
3278 PyTuple_GET_ITEM(args, 0), newstr)) {
3279 /* really not much we can do; just leak */
3280 PyErr_Clear();
3281 }
3282 else {
3283 Py_DECREF(newstr);
3284 }
3285
3286 Py_INCREF(Py_None);
3287 return Py_None;
3288 }
3289 #endif /* putenv */
3290
3291 #ifdef HAVE_UNSETENV
3292 PyDoc_STRVAR(posix_unsetenv__doc__,
3293 "unsetenv(key)\n\n\
3294 Delete an environment variable.");
3295
3296 static PyObject *
3297 posix_unsetenv(PyObject *self, PyObject *args)
3298 {
3299 char *s1;
3300
3301 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
3302 return NULL;
3303
3304 unsetenv(s1);
3305
3306 /* Remove the key from posix_putenv_garbage;
3307 * this will cause it to be collected. This has to
3308 * happen after the real unsetenv() call because the
3309 * old value was still accessible until then.
3310 */
3311 if (PyDict_DelItem(posix_putenv_garbage,
3312 PyTuple_GET_ITEM(args, 0))) {
3313 /* really not much we can do; just leak */
3314 PyErr_Clear();
3315 }
3316
3317 Py_INCREF(Py_None);
3318 return Py_None;
3319 }
3320 #endif /* unsetenv */
3321
3322 PyDoc_STRVAR(posix_strerror__doc__,
3323 "strerror(code) -> string\n\n\
3324 Translate an error code to a message string.");
3325
3326 static PyObject *
3327 posix_strerror(PyObject *self, PyObject *args)
3328 {
3329 int code;
3330 char *message;
3331 if (!PyArg_ParseTuple(args, "i:strerror", &code))
3332 return NULL;
3333 message = strerror(code);
3334 if (message == NULL) {
3335 PyErr_SetString(PyExc_ValueError,
3336 "strerror() argument out of range");
3337 return NULL;
3338 }
3339 return PyString_FromString(message);
3340 }
3341
3342
3343 #ifdef HAVE_SYS_WAIT_H
3344
3345 #ifdef WCOREDUMP
3346 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
3347 "WCOREDUMP(status) -> bool\n\n\
3348 Return True if the process returning 'status' was dumped to a core file.");
3349
3350 static PyObject *
3351 posix_WCOREDUMP(PyObject *self, PyObject *args)
3352 {
3353 WAIT_TYPE status;
3354 WAIT_STATUS_INT(status) = 0;
3355
3356 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
3357 return NULL;
3358
3359 return PyBool_FromLong(WCOREDUMP(status));
3360 }
3361 #endif /* WCOREDUMP */
3362
3363 #ifdef WIFCONTINUED
3364 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
3365 "WIFCONTINUED(status) -> bool\n\n\
3366 Return True if the process returning 'status' was continued from a\n\
3367 job control stop.");
3368
3369 static PyObject *
3370 posix_WIFCONTINUED(PyObject *self, PyObject *args)
3371 {
3372 WAIT_TYPE status;
3373 WAIT_STATUS_INT(status) = 0;
3374
3375 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
3376 return NULL;
3377
3378 return PyBool_FromLong(WIFCONTINUED(status));
3379 }
3380 #endif /* WIFCONTINUED */
3381
3382 #ifdef WIFSTOPPED
3383 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
3384 "WIFSTOPPED(status) -> bool\n\n\
3385 Return True if the process returning 'status' was stopped.");
3386
3387 static PyObject *
3388 posix_WIFSTOPPED(PyObject *self, PyObject *args)
3389 {
3390 WAIT_TYPE status;
3391 WAIT_STATUS_INT(status) = 0;
3392
3393 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
3394 return NULL;
3395
3396 return PyBool_FromLong(WIFSTOPPED(status));
3397 }
3398 #endif /* WIFSTOPPED */
3399
3400 #ifdef WIFSIGNALED
3401 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
3402 "WIFSIGNALED(status) -> bool\n\n\
3403 Return True if the process returning 'status' was terminated by a signal.");
3404
3405 static PyObject *
3406 posix_WIFSIGNALED(PyObject *self, PyObject *args)
3407 {
3408 WAIT_TYPE status;
3409 WAIT_STATUS_INT(status) = 0;
3410
3411 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
3412 return NULL;
3413
3414 return PyBool_FromLong(WIFSIGNALED(status));
3415 }
3416 #endif /* WIFSIGNALED */
3417
3418 #ifdef WIFEXITED
3419 PyDoc_STRVAR(posix_WIFEXITED__doc__,
3420 "WIFEXITED(status) -> bool\n\n\
3421 Return true if the process returning 'status' exited using the exit()\n\
3422 system call.");
3423
3424 static PyObject *
3425 posix_WIFEXITED(PyObject *self, PyObject *args)
3426 {
3427 WAIT_TYPE status;
3428 WAIT_STATUS_INT(status) = 0;
3429
3430 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
3431 return NULL;
3432
3433 return PyBool_FromLong(WIFEXITED(status));
3434 }
3435 #endif /* WIFEXITED */
3436
3437 #ifdef WEXITSTATUS
3438 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
3439 "WEXITSTATUS(status) -> integer\n\n\
3440 Return the process return code from 'status'.");
3441
3442 static PyObject *
3443 posix_WEXITSTATUS(PyObject *self, PyObject *args)
3444 {
3445 WAIT_TYPE status;
3446 WAIT_STATUS_INT(status) = 0;
3447
3448 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
3449 return NULL;
3450
3451 return Py_BuildValue("i", WEXITSTATUS(status));
3452 }
3453 #endif /* WEXITSTATUS */
3454
3455 #ifdef WTERMSIG
3456 PyDoc_STRVAR(posix_WTERMSIG__doc__,
3457 "WTERMSIG(status) -> integer\n\n\
3458 Return the signal that terminated the process that provided the 'status'\n\
3459 value.");
3460
3461 static PyObject *
3462 posix_WTERMSIG(PyObject *self, PyObject *args)
3463 {
3464 WAIT_TYPE status;
3465 WAIT_STATUS_INT(status) = 0;
3466
3467 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
3468 return NULL;
3469
3470 return Py_BuildValue("i", WTERMSIG(status));
3471 }
3472 #endif /* WTERMSIG */
3473
3474 #ifdef WSTOPSIG
3475 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
3476 "WSTOPSIG(status) -> integer\n\n\
3477 Return the signal that stopped the process that provided\n\
3478 the 'status' value.");
3479
3480 static PyObject *
3481 posix_WSTOPSIG(PyObject *self, PyObject *args)
3482 {
3483 WAIT_TYPE status;
3484 WAIT_STATUS_INT(status) = 0;
3485
3486 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
3487 return NULL;
3488
3489 return Py_BuildValue("i", WSTOPSIG(status));
3490 }
3491 #endif /* WSTOPSIG */
3492
3493 #endif /* HAVE_SYS_WAIT_H */
3494
3495
3496 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
3497 #include <sys/statvfs.h>
3498
3499 static PyObject*
3500 _pystatvfs_fromstructstatvfs(struct statvfs st) {
3501 PyObject *v = PyStructSequence_New(&StatVFSResultType);
3502 if (v == NULL)
3503 return NULL;
3504
3505 #if !defined(HAVE_LARGEFILE_SUPPORT)
3506 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
3507 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
3508 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
3509 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
3510 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
3511 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
3512 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
3513 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
3514 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
3515 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
3516 #else
3517 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
3518 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
3519 PyStructSequence_SET_ITEM(v, 2,
3520 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
3521 PyStructSequence_SET_ITEM(v, 3,
3522 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
3523 PyStructSequence_SET_ITEM(v, 4,
3524 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
3525 PyStructSequence_SET_ITEM(v, 5,
3526 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
3527 PyStructSequence_SET_ITEM(v, 6,
3528 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
3529 PyStructSequence_SET_ITEM(v, 7,
3530 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
3531 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
3532 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
3533 #endif
3534
3535 return v;
3536 }
3537
3538 PyDoc_STRVAR(posix_fstatvfs__doc__,
3539 "fstatvfs(fd) -> statvfs result\n\n\
3540 Perform an fstatvfs system call on the given fd.");
3541
3542 static PyObject *
3543 posix_fstatvfs(PyObject *self, PyObject *args)
3544 {
3545 int fd, res;
3546 struct statvfs st;
3547
3548 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
3549 return NULL;
3550 Py_BEGIN_ALLOW_THREADS
3551 res = fstatvfs(fd, &st);
3552 Py_END_ALLOW_THREADS
3553 if (res != 0)
3554 return posix_error();
3555
3556 return _pystatvfs_fromstructstatvfs(st);
3557 }
3558 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
3559
3560
3561 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
3562 #include <sys/statvfs.h>
3563
3564 PyDoc_STRVAR(posix_statvfs__doc__,
3565 "statvfs(path) -> statvfs result\n\n\
3566 Perform a statvfs system call on the given path.");
3567
3568 static PyObject *
3569 posix_statvfs(PyObject *self, PyObject *args)
3570 {
3571 char *path;
3572 int res;
3573 struct statvfs st;
3574 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
3575 return NULL;
3576 Py_BEGIN_ALLOW_THREADS
3577 res = statvfs(path, &st);
3578 Py_END_ALLOW_THREADS
3579 if (res != 0)
3580 return posix_error_with_filename(path);
3581
3582 return _pystatvfs_fromstructstatvfs(st);
3583 }
3584 #endif /* HAVE_STATVFS */
3585
3586
3587 #ifdef HAVE_TEMPNAM
3588 PyDoc_STRVAR(posix_tempnam__doc__,
3589 "tempnam([dir[, prefix]]) -> string\n\n\
3590 Return a unique name for a temporary file.\n\
3591 The directory and a prefix may be specified as strings; they may be omitted\n\
3592 or None if not needed.");
3593
3594 static PyObject *
3595 posix_tempnam(PyObject *self, PyObject *args)
3596 {
3597 PyObject *result = NULL;
3598 char *dir = NULL;
3599 char *pfx = NULL;
3600 char *name;
3601
3602 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
3603 return NULL;
3604
3605 if (PyErr_Warn(PyExc_RuntimeWarning,
3606 "tempnam is a potential security risk to your program") < 0)
3607 return NULL;
3608
3609 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
3610 "use the tempfile module", 1) < 0)
3611 return NULL;
3612
3613 name = tempnam(dir, pfx);
3614 if (name == NULL)
3615 return PyErr_NoMemory();
3616 result = PyString_FromString(name);
3617 free(name);
3618 return result;
3619 }
3620 #endif
3621
3622
3623 #ifdef HAVE_TMPFILE
3624 PyDoc_STRVAR(posix_tmpfile__doc__,
3625 "tmpfile() -> file object\n\n\
3626 Create a temporary file with no directory entries.");
3627
3628 static PyObject *
3629 posix_tmpfile(PyObject *self, PyObject *noargs)
3630 {
3631 FILE *fp;
3632
3633 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
3634 "use the tempfile module", 1) < 0)
3635 return NULL;
3636
3637 fp = tmpfile();
3638 if (fp == NULL)
3639 return posix_error();
3640 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
3641 }
3642 #endif
3643
3644
3645 #ifdef HAVE_TMPNAM
3646 PyDoc_STRVAR(posix_tmpnam__doc__,
3647 "tmpnam() -> string\n\n\
3648 Return a unique name for a temporary file.");
3649
3650 static PyObject *
3651 posix_tmpnam(PyObject *self, PyObject *noargs)
3652 {
3653 char buffer[L_tmpnam];
3654 char *name;
3655
3656 if (PyErr_Warn(PyExc_RuntimeWarning,
3657 "tmpnam is a potential security risk to your program") < 0)
3658 return NULL;
3659
3660 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
3661 "use the tempfile module", 1) < 0)
3662 return NULL;
3663
3664 #ifdef USE_TMPNAM_R
3665 name = tmpnam_r(buffer);
3666 #else
3667 name = tmpnam(buffer);
3668 #endif
3669 if (name == NULL) {
3670 PyObject *err = Py_BuildValue("is", 0,
3671 #ifdef USE_TMPNAM_R
3672 "unexpected NULL from tmpnam_r"
3673 #else
3674 "unexpected NULL from tmpnam"
3675 #endif
3676 );
3677 PyErr_SetObject(PyExc_OSError, err);
3678 Py_XDECREF(err);
3679 return NULL;
3680 }
3681 return PyString_FromString(buffer);
3682 }
3683 #endif
3684
3685 PyDoc_STRVAR(posix_abort__doc__,
3686 "abort() -> does not return!\n\n\
3687 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
3688 in the hardest way possible on the hosting operating system.");
3689
3690 static PyObject *
3691 posix_abort(PyObject *self, PyObject *noargs)
3692 {
3693 abort();
3694 /*NOTREACHED*/
3695 Py_FatalError("abort() called from Python code didn't abort!");
3696 return NULL;
3697 }
3698
3699 static PyMethodDef posix_methods[] = {
3700 {"access", posix_access, METH_VARARGS, posix_access__doc__},
3701 #ifdef HAVE_TTYNAME
3702 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
3703 #endif
3704 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
3705 #ifdef HAVE_CHFLAGS
3706 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
3707 #endif /* HAVE_CHFLAGS */
3708 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
3709 #ifdef HAVE_FCHMOD
3710 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
3711 #endif /* HAVE_FCHMOD */
3712 #ifdef HAVE_CHOWN
3713 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
3714 #endif /* HAVE_CHOWN */
3715 #ifdef HAVE_LCHMOD
3716 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
3717 #endif /* HAVE_LCHMOD */
3718 #ifdef HAVE_FCHOWN
3719 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
3720 #endif /* HAVE_FCHOWN */
3721 #ifdef HAVE_LCHFLAGS
3722 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
3723 #endif /* HAVE_LCHFLAGS */
3724 #ifdef HAVE_LCHOWN
3725 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
3726 #endif /* HAVE_LCHOWN */
3727 #ifdef HAVE_CHROOT
3728 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
3729 #endif
3730 #ifdef HAVE_CTERMID
3731 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
3732 #endif
3733 #ifdef HAVE_GETCWD
3734 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
3735 #ifdef Py_USING_UNICODE
3736 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
3737 #endif
3738 #endif
3739 #ifdef HAVE_LINK
3740 {"link", posix_link, METH_VARARGS, posix_link__doc__},
3741 #endif /* HAVE_LINK */
3742 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
3743 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
3744 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
3745 #ifdef HAVE_NICE
3746 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
3747 #endif /* HAVE_NICE */
3748 #ifdef HAVE_READLINK
3749 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
3750 #endif /* HAVE_READLINK */
3751 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
3752 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
3753 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
3754 //{"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
3755 #ifdef HAVE_SYMLINK
3756 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
3757 #endif /* HAVE_SYMLINK */
3758 #ifdef HAVE_SYSTEM
3759 {"system", posix_system, METH_VARARGS, posix_system__doc__},
3760 #endif
3761 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
3762 #ifdef HAVE_UNAME
3763 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
3764 #endif /* HAVE_UNAME */
3765 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
3766 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
3767 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
3768 #ifdef HAVE_TIMES
3769 {"times", posix_times, METH_NOARGS, posix_times__doc__},
3770 #endif /* HAVE_TIMES */
3771 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
3772 #ifdef HAVE_EXECV
3773 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
3774 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
3775 #endif /* HAVE_EXECV */
3776 #ifdef HAVE_SPAWNV
3777 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
3778 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
3779 #if defined(PYOS_OS2)
3780 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
3781 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
3782 #endif /* PYOS_OS2 */
3783 #endif /* HAVE_SPAWNV */
3784 #ifdef HAVE_FORK1
3785 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
3786 #endif /* HAVE_FORK1 */
3787 #ifdef HAVE_FORK
3788 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
3789 #endif /* HAVE_FORK */
3790 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3791 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
3792 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
3793 #ifdef HAVE_FORKPTY
3794 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
3795 #endif /* HAVE_FORKPTY */
3796 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
3797 #ifdef HAVE_GETPGRP
3798 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
3799 #endif /* HAVE_GETPGRP */
3800 #ifdef HAVE_GETPPID
3801 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
3802 #endif /* HAVE_GETPPID */
3803 #ifdef HAVE_GETLOGIN
3804 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
3805 #endif
3806 #ifdef HAVE_KILL
3807 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
3808 #endif /* HAVE_KILL */
3809 #ifdef HAVE_KILLPG
3810 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
3811 #endif /* HAVE_KILLPG */
3812 #ifdef HAVE_PLOCK
3813 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
3814 #endif /* HAVE_PLOCK */
3815 #ifdef HAVE_POPEN
3816 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
3817 #endif /* HAVE_POPEN */
3818 #ifdef HAVE_SETGROUPS
3819 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
3820 #endif /* HAVE_SETGROUPS */
3821 #ifdef HAVE_INITGROUPS
3822 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
3823 #endif /* HAVE_INITGROUPS */
3824 #ifdef HAVE_GETPGID
3825 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
3826 #endif /* HAVE_GETPGID */
3827 #ifdef HAVE_SETPGRP
3828 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
3829 #endif /* HAVE_SETPGRP */
3830 #ifdef HAVE_WAIT
3831 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
3832 #endif /* HAVE_WAIT */
3833 #ifdef HAVE_WAIT3
3834 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
3835 #endif /* HAVE_WAIT3 */
3836 #ifdef HAVE_WAIT4
3837 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
3838 #endif /* HAVE_WAIT4 */
3839 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
3840 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
3841 #endif /* HAVE_WAITPID */
3842 #ifdef HAVE_GETSID
3843 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
3844 #endif /* HAVE_GETSID */
3845 #ifdef HAVE_SETSID
3846 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
3847 #endif /* HAVE_SETSID */
3848 #ifdef HAVE_SETPGID
3849 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
3850 #endif /* HAVE_SETPGID */
3851 #ifdef HAVE_TCGETPGRP
3852 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
3853 #endif /* HAVE_TCGETPGRP */
3854 #ifdef HAVE_TCSETPGRP
3855 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
3856 #endif /* HAVE_TCSETPGRP */
3857 {"open", posix_open, METH_VARARGS, posix_open__doc__},
3858 {"close", posix_close, METH_VARARGS, posix_close__doc__},
3859 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
3860 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
3861 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
3862 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
3863 {"read", posix_read, METH_VARARGS, posix_read__doc__},
3864 {"write", posix_write, METH_VARARGS, posix_write__doc__},
3865 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
3866 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
3867 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
3868 #ifdef HAVE_PIPE
3869 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
3870 #endif
3871 #ifdef HAVE_MKFIFO
3872 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
3873 #endif
3874 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
3875 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
3876 #endif
3877 #ifdef HAVE_DEVICE_MACROS
3878 {"major", posix_major, METH_VARARGS, posix_major__doc__},
3879 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
3880 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
3881 #endif
3882 #ifdef HAVE_FTRUNCATE
3883 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
3884 #endif
3885 #ifdef HAVE_PUTENV
3886 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
3887 #endif
3888 #ifdef HAVE_UNSETENV
3889 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
3890 #endif
3891 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
3892 #ifdef HAVE_FCHDIR
3893 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
3894 #endif
3895 #ifdef HAVE_FSYNC
3896 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
3897 #endif
3898 #ifdef HAVE_FDATASYNC
3899 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
3900 #endif
3901 #ifdef HAVE_SYS_WAIT_H
3902 #ifdef WCOREDUMP
3903 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
3904 #endif /* WCOREDUMP */
3905 #ifdef WIFCONTINUED
3906 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
3907 #endif /* WIFCONTINUED */
3908 #ifdef WIFSTOPPED
3909 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
3910 #endif /* WIFSTOPPED */
3911 #ifdef WIFSIGNALED
3912 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
3913 #endif /* WIFSIGNALED */
3914 #ifdef WIFEXITED
3915 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
3916 #endif /* WIFEXITED */
3917 #ifdef WEXITSTATUS
3918 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
3919 #endif /* WEXITSTATUS */
3920 #ifdef WTERMSIG
3921 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
3922 #endif /* WTERMSIG */
3923 #ifdef WSTOPSIG
3924 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
3925 #endif /* WSTOPSIG */
3926 #endif /* HAVE_SYS_WAIT_H */
3927 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
3928 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
3929 #endif
3930 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
3931 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
3932 #endif
3933 #ifdef HAVE_TMPFILE
3934 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
3935 #endif
3936 #ifdef HAVE_TEMPNAM
3937 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
3938 #endif
3939 #ifdef HAVE_TMPNAM
3940 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
3941 #endif
3942 #ifdef HAVE_CONFSTR
3943 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
3944 #endif
3945 #ifdef HAVE_SYSCONF
3946 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
3947 #endif
3948 #ifdef HAVE_FPATHCONF
3949 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
3950 #endif
3951 #ifdef HAVE_PATHCONF
3952 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
3953 #endif
3954 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
3955
3956 {NULL, NULL} /* Sentinel */
3957 };
3958
3959
3960 static int
3961 ins(PyObject *module, char *symbol, long value)
3962 {
3963 return PyModule_AddIntConstant(module, symbol, value);
3964 }
3965
3966 static int
3967 all_ins(PyObject *d)
3968 {
3969 #ifdef F_OK
3970 if (ins(d, "F_OK", (long)F_OK)) return -1;
3971 #endif
3972 #ifdef R_OK
3973 if (ins(d, "R_OK", (long)R_OK)) return -1;
3974 #endif
3975 #ifdef W_OK
3976 if (ins(d, "W_OK", (long)W_OK)) return -1;
3977 #endif
3978 #ifdef X_OK
3979 if (ins(d, "X_OK", (long)X_OK)) return -1;
3980 #endif
3981 #ifdef NGROUPS_MAX
3982 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
3983 #endif
3984 #ifdef TMP_MAX
3985 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
3986 #endif
3987 #ifdef WCONTINUED
3988 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
3989 #endif
3990 #ifdef WNOHANG
3991 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
3992 #endif
3993 #ifdef WUNTRACED
3994 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
3995 #endif
3996 #ifdef O_RDONLY
3997 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
3998 #endif
3999 #ifdef O_WRONLY
4000 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
4001 #endif
4002 #ifdef O_RDWR
4003 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
4004 #endif
4005 #ifdef O_NDELAY
4006 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
4007 #endif
4008 #ifdef O_NONBLOCK
4009 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
4010 #endif
4011 #ifdef O_APPEND
4012 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
4013 #endif
4014 #ifdef O_DSYNC
4015 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
4016 #endif
4017 #ifdef O_RSYNC
4018 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
4019 #endif
4020 #ifdef O_SYNC
4021 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
4022 #endif
4023 #ifdef O_NOCTTY
4024 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
4025 #endif
4026 #ifdef O_CREAT
4027 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
4028 #endif
4029 #ifdef O_EXCL
4030 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
4031 #endif
4032 #ifdef O_TRUNC
4033 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
4034 #endif
4035 #ifdef O_BINARY
4036 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
4037 #endif
4038 #ifdef O_TEXT
4039 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
4040 #endif
4041 #ifdef O_LARGEFILE
4042 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
4043 #endif
4044 #ifdef O_SHLOCK
4045 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
4046 #endif
4047 #ifdef O_EXLOCK
4048 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
4049 #endif
4050
4051 /* MS Windows */
4052 #ifdef O_NOINHERIT
4053 /* Don't inherit in child processes. */
4054 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
4055 #endif
4056 #ifdef _O_SHORT_LIVED
4057 /* Optimize for short life (keep in memory). */
4058 /* MS forgot to define this one with a non-underscore form too. */
4059 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
4060 #endif
4061 #ifdef O_TEMPORARY
4062 /* Automatically delete when last handle is closed. */
4063 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
4064 #endif
4065 #ifdef O_RANDOM
4066 /* Optimize for random access. */
4067 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
4068 #endif
4069 #ifdef O_SEQUENTIAL
4070 /* Optimize for sequential access. */
4071 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
4072 #endif
4073
4074 /* GNU extensions. */
4075 #ifdef O_ASYNC
4076 /* Send a SIGIO signal whenever input or output
4077 becomes available on file descriptor */
4078 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
4079 #endif
4080 #ifdef O_DIRECT
4081 /* Direct disk access. */
4082 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
4083 #endif
4084 #ifdef O_DIRECTORY
4085 /* Must be a directory. */
4086 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
4087 #endif
4088 #ifdef O_NOFOLLOW
4089 /* Do not follow links. */
4090 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
4091 #endif
4092 #ifdef O_NOATIME
4093 /* Do not update the access time. */
4094 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
4095 #endif
4096
4097 /* These come from sysexits.h */
4098 #ifdef EX_OK
4099 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
4100 #endif /* EX_OK */
4101 #ifdef EX_USAGE
4102 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
4103 #endif /* EX_USAGE */
4104 #ifdef EX_DATAERR
4105 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
4106 #endif /* EX_DATAERR */
4107 #ifdef EX_NOINPUT
4108 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
4109 #endif /* EX_NOINPUT */
4110 #ifdef EX_NOUSER
4111 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
4112 #endif /* EX_NOUSER */
4113 #ifdef EX_NOHOST
4114 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
4115 #endif /* EX_NOHOST */
4116 #ifdef EX_UNAVAILABLE
4117 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
4118 #endif /* EX_UNAVAILABLE */
4119 #ifdef EX_SOFTWARE
4120 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
4121 #endif /* EX_SOFTWARE */
4122 #ifdef EX_OSERR
4123 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
4124 #endif /* EX_OSERR */
4125 #ifdef EX_OSFILE
4126 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
4127 #endif /* EX_OSFILE */
4128 #ifdef EX_CANTCREAT
4129 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
4130 #endif /* EX_CANTCREAT */
4131 #ifdef EX_IOERR
4132 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
4133 #endif /* EX_IOERR */
4134 #ifdef EX_TEMPFAIL
4135 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
4136 #endif /* EX_TEMPFAIL */
4137 #ifdef EX_PROTOCOL
4138 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
4139 #endif /* EX_PROTOCOL */
4140 #ifdef EX_NOPERM
4141 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
4142 #endif /* EX_NOPERM */
4143 #ifdef EX_CONFIG
4144 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
4145 #endif /* EX_CONFIG */
4146 #ifdef EX_NOTFOUND
4147 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
4148 #endif /* EX_NOTFOUND */
4149
4150 #ifdef HAVE_SPAWNV
4151 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
4152 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
4153 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
4154 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
4155 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
4156 #endif
4157 return 0;
4158 }
4159
4160 #define INITFUNC initedk2
4161 #define MODNAME "edk2"
4162
4163 PyMODINIT_FUNC
4164 INITFUNC(void)
4165 {
4166 PyObject *m;
4167
4168 #ifndef UEFI_C_SOURCE
4169 PyObject *v;
4170 #endif
4171
4172 m = Py_InitModule3(MODNAME,
4173 posix_methods,
4174 edk2__doc__);
4175 if (m == NULL)
4176 return;
4177
4178 #ifndef UEFI_C_SOURCE
4179 /* Initialize environ dictionary */
4180 v = convertenviron();
4181 Py_XINCREF(v);
4182 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
4183 return;
4184 Py_DECREF(v);
4185 #endif /* UEFI_C_SOURCE */
4186
4187 if (all_ins(m))
4188 return;
4189
4190 if (setup_confname_tables(m))
4191 return;
4192
4193 Py_INCREF(PyExc_OSError);
4194 PyModule_AddObject(m, "error", PyExc_OSError);
4195
4196 #ifdef HAVE_PUTENV
4197 if (posix_putenv_garbage == NULL)
4198 posix_putenv_garbage = PyDict_New();
4199 #endif
4200
4201 if (!initialized) {
4202 stat_result_desc.name = MODNAME ".stat_result";
4203 stat_result_desc.fields[2].name = PyStructSequence_UnnamedField;
4204 stat_result_desc.fields[3].name = PyStructSequence_UnnamedField;
4205 stat_result_desc.fields[4].name = PyStructSequence_UnnamedField;
4206 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
4207 structseq_new = StatResultType.tp_new;
4208 StatResultType.tp_new = statresult_new;
4209
4210 //statvfs_result_desc.name = MODNAME ".statvfs_result";
4211 //PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
4212 #ifdef NEED_TICKS_PER_SECOND
4213 # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
4214 ticks_per_second = sysconf(_SC_CLK_TCK);
4215 # elif defined(HZ)
4216 ticks_per_second = HZ;
4217 # else
4218 ticks_per_second = 60; /* magic fallback value; may be bogus */
4219 # endif
4220 #endif
4221 }
4222 Py_INCREF((PyObject*) &StatResultType);
4223 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
4224 //Py_INCREF((PyObject*) &StatVFSResultType);
4225 //PyModule_AddObject(m, "statvfs_result",
4226 // (PyObject*) &StatVFSResultType);
4227 initialized = 1;
4228
4229 }
4230
4231 #ifdef __cplusplus
4232 }
4233 #endif
4234
4235