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) 2015, Daryl McDaniel. All rights reserved.<BR>
6 Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials are licensed and made available under
8 the terms and conditions of the BSD License that accompanies this distribution.
9 The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 **/
15 #define PY_SSIZE_T_CLEAN
16
17 #include "Python.h"
18 #include "structseq.h"
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <wchar.h>
23 #include <sys/syslimits.h>
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 PyDoc_STRVAR(edk2__doc__,
30 "This module provides access to UEFI firmware functionality that is\n\
31 standardized by the C Standard and the POSIX standard (a thinly\n\
32 disguised Unix interface). Refer to the library manual and\n\
33 corresponding UEFI Specification entries for more information on calls.");
34
35 #ifndef Py_USING_UNICODE
36 /* This is used in signatures of functions. */
37 #define Py_UNICODE void
38 #endif
39
40 #ifdef HAVE_SYS_TYPES_H
41 #include <sys/types.h>
42 #endif /* HAVE_SYS_TYPES_H */
43
44 #ifdef HAVE_SYS_STAT_H
45 #include <sys/stat.h>
46 #endif /* HAVE_SYS_STAT_H */
47
48 #ifdef HAVE_SYS_WAIT_H
49 #include <sys/wait.h> /* For WNOHANG */
50 #endif
51
52 #ifdef HAVE_SIGNAL_H
53 #include <signal.h>
54 #endif
55
56 #ifdef HAVE_FCNTL_H
57 #include <fcntl.h>
58 #endif /* HAVE_FCNTL_H */
59
60 #ifdef HAVE_GRP_H
61 #include <grp.h>
62 #endif
63
64 #ifdef HAVE_SYSEXITS_H
65 #include <sysexits.h>
66 #endif /* HAVE_SYSEXITS_H */
67
68 #ifdef HAVE_SYS_LOADAVG_H
69 #include <sys/loadavg.h>
70 #endif
71
72 #ifdef HAVE_UTIME_H
73 #include <utime.h>
74 #endif /* HAVE_UTIME_H */
75
76 #ifdef HAVE_SYS_UTIME_H
77 #include <sys/utime.h>
78 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
79 #endif /* HAVE_SYS_UTIME_H */
80
81 #ifdef HAVE_SYS_TIMES_H
82 #include <sys/times.h>
83 #endif /* HAVE_SYS_TIMES_H */
84
85 #ifdef HAVE_SYS_PARAM_H
86 #include <sys/param.h>
87 #endif /* HAVE_SYS_PARAM_H */
88
89 #ifdef HAVE_SYS_UTSNAME_H
90 #include <sys/utsname.h>
91 #endif /* HAVE_SYS_UTSNAME_H */
92
93 #ifdef HAVE_DIRENT_H
94 #include <dirent.h>
95 #define NAMLEN(dirent) wcslen((dirent)->FileName)
96 #else
97 #define dirent direct
98 #define NAMLEN(dirent) (dirent)->d_namlen
99 #ifdef HAVE_SYS_NDIR_H
100 #include <sys/ndir.h>
101 #endif
102 #ifdef HAVE_SYS_DIR_H
103 #include <sys/dir.h>
104 #endif
105 #ifdef HAVE_NDIR_H
106 #include <ndir.h>
107 #endif
108 #endif
109
110 #ifndef MAXPATHLEN
111 #if defined(PATH_MAX) && PATH_MAX > 1024
112 #define MAXPATHLEN PATH_MAX
113 #else
114 #define MAXPATHLEN 1024
115 #endif
116 #endif /* MAXPATHLEN */
117
118 #define WAIT_TYPE int
119 #define WAIT_STATUS_INT(s) (s)
120
121 /* Issue #1983: pid_t can be longer than a C long on some systems */
122 #if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
123 #define PARSE_PID "i"
124 #define PyLong_FromPid PyInt_FromLong
125 #define PyLong_AsPid PyInt_AsLong
126 #elif SIZEOF_PID_T == SIZEOF_LONG
127 #define PARSE_PID "l"
128 #define PyLong_FromPid PyInt_FromLong
129 #define PyLong_AsPid PyInt_AsLong
130 #elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
131 #define PARSE_PID "L"
132 #define PyLong_FromPid PyLong_FromLongLong
133 #define PyLong_AsPid PyInt_AsLongLong
134 #else
135 #error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
136 #endif /* SIZEOF_PID_T */
137
138 /* Don't use the "_r" form if we don't need it (also, won't have a
139 prototype for it, at least on Solaris -- maybe others as well?). */
140 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
141 #define USE_CTERMID_R
142 #endif
143
144 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
145 #define USE_TMPNAM_R
146 #endif
147
148 /* choose the appropriate stat and fstat functions and return structs */
149 #undef STAT
150 #undef FSTAT
151 #undef STRUCT_STAT
152 #define STAT stat
153 #define FSTAT fstat
154 #define STRUCT_STAT struct stat
155
156 /* dummy version. _PyVerify_fd() is already defined in fileobject.h */
157 #define _PyVerify_fd_dup2(A, B) (1)
158
159 #ifndef UEFI_C_SOURCE
160 /* Return a dictionary corresponding to the POSIX environment table */
161 extern char **environ;
162
163 static PyObject *
convertenviron(void)164 convertenviron(void)
165 {
166 PyObject *d;
167 char **e;
168 d = PyDict_New();
169 if (d == NULL)
170 return NULL;
171 if (environ == NULL)
172 return d;
173 /* This part ignores errors */
174 for (e = environ; *e != NULL; e++) {
175 PyObject *k;
176 PyObject *v;
177 char *p = strchr(*e, '=');
178 if (p == NULL)
179 continue;
180 k = PyString_FromStringAndSize(*e, (int)(p-*e));
181 if (k == NULL) {
182 PyErr_Clear();
183 continue;
184 }
185 v = PyString_FromString(p+1);
186 if (v == NULL) {
187 PyErr_Clear();
188 Py_DECREF(k);
189 continue;
190 }
191 if (PyDict_GetItem(d, k) == NULL) {
192 if (PyDict_SetItem(d, k, v) != 0)
193 PyErr_Clear();
194 }
195 Py_DECREF(k);
196 Py_DECREF(v);
197 }
198 return d;
199 }
200 #endif /* UEFI_C_SOURCE */
201
202 /* Set a POSIX-specific error from errno, and return NULL */
203
204 static PyObject *
edk2_error(void)205 edk2_error(void)
206 {
207 return PyErr_SetFromErrno(PyExc_OSError);
208 }
209 static PyObject *
edk2_error_with_filename(char * name)210 edk2_error_with_filename(char* name)
211 {
212 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
213 }
214
215
216 static PyObject *
edk2_error_with_allocated_filename(char * name)217 edk2_error_with_allocated_filename(char* name)
218 {
219 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
220 PyMem_Free(name);
221 return rc;
222 }
223
224 /* POSIX generic methods */
225
226 #ifndef UEFI_C_SOURCE
227 static PyObject *
edk2_fildes(PyObject * fdobj,int (* func)(int))228 edk2_fildes(PyObject *fdobj, int (*func)(int))
229 {
230 int fd;
231 int res;
232 fd = PyObject_AsFileDescriptor(fdobj);
233 if (fd < 0)
234 return NULL;
235 if (!_PyVerify_fd(fd))
236 return edk2_error();
237 Py_BEGIN_ALLOW_THREADS
238 res = (*func)(fd);
239 Py_END_ALLOW_THREADS
240 if (res < 0)
241 return edk2_error();
242 Py_INCREF(Py_None);
243 return Py_None;
244 }
245 #endif /* UEFI_C_SOURCE */
246
247 static PyObject *
edk2_1str(PyObject * args,char * format,int (* func)(const char *))248 edk2_1str(PyObject *args, char *format, int (*func)(const char*))
249 {
250 char *path1 = NULL;
251 int res;
252 if (!PyArg_ParseTuple(args, format,
253 Py_FileSystemDefaultEncoding, &path1))
254 return NULL;
255 Py_BEGIN_ALLOW_THREADS
256 res = (*func)(path1);
257 Py_END_ALLOW_THREADS
258 if (res < 0)
259 return edk2_error_with_allocated_filename(path1);
260 PyMem_Free(path1);
261 Py_INCREF(Py_None);
262 return Py_None;
263 }
264
265 static PyObject *
edk2_2str(PyObject * args,char * format,int (* func)(const char *,const char *))266 edk2_2str(PyObject *args,
267 char *format,
268 int (*func)(const char *, const char *))
269 {
270 char *path1 = NULL, *path2 = NULL;
271 int res;
272 if (!PyArg_ParseTuple(args, format,
273 Py_FileSystemDefaultEncoding, &path1,
274 Py_FileSystemDefaultEncoding, &path2))
275 return NULL;
276 Py_BEGIN_ALLOW_THREADS
277 res = (*func)(path1, path2);
278 Py_END_ALLOW_THREADS
279 PyMem_Free(path1);
280 PyMem_Free(path2);
281 if (res != 0)
282 /* XXX how to report both path1 and path2??? */
283 return edk2_error();
284 Py_INCREF(Py_None);
285 return Py_None;
286 }
287
288 PyDoc_STRVAR(stat_result__doc__,
289 "stat_result: Result from stat or lstat.\n\n\
290 This object may be accessed either as a tuple of\n\
291 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
292 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
293 \n\
294 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
295 or st_flags, they are available as attributes only.\n\
296 \n\
297 See os.stat for more information.");
298
299 static PyStructSequence_Field stat_result_fields[] = {
300 {"st_mode", "protection bits"},
301 //{"st_ino", "inode"},
302 //{"st_dev", "device"},
303 //{"st_nlink", "number of hard links"},
304 //{"st_uid", "user ID of owner"},
305 //{"st_gid", "group ID of owner"},
306 {"st_size", "total size, in bytes"},
307 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
308 {NULL, "integer time of last access"},
309 {NULL, "integer time of last modification"},
310 {NULL, "integer time of last change"},
311 {"st_atime", "time of last access"},
312 {"st_mtime", "time of last modification"},
313 {"st_ctime", "time of last change"},
314 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
315 {"st_blksize", "blocksize for filesystem I/O"},
316 #endif
317 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
318 {"st_blocks", "number of blocks allocated"},
319 #endif
320 #ifdef HAVE_STRUCT_STAT_ST_RDEV
321 {"st_rdev", "device type (if inode device)"},
322 #endif
323 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
324 {"st_flags", "user defined flags for file"},
325 #endif
326 #ifdef HAVE_STRUCT_STAT_ST_GEN
327 {"st_gen", "generation number"},
328 #endif
329 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
330 {"st_birthtime", "time of creation"},
331 #endif
332 {0}
333 };
334
335 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
336 #define ST_BLKSIZE_IDX 8
337 #else
338 #define ST_BLKSIZE_IDX 12
339 #endif
340
341 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
342 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
343 #else
344 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
345 #endif
346
347 #ifdef HAVE_STRUCT_STAT_ST_RDEV
348 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
349 #else
350 #define ST_RDEV_IDX ST_BLOCKS_IDX
351 #endif
352
353 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
354 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
355 #else
356 #define ST_FLAGS_IDX ST_RDEV_IDX
357 #endif
358
359 #ifdef HAVE_STRUCT_STAT_ST_GEN
360 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
361 #else
362 #define ST_GEN_IDX ST_FLAGS_IDX
363 #endif
364
365 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
366 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
367 #else
368 #define ST_BIRTHTIME_IDX ST_GEN_IDX
369 #endif
370
371 static PyStructSequence_Desc stat_result_desc = {
372 "stat_result", /* name */
373 stat_result__doc__, /* doc */
374 stat_result_fields,
375 10
376 };
377
378 #ifndef UEFI_C_SOURCE /* Not in UEFI */
379 PyDoc_STRVAR(statvfs_result__doc__,
380 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
381 This object may be accessed either as a tuple of\n\
382 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
383 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
384 \n\
385 See os.statvfs for more information.");
386
387 static PyStructSequence_Field statvfs_result_fields[] = {
388 {"f_bsize", },
389 {"f_frsize", },
390 {"f_blocks", },
391 {"f_bfree", },
392 {"f_bavail", },
393 {"f_files", },
394 {"f_ffree", },
395 {"f_favail", },
396 {"f_flag", },
397 {"f_namemax",},
398 {0}
399 };
400
401 static PyStructSequence_Desc statvfs_result_desc = {
402 "statvfs_result", /* name */
403 statvfs_result__doc__, /* doc */
404 statvfs_result_fields,
405 10
406 };
407
408 static PyTypeObject StatVFSResultType;
409 #endif
410
411 static int initialized;
412 static PyTypeObject StatResultType;
413 static newfunc structseq_new;
414
415 static PyObject *
statresult_new(PyTypeObject * type,PyObject * args,PyObject * kwds)416 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
417 {
418 PyStructSequence *result;
419 int i;
420
421 result = (PyStructSequence*)structseq_new(type, args, kwds);
422 if (!result)
423 return NULL;
424 /* If we have been initialized from a tuple,
425 st_?time might be set to None. Initialize it
426 from the int slots. */
427 for (i = 7; i <= 9; i++) {
428 if (result->ob_item[i+3] == Py_None) {
429 Py_DECREF(Py_None);
430 Py_INCREF(result->ob_item[i]);
431 result->ob_item[i+3] = result->ob_item[i];
432 }
433 }
434 return (PyObject*)result;
435 }
436
437
438
439 /* If true, st_?time is float. */
440 #if defined(UEFI_C_SOURCE)
441 static int _stat_float_times = 0;
442 #else
443 static int _stat_float_times = 1;
444
445 PyDoc_STRVAR(stat_float_times__doc__,
446 "stat_float_times([newval]) -> oldval\n\n\
447 Determine whether os.[lf]stat represents time stamps as float objects.\n\
448 If newval is True, future calls to stat() return floats, if it is False,\n\
449 future calls return ints. \n\
450 If newval is omitted, return the current setting.\n");
451
452 static PyObject*
stat_float_times(PyObject * self,PyObject * args)453 stat_float_times(PyObject* self, PyObject *args)
454 {
455 int newval = -1;
456
457 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
458 return NULL;
459 if (newval == -1)
460 /* Return old value */
461 return PyBool_FromLong(_stat_float_times);
462 _stat_float_times = newval;
463 Py_INCREF(Py_None);
464 return Py_None;
465 }
466 #endif /* UEFI_C_SOURCE */
467
468 static void
fill_time(PyObject * v,int index,time_t sec,unsigned long nsec)469 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
470 {
471 PyObject *fval,*ival;
472 #if SIZEOF_TIME_T > SIZEOF_LONG
473 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
474 #else
475 ival = PyInt_FromLong((long)sec);
476 #endif
477 if (!ival)
478 return;
479 if (_stat_float_times) {
480 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
481 } else {
482 fval = ival;
483 Py_INCREF(fval);
484 }
485 PyStructSequence_SET_ITEM(v, index, ival);
486 PyStructSequence_SET_ITEM(v, index+3, fval);
487 }
488
489 /* pack a system stat C structure into the Python stat tuple
490 (used by edk2_stat() and edk2_fstat()) */
491 static PyObject*
_pystat_fromstructstat(STRUCT_STAT * st)492 _pystat_fromstructstat(STRUCT_STAT *st)
493 {
494 unsigned long ansec, mnsec, cnsec;
495 PyObject *v = PyStructSequence_New(&StatResultType);
496 if (v == NULL)
497 return NULL;
498
499 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
500 PyStructSequence_SET_ITEM(v, 1,
501 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
502
503 ansec = mnsec = cnsec = 0;
504 /* The index used by fill_time is the index of the integer time.
505 fill_time will add 3 to the index to get the floating time index.
506 */
507 fill_time(v, 2, st->st_atime, ansec);
508 fill_time(v, 3, st->st_mtime, mnsec);
509 fill_time(v, 4, st->st_mtime, cnsec);
510
511 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
512 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
513 PyInt_FromLong((long)st->st_blksize));
514 #endif
515 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
516 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
517 PyInt_FromLong((long)st->st_blocks));
518 #endif
519 #ifdef HAVE_STRUCT_STAT_ST_RDEV
520 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
521 PyInt_FromLong((long)st->st_rdev));
522 #endif
523 #ifdef HAVE_STRUCT_STAT_ST_GEN
524 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
525 PyInt_FromLong((long)st->st_gen));
526 #endif
527 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
528 {
529 PyObject *val;
530 unsigned long bsec,bnsec;
531 bsec = (long)st->st_birthtime;
532 #ifdef HAVE_STAT_TV_NSEC2
533 bnsec = st->st_birthtimespec.tv_nsec;
534 #else
535 bnsec = 0;
536 #endif
537 if (_stat_float_times) {
538 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
539 } else {
540 val = PyInt_FromLong((long)bsec);
541 }
542 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
543 val);
544 }
545 #endif
546 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
547 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
548 PyInt_FromLong((long)st->st_flags));
549 #endif
550
551 if (PyErr_Occurred()) {
552 Py_DECREF(v);
553 return NULL;
554 }
555
556 return v;
557 }
558
559 static PyObject *
edk2_do_stat(PyObject * self,PyObject * args,char * format,int (* statfunc)(const char *,STRUCT_STAT *),char * wformat,int (* wstatfunc)(const Py_UNICODE *,STRUCT_STAT *))560 edk2_do_stat(PyObject *self, PyObject *args,
561 char *format,
562 int (*statfunc)(const char *, STRUCT_STAT *),
563 char *wformat,
564 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
565 {
566 STRUCT_STAT st;
567 char *path = NULL; /* pass this to stat; do not free() it */
568 char *pathfree = NULL; /* this memory must be free'd */
569 int res;
570 PyObject *result;
571
572 if (!PyArg_ParseTuple(args, format,
573 Py_FileSystemDefaultEncoding, &path))
574 return NULL;
575 pathfree = path;
576
577 Py_BEGIN_ALLOW_THREADS
578 res = (*statfunc)(path, &st);
579 Py_END_ALLOW_THREADS
580
581 if (res != 0) {
582 result = edk2_error_with_filename(pathfree);
583 }
584 else
585 result = _pystat_fromstructstat(&st);
586
587 PyMem_Free(pathfree);
588 return result;
589 }
590
591 /* POSIX methods */
592
593 PyDoc_STRVAR(edk2_access__doc__,
594 "access(path, mode) -> True if granted, False otherwise\n\n\
595 Use the real uid/gid to test for access to a path. Note that most\n\
596 operations will use the effective uid/gid, therefore this routine can\n\
597 be used in a suid/sgid environment to test if the invoking user has the\n\
598 specified access to the path. The mode argument can be F_OK to test\n\
599 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
600
601 static PyObject *
edk2_access(PyObject * self,PyObject * args)602 edk2_access(PyObject *self, PyObject *args)
603 {
604 char *path;
605 int mode;
606
607 int res;
608 if (!PyArg_ParseTuple(args, "eti:access",
609 Py_FileSystemDefaultEncoding, &path, &mode))
610 return NULL;
611 Py_BEGIN_ALLOW_THREADS
612 res = access(path, mode);
613 Py_END_ALLOW_THREADS
614 PyMem_Free(path);
615 return PyBool_FromLong(res == 0);
616 }
617
618 #ifndef F_OK
619 #define F_OK 0
620 #endif
621 #ifndef R_OK
622 #define R_OK 4
623 #endif
624 #ifndef W_OK
625 #define W_OK 2
626 #endif
627 #ifndef X_OK
628 #define X_OK 1
629 #endif
630
631 PyDoc_STRVAR(edk2_chdir__doc__,
632 "chdir(path)\n\n\
633 Change the current working directory to the specified path.");
634
635 static PyObject *
edk2_chdir(PyObject * self,PyObject * args)636 edk2_chdir(PyObject *self, PyObject *args)
637 {
638 return edk2_1str(args, "et:chdir", chdir);
639 }
640
641 PyDoc_STRVAR(edk2_chmod__doc__,
642 "chmod(path, mode)\n\n\
643 Change the access permissions of a file.");
644
645 static PyObject *
edk2_chmod(PyObject * self,PyObject * args)646 edk2_chmod(PyObject *self, PyObject *args)
647 {
648 char *path = NULL;
649 int i;
650 int res;
651 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
652 &path, &i))
653 return NULL;
654 Py_BEGIN_ALLOW_THREADS
655 res = chmod(path, i);
656 Py_END_ALLOW_THREADS
657 if (res < 0)
658 return edk2_error_with_allocated_filename(path);
659 PyMem_Free(path);
660 Py_INCREF(Py_None);
661 return Py_None;
662 }
663
664 #ifdef HAVE_FCHMOD
665 PyDoc_STRVAR(edk2_fchmod__doc__,
666 "fchmod(fd, mode)\n\n\
667 Change the access permissions of the file given by file\n\
668 descriptor fd.");
669
670 static PyObject *
edk2_fchmod(PyObject * self,PyObject * args)671 edk2_fchmod(PyObject *self, PyObject *args)
672 {
673 int fd, mode, res;
674 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
675 return NULL;
676 Py_BEGIN_ALLOW_THREADS
677 res = fchmod(fd, mode);
678 Py_END_ALLOW_THREADS
679 if (res < 0)
680 return edk2_error();
681 Py_RETURN_NONE;
682 }
683 #endif /* HAVE_FCHMOD */
684
685 #ifdef HAVE_LCHMOD
686 PyDoc_STRVAR(edk2_lchmod__doc__,
687 "lchmod(path, mode)\n\n\
688 Change the access permissions of a file. If path is a symlink, this\n\
689 affects the link itself rather than the target.");
690
691 static PyObject *
edk2_lchmod(PyObject * self,PyObject * args)692 edk2_lchmod(PyObject *self, PyObject *args)
693 {
694 char *path = NULL;
695 int i;
696 int res;
697 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
698 &path, &i))
699 return NULL;
700 Py_BEGIN_ALLOW_THREADS
701 res = lchmod(path, i);
702 Py_END_ALLOW_THREADS
703 if (res < 0)
704 return edk2_error_with_allocated_filename(path);
705 PyMem_Free(path);
706 Py_RETURN_NONE;
707 }
708 #endif /* HAVE_LCHMOD */
709
710
711 #ifdef HAVE_CHFLAGS
712 PyDoc_STRVAR(edk2_chflags__doc__,
713 "chflags(path, flags)\n\n\
714 Set file flags.");
715
716 static PyObject *
edk2_chflags(PyObject * self,PyObject * args)717 edk2_chflags(PyObject *self, PyObject *args)
718 {
719 char *path;
720 unsigned long flags;
721 int res;
722 if (!PyArg_ParseTuple(args, "etk:chflags",
723 Py_FileSystemDefaultEncoding, &path, &flags))
724 return NULL;
725 Py_BEGIN_ALLOW_THREADS
726 res = chflags(path, flags);
727 Py_END_ALLOW_THREADS
728 if (res < 0)
729 return edk2_error_with_allocated_filename(path);
730 PyMem_Free(path);
731 Py_INCREF(Py_None);
732 return Py_None;
733 }
734 #endif /* HAVE_CHFLAGS */
735
736 #ifdef HAVE_LCHFLAGS
737 PyDoc_STRVAR(edk2_lchflags__doc__,
738 "lchflags(path, flags)\n\n\
739 Set file flags.\n\
740 This function will not follow symbolic links.");
741
742 static PyObject *
edk2_lchflags(PyObject * self,PyObject * args)743 edk2_lchflags(PyObject *self, PyObject *args)
744 {
745 char *path;
746 unsigned long flags;
747 int res;
748 if (!PyArg_ParseTuple(args, "etk:lchflags",
749 Py_FileSystemDefaultEncoding, &path, &flags))
750 return NULL;
751 Py_BEGIN_ALLOW_THREADS
752 res = lchflags(path, flags);
753 Py_END_ALLOW_THREADS
754 if (res < 0)
755 return edk2_error_with_allocated_filename(path);
756 PyMem_Free(path);
757 Py_INCREF(Py_None);
758 return Py_None;
759 }
760 #endif /* HAVE_LCHFLAGS */
761
762 #ifdef HAVE_CHROOT
763 PyDoc_STRVAR(edk2_chroot__doc__,
764 "chroot(path)\n\n\
765 Change root directory to path.");
766
767 static PyObject *
edk2_chroot(PyObject * self,PyObject * args)768 edk2_chroot(PyObject *self, PyObject *args)
769 {
770 return edk2_1str(args, "et:chroot", chroot);
771 }
772 #endif
773
774 #ifdef HAVE_FSYNC
775 PyDoc_STRVAR(edk2_fsync__doc__,
776 "fsync(fildes)\n\n\
777 force write of file with filedescriptor to disk.");
778
779 static PyObject *
edk2_fsync(PyObject * self,PyObject * fdobj)780 edk2_fsync(PyObject *self, PyObject *fdobj)
781 {
782 return edk2_fildes(fdobj, fsync);
783 }
784 #endif /* HAVE_FSYNC */
785
786 #ifdef HAVE_FDATASYNC
787
788 #ifdef __hpux
789 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
790 #endif
791
792 PyDoc_STRVAR(edk2_fdatasync__doc__,
793 "fdatasync(fildes)\n\n\
794 force write of file with filedescriptor to disk.\n\
795 does not force update of metadata.");
796
797 static PyObject *
edk2_fdatasync(PyObject * self,PyObject * fdobj)798 edk2_fdatasync(PyObject *self, PyObject *fdobj)
799 {
800 return edk2_fildes(fdobj, fdatasync);
801 }
802 #endif /* HAVE_FDATASYNC */
803
804
805 #ifdef HAVE_CHOWN
806 PyDoc_STRVAR(edk2_chown__doc__,
807 "chown(path, uid, gid)\n\n\
808 Change the owner and group id of path to the numeric uid and gid.");
809
810 static PyObject *
edk2_chown(PyObject * self,PyObject * args)811 edk2_chown(PyObject *self, PyObject *args)
812 {
813 char *path = NULL;
814 long uid, gid;
815 int res;
816 if (!PyArg_ParseTuple(args, "etll:chown",
817 Py_FileSystemDefaultEncoding, &path,
818 &uid, &gid))
819 return NULL;
820 Py_BEGIN_ALLOW_THREADS
821 res = chown(path, (uid_t) uid, (gid_t) gid);
822 Py_END_ALLOW_THREADS
823 if (res < 0)
824 return edk2_error_with_allocated_filename(path);
825 PyMem_Free(path);
826 Py_INCREF(Py_None);
827 return Py_None;
828 }
829 #endif /* HAVE_CHOWN */
830
831 #ifdef HAVE_FCHOWN
832 PyDoc_STRVAR(edk2_fchown__doc__,
833 "fchown(fd, uid, gid)\n\n\
834 Change the owner and group id of the file given by file descriptor\n\
835 fd to the numeric uid and gid.");
836
837 static PyObject *
edk2_fchown(PyObject * self,PyObject * args)838 edk2_fchown(PyObject *self, PyObject *args)
839 {
840 int fd;
841 long uid, gid;
842 int res;
843 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
844 return NULL;
845 Py_BEGIN_ALLOW_THREADS
846 res = fchown(fd, (uid_t) uid, (gid_t) gid);
847 Py_END_ALLOW_THREADS
848 if (res < 0)
849 return edk2_error();
850 Py_RETURN_NONE;
851 }
852 #endif /* HAVE_FCHOWN */
853
854 #ifdef HAVE_LCHOWN
855 PyDoc_STRVAR(edk2_lchown__doc__,
856 "lchown(path, uid, gid)\n\n\
857 Change the owner and group id of path to the numeric uid and gid.\n\
858 This function will not follow symbolic links.");
859
860 static PyObject *
edk2_lchown(PyObject * self,PyObject * args)861 edk2_lchown(PyObject *self, PyObject *args)
862 {
863 char *path = NULL;
864 long uid, gid;
865 int res;
866 if (!PyArg_ParseTuple(args, "etll:lchown",
867 Py_FileSystemDefaultEncoding, &path,
868 &uid, &gid))
869 return NULL;
870 Py_BEGIN_ALLOW_THREADS
871 res = lchown(path, (uid_t) uid, (gid_t) gid);
872 Py_END_ALLOW_THREADS
873 if (res < 0)
874 return edk2_error_with_allocated_filename(path);
875 PyMem_Free(path);
876 Py_INCREF(Py_None);
877 return Py_None;
878 }
879 #endif /* HAVE_LCHOWN */
880
881
882 #ifdef HAVE_GETCWD
883 PyDoc_STRVAR(edk2_getcwd__doc__,
884 "getcwd() -> path\n\n\
885 Return a string representing the current working directory.");
886
887 static PyObject *
edk2_getcwd(PyObject * self,PyObject * noargs)888 edk2_getcwd(PyObject *self, PyObject *noargs)
889 {
890 int bufsize_incr = 1024;
891 int bufsize = 0;
892 char *tmpbuf = NULL;
893 char *res = NULL;
894 PyObject *dynamic_return;
895
896 Py_BEGIN_ALLOW_THREADS
897 do {
898 bufsize = bufsize + bufsize_incr;
899 tmpbuf = malloc(bufsize);
900 if (tmpbuf == NULL) {
901 break;
902 }
903 res = getcwd(tmpbuf, bufsize);
904 if (res == NULL) {
905 free(tmpbuf);
906 }
907 } while ((res == NULL) && (errno == ERANGE));
908 Py_END_ALLOW_THREADS
909
910 if (res == NULL)
911 return edk2_error();
912
913 dynamic_return = PyString_FromString(tmpbuf);
914 free(tmpbuf);
915
916 return dynamic_return;
917 }
918
919 #ifdef Py_USING_UNICODE
920 PyDoc_STRVAR(edk2_getcwdu__doc__,
921 "getcwdu() -> path\n\n\
922 Return a unicode string representing the current working directory.");
923
924 static PyObject *
edk2_getcwdu(PyObject * self,PyObject * noargs)925 edk2_getcwdu(PyObject *self, PyObject *noargs)
926 {
927 char buf[1026];
928 char *res;
929
930 Py_BEGIN_ALLOW_THREADS
931 res = getcwd(buf, sizeof buf);
932 Py_END_ALLOW_THREADS
933 if (res == NULL)
934 return edk2_error();
935 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
936 }
937 #endif /* Py_USING_UNICODE */
938 #endif /* HAVE_GETCWD */
939
940
941 PyDoc_STRVAR(edk2_listdir__doc__,
942 "listdir(path) -> list_of_strings\n\n\
943 Return a list containing the names of the entries in the directory.\n\
944 \n\
945 path: path of directory to list\n\
946 \n\
947 The list is in arbitrary order. It does not include the special\n\
948 entries '.' and '..' even if they are present in the directory.");
949
950 static PyObject *
edk2_listdir(PyObject * self,PyObject * args)951 edk2_listdir(PyObject *self, PyObject *args)
952 {
953 /* XXX Should redo this putting the (now four) versions of opendir
954 in separate files instead of having them all here... */
955
956 char *name = NULL;
957 char *MBname;
958 PyObject *d, *v;
959 DIR *dirp;
960 struct dirent *ep;
961 int arg_is_unicode = 1;
962
963 errno = 0;
964 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
965 arg_is_unicode = 0;
966 PyErr_Clear();
967 }
968 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
969 return NULL;
970 Py_BEGIN_ALLOW_THREADS
971 dirp = opendir(name);
972 Py_END_ALLOW_THREADS
973 if (dirp == NULL) {
974 return edk2_error_with_allocated_filename(name);
975 }
976 if ((d = PyList_New(0)) == NULL) {
977 Py_BEGIN_ALLOW_THREADS
978 closedir(dirp);
979 Py_END_ALLOW_THREADS
980 PyMem_Free(name);
981 return NULL;
982 }
983 if((MBname = malloc(NAME_MAX)) == NULL) {
984 Py_BEGIN_ALLOW_THREADS
985 closedir(dirp);
986 Py_END_ALLOW_THREADS
987 Py_DECREF(d);
988 PyMem_Free(name);
989 return NULL;
990 }
991 for (;;) {
992 errno = 0;
993 Py_BEGIN_ALLOW_THREADS
994 ep = readdir(dirp);
995 Py_END_ALLOW_THREADS
996 if (ep == NULL) {
997 if ((errno == 0) || (errno == EISDIR)) {
998 break;
999 } else {
1000 Py_BEGIN_ALLOW_THREADS
1001 closedir(dirp);
1002 Py_END_ALLOW_THREADS
1003 Py_DECREF(d);
1004 return edk2_error_with_allocated_filename(name);
1005 }
1006 }
1007 if (ep->FileName[0] == L'.' &&
1008 (NAMLEN(ep) == 1 ||
1009 (ep->FileName[1] == L'.' && NAMLEN(ep) == 2)))
1010 continue;
1011 if(wcstombs(MBname, ep->FileName, NAME_MAX) == -1) {
1012 free(MBname);
1013 Py_BEGIN_ALLOW_THREADS
1014 closedir(dirp);
1015 Py_END_ALLOW_THREADS
1016 Py_DECREF(d);
1017 PyMem_Free(name);
1018 return NULL;
1019 }
1020 v = PyString_FromStringAndSize(MBname, strlen(MBname));
1021 if (v == NULL) {
1022 Py_DECREF(d);
1023 d = NULL;
1024 break;
1025 }
1026 #ifdef Py_USING_UNICODE
1027 if (arg_is_unicode) {
1028 PyObject *w;
1029
1030 w = PyUnicode_FromEncodedObject(v,
1031 Py_FileSystemDefaultEncoding,
1032 "strict");
1033 if (w != NULL) {
1034 Py_DECREF(v);
1035 v = w;
1036 }
1037 else {
1038 /* fall back to the original byte string, as
1039 discussed in patch #683592 */
1040 PyErr_Clear();
1041 }
1042 }
1043 #endif
1044 if (PyList_Append(d, v) != 0) {
1045 Py_DECREF(v);
1046 Py_DECREF(d);
1047 d = NULL;
1048 break;
1049 }
1050 Py_DECREF(v);
1051 }
1052 Py_BEGIN_ALLOW_THREADS
1053 closedir(dirp);
1054 Py_END_ALLOW_THREADS
1055 PyMem_Free(name);
1056 if(MBname != NULL) {
1057 free(MBname);
1058 }
1059
1060 return d;
1061
1062 } /* end of edk2_listdir */
1063
1064 PyDoc_STRVAR(edk2_mkdir__doc__,
1065 "mkdir(path [, mode=0777])\n\n\
1066 Create a directory.");
1067
1068 static PyObject *
edk2_mkdir(PyObject * self,PyObject * args)1069 edk2_mkdir(PyObject *self, PyObject *args)
1070 {
1071 int res;
1072 char *path = NULL;
1073 int mode = 0777;
1074
1075 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1076 Py_FileSystemDefaultEncoding, &path, &mode))
1077 return NULL;
1078 Py_BEGIN_ALLOW_THREADS
1079 res = mkdir(path, mode);
1080 Py_END_ALLOW_THREADS
1081 if (res < 0)
1082 return edk2_error_with_allocated_filename(path);
1083 PyMem_Free(path);
1084 Py_INCREF(Py_None);
1085 return Py_None;
1086 }
1087
1088
1089 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
1090 #if defined(HAVE_SYS_RESOURCE_H)
1091 #include <sys/resource.h>
1092 #endif
1093
1094
1095 #ifdef HAVE_NICE
1096 PyDoc_STRVAR(edk2_nice__doc__,
1097 "nice(inc) -> new_priority\n\n\
1098 Decrease the priority of process by inc and return the new priority.");
1099
1100 static PyObject *
edk2_nice(PyObject * self,PyObject * args)1101 edk2_nice(PyObject *self, PyObject *args)
1102 {
1103 int increment, value;
1104
1105 if (!PyArg_ParseTuple(args, "i:nice", &increment))
1106 return NULL;
1107
1108 /* There are two flavours of 'nice': one that returns the new
1109 priority (as required by almost all standards out there) and the
1110 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1111 the use of getpriority() to get the new priority.
1112
1113 If we are of the nice family that returns the new priority, we
1114 need to clear errno before the call, and check if errno is filled
1115 before calling edk2_error() on a returnvalue of -1, because the
1116 -1 may be the actual new priority! */
1117
1118 errno = 0;
1119 value = nice(increment);
1120 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
1121 if (value == 0)
1122 value = getpriority(PRIO_PROCESS, 0);
1123 #endif
1124 if (value == -1 && errno != 0)
1125 /* either nice() or getpriority() returned an error */
1126 return edk2_error();
1127 return PyInt_FromLong((long) value);
1128 }
1129 #endif /* HAVE_NICE */
1130
1131 PyDoc_STRVAR(edk2_rename__doc__,
1132 "rename(old, new)\n\n\
1133 Rename a file or directory.");
1134
1135 static PyObject *
edk2_rename(PyObject * self,PyObject * args)1136 edk2_rename(PyObject *self, PyObject *args)
1137 {
1138 return edk2_2str(args, "etet:rename", rename);
1139 }
1140
1141
1142 PyDoc_STRVAR(edk2_rmdir__doc__,
1143 "rmdir(path)\n\n\
1144 Remove a directory.");
1145
1146 static PyObject *
edk2_rmdir(PyObject * self,PyObject * args)1147 edk2_rmdir(PyObject *self, PyObject *args)
1148 {
1149 return edk2_1str(args, "et:rmdir", rmdir);
1150 }
1151
1152
1153 PyDoc_STRVAR(edk2_stat__doc__,
1154 "stat(path) -> stat result\n\n\
1155 Perform a stat system call on the given path.");
1156
1157 static PyObject *
edk2_stat(PyObject * self,PyObject * args)1158 edk2_stat(PyObject *self, PyObject *args)
1159 {
1160 return edk2_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1161 }
1162
1163
1164 #ifdef HAVE_SYSTEM
1165 PyDoc_STRVAR(edk2_system__doc__,
1166 "system(command) -> exit_status\n\n\
1167 Execute the command (a string) in a subshell.");
1168
1169 static PyObject *
edk2_system(PyObject * self,PyObject * args)1170 edk2_system(PyObject *self, PyObject *args)
1171 {
1172 char *command;
1173 long sts;
1174 if (!PyArg_ParseTuple(args, "s:system", &command))
1175 return NULL;
1176 Py_BEGIN_ALLOW_THREADS
1177 sts = system(command);
1178 Py_END_ALLOW_THREADS
1179 return PyInt_FromLong(sts);
1180 }
1181 #endif
1182
1183
1184 PyDoc_STRVAR(edk2_umask__doc__,
1185 "umask(new_mask) -> old_mask\n\n\
1186 Set the current numeric umask and return the previous umask.");
1187
1188 static PyObject *
edk2_umask(PyObject * self,PyObject * args)1189 edk2_umask(PyObject *self, PyObject *args)
1190 {
1191 int i;
1192 if (!PyArg_ParseTuple(args, "i:umask", &i))
1193 return NULL;
1194 i = (int)umask(i);
1195 if (i < 0)
1196 return edk2_error();
1197 return PyInt_FromLong((long)i);
1198 }
1199
1200
1201 PyDoc_STRVAR(edk2_unlink__doc__,
1202 "unlink(path)\n\n\
1203 Remove a file (same as remove(path)).");
1204
1205 PyDoc_STRVAR(edk2_remove__doc__,
1206 "remove(path)\n\n\
1207 Remove a file (same as unlink(path)).");
1208
1209 static PyObject *
edk2_unlink(PyObject * self,PyObject * args)1210 edk2_unlink(PyObject *self, PyObject *args)
1211 {
1212 return edk2_1str(args, "et:remove", unlink);
1213 }
1214
1215
1216 static int
extract_time(PyObject * t,time_t * sec,long * usec)1217 extract_time(PyObject *t, time_t* sec, long* usec)
1218 {
1219 time_t intval;
1220 if (PyFloat_Check(t)) {
1221 double tval = PyFloat_AsDouble(t);
1222 PyObject *intobj = PyNumber_Long(t);
1223 if (!intobj)
1224 return -1;
1225 #if SIZEOF_TIME_T > SIZEOF_LONG
1226 intval = PyInt_AsUnsignedLongLongMask(intobj);
1227 #else
1228 intval = PyInt_AsLong(intobj);
1229 #endif
1230 Py_DECREF(intobj);
1231 if (intval == -1 && PyErr_Occurred())
1232 return -1;
1233 *sec = intval;
1234 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
1235 if (*usec < 0)
1236 /* If rounding gave us a negative number,
1237 truncate. */
1238 *usec = 0;
1239 return 0;
1240 }
1241 #if SIZEOF_TIME_T > SIZEOF_LONG
1242 intval = PyInt_AsUnsignedLongLongMask(t);
1243 #else
1244 intval = PyInt_AsLong(t);
1245 #endif
1246 if (intval == -1 && PyErr_Occurred())
1247 return -1;
1248 *sec = intval;
1249 *usec = 0;
1250 return 0;
1251 }
1252
1253 PyDoc_STRVAR(edk2_utime__doc__,
1254 "utime(path, (atime, mtime))\n\
1255 utime(path, None)\n\n\
1256 Set the access and modified time of the file to the given values. If the\n\
1257 second form is used, set the access and modified times to the current time.");
1258
1259 static PyObject *
edk2_utime(PyObject * self,PyObject * args)1260 edk2_utime(PyObject *self, PyObject *args)
1261 {
1262 char *path = NULL;
1263 time_t atime, mtime;
1264 long ausec, musec;
1265 int res;
1266 PyObject* arg;
1267
1268 #if defined(HAVE_UTIMES)
1269 struct timeval buf[2];
1270 #define ATIME buf[0].tv_sec
1271 #define MTIME buf[1].tv_sec
1272 #elif defined(HAVE_UTIME_H)
1273 /* XXX should define struct utimbuf instead, above */
1274 struct utimbuf buf;
1275 #define ATIME buf.actime
1276 #define MTIME buf.modtime
1277 #define UTIME_ARG &buf
1278 #else /* HAVE_UTIMES */
1279 time_t buf[2];
1280 #define ATIME buf[0]
1281 #define MTIME buf[1]
1282 #define UTIME_ARG buf
1283 #endif /* HAVE_UTIMES */
1284
1285
1286 if (!PyArg_ParseTuple(args, "etO:utime",
1287 Py_FileSystemDefaultEncoding, &path, &arg))
1288 return NULL;
1289 if (arg == Py_None) {
1290 /* optional time values not given */
1291 Py_BEGIN_ALLOW_THREADS
1292 res = utime(path, NULL);
1293 Py_END_ALLOW_THREADS
1294 }
1295 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
1296 PyErr_SetString(PyExc_TypeError,
1297 "utime() arg 2 must be a tuple (atime, mtime)");
1298 PyMem_Free(path);
1299 return NULL;
1300 }
1301 else {
1302 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1303 &atime, &ausec) == -1) {
1304 PyMem_Free(path);
1305 return NULL;
1306 }
1307 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1308 &mtime, &musec) == -1) {
1309 PyMem_Free(path);
1310 return NULL;
1311 }
1312 ATIME = atime;
1313 MTIME = mtime;
1314 #ifdef HAVE_UTIMES
1315 buf[0].tv_usec = ausec;
1316 buf[1].tv_usec = musec;
1317 Py_BEGIN_ALLOW_THREADS
1318 res = utimes(path, buf);
1319 Py_END_ALLOW_THREADS
1320 #else
1321 Py_BEGIN_ALLOW_THREADS
1322 res = utime(path, UTIME_ARG);
1323 Py_END_ALLOW_THREADS
1324 #endif /* HAVE_UTIMES */
1325 }
1326 if (res < 0) {
1327 return edk2_error_with_allocated_filename(path);
1328 }
1329 PyMem_Free(path);
1330 Py_INCREF(Py_None);
1331 return Py_None;
1332 #undef UTIME_ARG
1333 #undef ATIME
1334 #undef MTIME
1335 }
1336
1337
1338 /* Process operations */
1339
1340 PyDoc_STRVAR(edk2__exit__doc__,
1341 "_exit(status)\n\n\
1342 Exit to the system with specified status, without normal exit processing.");
1343
1344 static PyObject *
edk2__exit(PyObject * self,PyObject * args)1345 edk2__exit(PyObject *self, PyObject *args)
1346 {
1347 int sts;
1348 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
1349 return NULL;
1350 _Exit(sts);
1351 return NULL; /* Make gcc -Wall happy */
1352 }
1353
1354 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
1355 static void
free_string_array(char ** array,Py_ssize_t count)1356 free_string_array(char **array, Py_ssize_t count)
1357 {
1358 Py_ssize_t i;
1359 for (i = 0; i < count; i++)
1360 PyMem_Free(array[i]);
1361 PyMem_DEL(array);
1362 }
1363 #endif
1364
1365
1366 #ifdef HAVE_EXECV
1367 PyDoc_STRVAR(edk2_execv__doc__,
1368 "execv(path, args)\n\n\
1369 Execute an executable path with arguments, replacing current process.\n\
1370 \n\
1371 path: path of executable file\n\
1372 args: tuple or list of strings");
1373
1374 static PyObject *
edk2_execv(PyObject * self,PyObject * args)1375 edk2_execv(PyObject *self, PyObject *args)
1376 {
1377 char *path;
1378 PyObject *argv;
1379 char **argvlist;
1380 Py_ssize_t i, argc;
1381 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1382
1383 /* execv has two arguments: (path, argv), where
1384 argv is a list or tuple of strings. */
1385
1386 if (!PyArg_ParseTuple(args, "etO:execv",
1387 Py_FileSystemDefaultEncoding,
1388 &path, &argv))
1389 return NULL;
1390 if (PyList_Check(argv)) {
1391 argc = PyList_Size(argv);
1392 getitem = PyList_GetItem;
1393 }
1394 else if (PyTuple_Check(argv)) {
1395 argc = PyTuple_Size(argv);
1396 getitem = PyTuple_GetItem;
1397 }
1398 else {
1399 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
1400 PyMem_Free(path);
1401 return NULL;
1402 }
1403 if (argc < 1) {
1404 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
1405 PyMem_Free(path);
1406 return NULL;
1407 }
1408
1409 argvlist = PyMem_NEW(char *, argc+1);
1410 if (argvlist == NULL) {
1411 PyMem_Free(path);
1412 return PyErr_NoMemory();
1413 }
1414 for (i = 0; i < argc; i++) {
1415 if (!PyArg_Parse((*getitem)(argv, i), "et",
1416 Py_FileSystemDefaultEncoding,
1417 &argvlist[i])) {
1418 free_string_array(argvlist, i);
1419 PyErr_SetString(PyExc_TypeError,
1420 "execv() arg 2 must contain only strings");
1421 PyMem_Free(path);
1422 return NULL;
1423
1424 }
1425 }
1426 argvlist[argc] = NULL;
1427
1428 execv(path, argvlist);
1429
1430 /* If we get here it's definitely an error */
1431
1432 free_string_array(argvlist, argc);
1433 PyMem_Free(path);
1434 return edk2_error();
1435 }
1436
1437
1438 PyDoc_STRVAR(edk2_execve__doc__,
1439 "execve(path, args, env)\n\n\
1440 Execute a path with arguments and environment, replacing current process.\n\
1441 \n\
1442 path: path of executable file\n\
1443 args: tuple or list of arguments\n\
1444 env: dictionary of strings mapping to strings");
1445
1446 static PyObject *
edk2_execve(PyObject * self,PyObject * args)1447 edk2_execve(PyObject *self, PyObject *args)
1448 {
1449 char *path;
1450 PyObject *argv, *env;
1451 char **argvlist;
1452 char **envlist;
1453 PyObject *key, *val, *keys=NULL, *vals=NULL;
1454 Py_ssize_t i, pos, argc, envc;
1455 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1456 Py_ssize_t lastarg = 0;
1457
1458 /* execve has three arguments: (path, argv, env), where
1459 argv is a list or tuple of strings and env is a dictionary
1460 like posix.environ. */
1461
1462 if (!PyArg_ParseTuple(args, "etOO:execve",
1463 Py_FileSystemDefaultEncoding,
1464 &path, &argv, &env))
1465 return NULL;
1466 if (PyList_Check(argv)) {
1467 argc = PyList_Size(argv);
1468 getitem = PyList_GetItem;
1469 }
1470 else if (PyTuple_Check(argv)) {
1471 argc = PyTuple_Size(argv);
1472 getitem = PyTuple_GetItem;
1473 }
1474 else {
1475 PyErr_SetString(PyExc_TypeError,
1476 "execve() arg 2 must be a tuple or list");
1477 goto fail_0;
1478 }
1479 if (!PyMapping_Check(env)) {
1480 PyErr_SetString(PyExc_TypeError,
1481 "execve() arg 3 must be a mapping object");
1482 goto fail_0;
1483 }
1484
1485 argvlist = PyMem_NEW(char *, argc+1);
1486 if (argvlist == NULL) {
1487 PyErr_NoMemory();
1488 goto fail_0;
1489 }
1490 for (i = 0; i < argc; i++) {
1491 if (!PyArg_Parse((*getitem)(argv, i),
1492 "et;execve() arg 2 must contain only strings",
1493 Py_FileSystemDefaultEncoding,
1494 &argvlist[i]))
1495 {
1496 lastarg = i;
1497 goto fail_1;
1498 }
1499 }
1500 lastarg = argc;
1501 argvlist[argc] = NULL;
1502
1503 i = PyMapping_Size(env);
1504 if (i < 0)
1505 goto fail_1;
1506 envlist = PyMem_NEW(char *, i + 1);
1507 if (envlist == NULL) {
1508 PyErr_NoMemory();
1509 goto fail_1;
1510 }
1511 envc = 0;
1512 keys = PyMapping_Keys(env);
1513 vals = PyMapping_Values(env);
1514 if (!keys || !vals)
1515 goto fail_2;
1516 if (!PyList_Check(keys) || !PyList_Check(vals)) {
1517 PyErr_SetString(PyExc_TypeError,
1518 "execve(): env.keys() or env.values() is not a list");
1519 goto fail_2;
1520 }
1521
1522 for (pos = 0; pos < i; pos++) {
1523 char *p, *k, *v;
1524 size_t len;
1525
1526 key = PyList_GetItem(keys, pos);
1527 val = PyList_GetItem(vals, pos);
1528 if (!key || !val)
1529 goto fail_2;
1530
1531 if (!PyArg_Parse(
1532 key,
1533 "s;execve() arg 3 contains a non-string key",
1534 &k) ||
1535 !PyArg_Parse(
1536 val,
1537 "s;execve() arg 3 contains a non-string value",
1538 &v))
1539 {
1540 goto fail_2;
1541 }
1542
1543 #if defined(PYOS_OS2)
1544 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1545 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1546 #endif
1547 len = PyString_Size(key) + PyString_Size(val) + 2;
1548 p = PyMem_NEW(char, len);
1549 if (p == NULL) {
1550 PyErr_NoMemory();
1551 goto fail_2;
1552 }
1553 PyOS_snprintf(p, len, "%s=%s", k, v);
1554 envlist[envc++] = p;
1555 #if defined(PYOS_OS2)
1556 }
1557 #endif
1558 }
1559 envlist[envc] = 0;
1560
1561 execve(path, argvlist, envlist);
1562
1563 /* If we get here it's definitely an error */
1564
1565 (void) edk2_error();
1566
1567 fail_2:
1568 while (--envc >= 0)
1569 PyMem_DEL(envlist[envc]);
1570 PyMem_DEL(envlist);
1571 fail_1:
1572 free_string_array(argvlist, lastarg);
1573 Py_XDECREF(vals);
1574 Py_XDECREF(keys);
1575 fail_0:
1576 PyMem_Free(path);
1577 return NULL;
1578 }
1579 #endif /* HAVE_EXECV */
1580
1581
1582 #ifdef HAVE_SPAWNV
1583 PyDoc_STRVAR(edk2_spawnv__doc__,
1584 "spawnv(mode, path, args)\n\n\
1585 Execute the program 'path' in a new process.\n\
1586 \n\
1587 mode: mode of process creation\n\
1588 path: path of executable file\n\
1589 args: tuple or list of strings");
1590
1591 static PyObject *
edk2_spawnv(PyObject * self,PyObject * args)1592 edk2_spawnv(PyObject *self, PyObject *args)
1593 {
1594 char *path;
1595 PyObject *argv;
1596 char **argvlist;
1597 int mode, i;
1598 Py_ssize_t argc;
1599 Py_intptr_t spawnval;
1600 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1601
1602 /* spawnv has three arguments: (mode, path, argv), where
1603 argv is a list or tuple of strings. */
1604
1605 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
1606 Py_FileSystemDefaultEncoding,
1607 &path, &argv))
1608 return NULL;
1609 if (PyList_Check(argv)) {
1610 argc = PyList_Size(argv);
1611 getitem = PyList_GetItem;
1612 }
1613 else if (PyTuple_Check(argv)) {
1614 argc = PyTuple_Size(argv);
1615 getitem = PyTuple_GetItem;
1616 }
1617 else {
1618 PyErr_SetString(PyExc_TypeError,
1619 "spawnv() arg 2 must be a tuple or list");
1620 PyMem_Free(path);
1621 return NULL;
1622 }
1623
1624 argvlist = PyMem_NEW(char *, argc+1);
1625 if (argvlist == NULL) {
1626 PyMem_Free(path);
1627 return PyErr_NoMemory();
1628 }
1629 for (i = 0; i < argc; i++) {
1630 if (!PyArg_Parse((*getitem)(argv, i), "et",
1631 Py_FileSystemDefaultEncoding,
1632 &argvlist[i])) {
1633 free_string_array(argvlist, i);
1634 PyErr_SetString(
1635 PyExc_TypeError,
1636 "spawnv() arg 2 must contain only strings");
1637 PyMem_Free(path);
1638 return NULL;
1639 }
1640 }
1641 argvlist[argc] = NULL;
1642
1643 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1644 Py_BEGIN_ALLOW_THREADS
1645 spawnval = spawnv(mode, path, argvlist);
1646 Py_END_ALLOW_THREADS
1647 #else
1648 if (mode == _OLD_P_OVERLAY)
1649 mode = _P_OVERLAY;
1650
1651 Py_BEGIN_ALLOW_THREADS
1652 spawnval = _spawnv(mode, path, argvlist);
1653 Py_END_ALLOW_THREADS
1654 #endif
1655
1656 free_string_array(argvlist, argc);
1657 PyMem_Free(path);
1658
1659 if (spawnval == -1)
1660 return edk2_error();
1661 else
1662 #if SIZEOF_LONG == SIZEOF_VOID_P
1663 return Py_BuildValue("l", (long) spawnval);
1664 #else
1665 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
1666 #endif
1667 }
1668
1669
1670 PyDoc_STRVAR(edk2_spawnve__doc__,
1671 "spawnve(mode, path, args, env)\n\n\
1672 Execute the program 'path' in a new process.\n\
1673 \n\
1674 mode: mode of process creation\n\
1675 path: path of executable file\n\
1676 args: tuple or list of arguments\n\
1677 env: dictionary of strings mapping to strings");
1678
1679 static PyObject *
edk2_spawnve(PyObject * self,PyObject * args)1680 edk2_spawnve(PyObject *self, PyObject *args)
1681 {
1682 char *path;
1683 PyObject *argv, *env;
1684 char **argvlist;
1685 char **envlist;
1686 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1687 int mode, pos, envc;
1688 Py_ssize_t argc, i;
1689 Py_intptr_t spawnval;
1690 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1691 Py_ssize_t lastarg = 0;
1692
1693 /* spawnve has four arguments: (mode, path, argv, env), where
1694 argv is a list or tuple of strings and env is a dictionary
1695 like posix.environ. */
1696
1697 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
1698 Py_FileSystemDefaultEncoding,
1699 &path, &argv, &env))
1700 return NULL;
1701 if (PyList_Check(argv)) {
1702 argc = PyList_Size(argv);
1703 getitem = PyList_GetItem;
1704 }
1705 else if (PyTuple_Check(argv)) {
1706 argc = PyTuple_Size(argv);
1707 getitem = PyTuple_GetItem;
1708 }
1709 else {
1710 PyErr_SetString(PyExc_TypeError,
1711 "spawnve() arg 2 must be a tuple or list");
1712 goto fail_0;
1713 }
1714 if (!PyMapping_Check(env)) {
1715 PyErr_SetString(PyExc_TypeError,
1716 "spawnve() arg 3 must be a mapping object");
1717 goto fail_0;
1718 }
1719
1720 argvlist = PyMem_NEW(char *, argc+1);
1721 if (argvlist == NULL) {
1722 PyErr_NoMemory();
1723 goto fail_0;
1724 }
1725 for (i = 0; i < argc; i++) {
1726 if (!PyArg_Parse((*getitem)(argv, i),
1727 "et;spawnve() arg 2 must contain only strings",
1728 Py_FileSystemDefaultEncoding,
1729 &argvlist[i]))
1730 {
1731 lastarg = i;
1732 goto fail_1;
1733 }
1734 }
1735 lastarg = argc;
1736 argvlist[argc] = NULL;
1737
1738 i = PyMapping_Size(env);
1739 if (i < 0)
1740 goto fail_1;
1741 envlist = PyMem_NEW(char *, i + 1);
1742 if (envlist == NULL) {
1743 PyErr_NoMemory();
1744 goto fail_1;
1745 }
1746 envc = 0;
1747 keys = PyMapping_Keys(env);
1748 vals = PyMapping_Values(env);
1749 if (!keys || !vals)
1750 goto fail_2;
1751 if (!PyList_Check(keys) || !PyList_Check(vals)) {
1752 PyErr_SetString(PyExc_TypeError,
1753 "spawnve(): env.keys() or env.values() is not a list");
1754 goto fail_2;
1755 }
1756
1757 for (pos = 0; pos < i; pos++) {
1758 char *p, *k, *v;
1759 size_t len;
1760
1761 key = PyList_GetItem(keys, pos);
1762 val = PyList_GetItem(vals, pos);
1763 if (!key || !val)
1764 goto fail_2;
1765
1766 if (!PyArg_Parse(
1767 key,
1768 "s;spawnve() arg 3 contains a non-string key",
1769 &k) ||
1770 !PyArg_Parse(
1771 val,
1772 "s;spawnve() arg 3 contains a non-string value",
1773 &v))
1774 {
1775 goto fail_2;
1776 }
1777 len = PyString_Size(key) + PyString_Size(val) + 2;
1778 p = PyMem_NEW(char, len);
1779 if (p == NULL) {
1780 PyErr_NoMemory();
1781 goto fail_2;
1782 }
1783 PyOS_snprintf(p, len, "%s=%s", k, v);
1784 envlist[envc++] = p;
1785 }
1786 envlist[envc] = 0;
1787
1788 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1789 Py_BEGIN_ALLOW_THREADS
1790 spawnval = spawnve(mode, path, argvlist, envlist);
1791 Py_END_ALLOW_THREADS
1792 #else
1793 if (mode == _OLD_P_OVERLAY)
1794 mode = _P_OVERLAY;
1795
1796 Py_BEGIN_ALLOW_THREADS
1797 spawnval = _spawnve(mode, path, argvlist, envlist);
1798 Py_END_ALLOW_THREADS
1799 #endif
1800
1801 if (spawnval == -1)
1802 (void) edk2_error();
1803 else
1804 #if SIZEOF_LONG == SIZEOF_VOID_P
1805 res = Py_BuildValue("l", (long) spawnval);
1806 #else
1807 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
1808 #endif
1809
1810 fail_2:
1811 while (--envc >= 0)
1812 PyMem_DEL(envlist[envc]);
1813 PyMem_DEL(envlist);
1814 fail_1:
1815 free_string_array(argvlist, lastarg);
1816 Py_XDECREF(vals);
1817 Py_XDECREF(keys);
1818 fail_0:
1819 PyMem_Free(path);
1820 return res;
1821 }
1822
1823 /* OS/2 supports spawnvp & spawnvpe natively */
1824 #if defined(PYOS_OS2)
1825 PyDoc_STRVAR(edk2_spawnvp__doc__,
1826 "spawnvp(mode, file, args)\n\n\
1827 Execute the program 'file' in a new process, using the environment\n\
1828 search path to find the file.\n\
1829 \n\
1830 mode: mode of process creation\n\
1831 file: executable file name\n\
1832 args: tuple or list of strings");
1833
1834 static PyObject *
edk2_spawnvp(PyObject * self,PyObject * args)1835 edk2_spawnvp(PyObject *self, PyObject *args)
1836 {
1837 char *path;
1838 PyObject *argv;
1839 char **argvlist;
1840 int mode, i, argc;
1841 Py_intptr_t spawnval;
1842 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1843
1844 /* spawnvp has three arguments: (mode, path, argv), where
1845 argv is a list or tuple of strings. */
1846
1847 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
1848 Py_FileSystemDefaultEncoding,
1849 &path, &argv))
1850 return NULL;
1851 if (PyList_Check(argv)) {
1852 argc = PyList_Size(argv);
1853 getitem = PyList_GetItem;
1854 }
1855 else if (PyTuple_Check(argv)) {
1856 argc = PyTuple_Size(argv);
1857 getitem = PyTuple_GetItem;
1858 }
1859 else {
1860 PyErr_SetString(PyExc_TypeError,
1861 "spawnvp() arg 2 must be a tuple or list");
1862 PyMem_Free(path);
1863 return NULL;
1864 }
1865
1866 argvlist = PyMem_NEW(char *, argc+1);
1867 if (argvlist == NULL) {
1868 PyMem_Free(path);
1869 return PyErr_NoMemory();
1870 }
1871 for (i = 0; i < argc; i++) {
1872 if (!PyArg_Parse((*getitem)(argv, i), "et",
1873 Py_FileSystemDefaultEncoding,
1874 &argvlist[i])) {
1875 free_string_array(argvlist, i);
1876 PyErr_SetString(
1877 PyExc_TypeError,
1878 "spawnvp() arg 2 must contain only strings");
1879 PyMem_Free(path);
1880 return NULL;
1881 }
1882 }
1883 argvlist[argc] = NULL;
1884
1885 Py_BEGIN_ALLOW_THREADS
1886 #if defined(PYCC_GCC)
1887 spawnval = spawnvp(mode, path, argvlist);
1888 #else
1889 spawnval = _spawnvp(mode, path, argvlist);
1890 #endif
1891 Py_END_ALLOW_THREADS
1892
1893 free_string_array(argvlist, argc);
1894 PyMem_Free(path);
1895
1896 if (spawnval == -1)
1897 return edk2_error();
1898 else
1899 return Py_BuildValue("l", (long) spawnval);
1900 }
1901
1902
1903 PyDoc_STRVAR(edk2_spawnvpe__doc__,
1904 "spawnvpe(mode, file, args, env)\n\n\
1905 Execute the program 'file' in a new process, using the environment\n\
1906 search path to find the file.\n\
1907 \n\
1908 mode: mode of process creation\n\
1909 file: executable file name\n\
1910 args: tuple or list of arguments\n\
1911 env: dictionary of strings mapping to strings");
1912
1913 static PyObject *
edk2_spawnvpe(PyObject * self,PyObject * args)1914 edk2_spawnvpe(PyObject *self, PyObject *args)
1915 {
1916 char *path;
1917 PyObject *argv, *env;
1918 char **argvlist;
1919 char **envlist;
1920 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1921 int mode, i, pos, argc, envc;
1922 Py_intptr_t spawnval;
1923 PyObject *(*getitem)(PyObject *, Py_ssize_t);
1924 int lastarg = 0;
1925
1926 /* spawnvpe has four arguments: (mode, path, argv, env), where
1927 argv is a list or tuple of strings and env is a dictionary
1928 like posix.environ. */
1929
1930 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
1931 Py_FileSystemDefaultEncoding,
1932 &path, &argv, &env))
1933 return NULL;
1934 if (PyList_Check(argv)) {
1935 argc = PyList_Size(argv);
1936 getitem = PyList_GetItem;
1937 }
1938 else if (PyTuple_Check(argv)) {
1939 argc = PyTuple_Size(argv);
1940 getitem = PyTuple_GetItem;
1941 }
1942 else {
1943 PyErr_SetString(PyExc_TypeError,
1944 "spawnvpe() arg 2 must be a tuple or list");
1945 goto fail_0;
1946 }
1947 if (!PyMapping_Check(env)) {
1948 PyErr_SetString(PyExc_TypeError,
1949 "spawnvpe() arg 3 must be a mapping object");
1950 goto fail_0;
1951 }
1952
1953 argvlist = PyMem_NEW(char *, argc+1);
1954 if (argvlist == NULL) {
1955 PyErr_NoMemory();
1956 goto fail_0;
1957 }
1958 for (i = 0; i < argc; i++) {
1959 if (!PyArg_Parse((*getitem)(argv, i),
1960 "et;spawnvpe() arg 2 must contain only strings",
1961 Py_FileSystemDefaultEncoding,
1962 &argvlist[i]))
1963 {
1964 lastarg = i;
1965 goto fail_1;
1966 }
1967 }
1968 lastarg = argc;
1969 argvlist[argc] = NULL;
1970
1971 i = PyMapping_Size(env);
1972 if (i < 0)
1973 goto fail_1;
1974 envlist = PyMem_NEW(char *, i + 1);
1975 if (envlist == NULL) {
1976 PyErr_NoMemory();
1977 goto fail_1;
1978 }
1979 envc = 0;
1980 keys = PyMapping_Keys(env);
1981 vals = PyMapping_Values(env);
1982 if (!keys || !vals)
1983 goto fail_2;
1984 if (!PyList_Check(keys) || !PyList_Check(vals)) {
1985 PyErr_SetString(PyExc_TypeError,
1986 "spawnvpe(): env.keys() or env.values() is not a list");
1987 goto fail_2;
1988 }
1989
1990 for (pos = 0; pos < i; pos++) {
1991 char *p, *k, *v;
1992 size_t len;
1993
1994 key = PyList_GetItem(keys, pos);
1995 val = PyList_GetItem(vals, pos);
1996 if (!key || !val)
1997 goto fail_2;
1998
1999 if (!PyArg_Parse(
2000 key,
2001 "s;spawnvpe() arg 3 contains a non-string key",
2002 &k) ||
2003 !PyArg_Parse(
2004 val,
2005 "s;spawnvpe() arg 3 contains a non-string value",
2006 &v))
2007 {
2008 goto fail_2;
2009 }
2010 len = PyString_Size(key) + PyString_Size(val) + 2;
2011 p = PyMem_NEW(char, len);
2012 if (p == NULL) {
2013 PyErr_NoMemory();
2014 goto fail_2;
2015 }
2016 PyOS_snprintf(p, len, "%s=%s", k, v);
2017 envlist[envc++] = p;
2018 }
2019 envlist[envc] = 0;
2020
2021 Py_BEGIN_ALLOW_THREADS
2022 #if defined(PYCC_GCC)
2023 spawnval = spawnvpe(mode, path, argvlist, envlist);
2024 #else
2025 spawnval = _spawnvpe(mode, path, argvlist, envlist);
2026 #endif
2027 Py_END_ALLOW_THREADS
2028
2029 if (spawnval == -1)
2030 (void) edk2_error();
2031 else
2032 res = Py_BuildValue("l", (long) spawnval);
2033
2034 fail_2:
2035 while (--envc >= 0)
2036 PyMem_DEL(envlist[envc]);
2037 PyMem_DEL(envlist);
2038 fail_1:
2039 free_string_array(argvlist, lastarg);
2040 Py_XDECREF(vals);
2041 Py_XDECREF(keys);
2042 fail_0:
2043 PyMem_Free(path);
2044 return res;
2045 }
2046 #endif /* PYOS_OS2 */
2047 #endif /* HAVE_SPAWNV */
2048
2049
2050 #ifdef HAVE_FORK1
2051 PyDoc_STRVAR(edk2_fork1__doc__,
2052 "fork1() -> pid\n\n\
2053 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2054 \n\
2055 Return 0 to child process and PID of child to parent process.");
2056
2057 static PyObject *
edk2_fork1(PyObject * self,PyObject * noargs)2058 edk2_fork1(PyObject *self, PyObject *noargs)
2059 {
2060 pid_t pid;
2061 int result = 0;
2062 _PyImport_AcquireLock();
2063 pid = fork1();
2064 if (pid == 0) {
2065 /* child: this clobbers and resets the import lock. */
2066 PyOS_AfterFork();
2067 } else {
2068 /* parent: release the import lock. */
2069 result = _PyImport_ReleaseLock();
2070 }
2071 if (pid == -1)
2072 return edk2_error();
2073 if (result < 0) {
2074 /* Don't clobber the OSError if the fork failed. */
2075 PyErr_SetString(PyExc_RuntimeError,
2076 "not holding the import lock");
2077 return NULL;
2078 }
2079 return PyLong_FromPid(pid);
2080 }
2081 #endif
2082
2083
2084 #ifdef HAVE_FORK
2085 PyDoc_STRVAR(edk2_fork__doc__,
2086 "fork() -> pid\n\n\
2087 Fork a child process.\n\
2088 Return 0 to child process and PID of child to parent process.");
2089
2090 static PyObject *
edk2_fork(PyObject * self,PyObject * noargs)2091 edk2_fork(PyObject *self, PyObject *noargs)
2092 {
2093 pid_t pid;
2094 int result = 0;
2095 _PyImport_AcquireLock();
2096 pid = fork();
2097 if (pid == 0) {
2098 /* child: this clobbers and resets the import lock. */
2099 PyOS_AfterFork();
2100 } else {
2101 /* parent: release the import lock. */
2102 result = _PyImport_ReleaseLock();
2103 }
2104 if (pid == -1)
2105 return edk2_error();
2106 if (result < 0) {
2107 /* Don't clobber the OSError if the fork failed. */
2108 PyErr_SetString(PyExc_RuntimeError,
2109 "not holding the import lock");
2110 return NULL;
2111 }
2112 return PyLong_FromPid(pid);
2113 }
2114 #endif
2115
2116 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
2117 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2118 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
2119 #define DEV_PTY_FILE "/dev/ptc"
2120 #define HAVE_DEV_PTMX
2121 #else
2122 #define DEV_PTY_FILE "/dev/ptmx"
2123 #endif
2124
2125 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
2126 #ifdef HAVE_PTY_H
2127 #include <pty.h>
2128 #else
2129 #ifdef HAVE_LIBUTIL_H
2130 #include <libutil.h>
2131 #else
2132 #ifdef HAVE_UTIL_H
2133 #include <util.h>
2134 #endif /* HAVE_UTIL_H */
2135 #endif /* HAVE_LIBUTIL_H */
2136 #endif /* HAVE_PTY_H */
2137 #ifdef HAVE_STROPTS_H
2138 #include <stropts.h>
2139 #endif
2140 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
2141
2142 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
2143 PyDoc_STRVAR(edk2_openpty__doc__,
2144 "openpty() -> (master_fd, slave_fd)\n\n\
2145 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
2146
2147 static PyObject *
edk2_openpty(PyObject * self,PyObject * noargs)2148 edk2_openpty(PyObject *self, PyObject *noargs)
2149 {
2150 int master_fd, slave_fd;
2151 #ifndef HAVE_OPENPTY
2152 char * slave_name;
2153 #endif
2154 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
2155 PyOS_sighandler_t sig_saved;
2156 #ifdef sun
2157 extern char *ptsname(int fildes);
2158 #endif
2159 #endif
2160
2161 #ifdef HAVE_OPENPTY
2162 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2163 return edk2_error();
2164 #elif defined(HAVE__GETPTY)
2165 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2166 if (slave_name == NULL)
2167 return edk2_error();
2168
2169 slave_fd = open(slave_name, O_RDWR);
2170 if (slave_fd < 0)
2171 return edk2_error();
2172 #else
2173 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
2174 if (master_fd < 0)
2175 return edk2_error();
2176 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
2177 /* change permission of slave */
2178 if (grantpt(master_fd) < 0) {
2179 PyOS_setsig(SIGCHLD, sig_saved);
2180 return edk2_error();
2181 }
2182 /* unlock slave */
2183 if (unlockpt(master_fd) < 0) {
2184 PyOS_setsig(SIGCHLD, sig_saved);
2185 return edk2_error();
2186 }
2187 PyOS_setsig(SIGCHLD, sig_saved);
2188 slave_name = ptsname(master_fd); /* get name of slave */
2189 if (slave_name == NULL)
2190 return edk2_error();
2191 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2192 if (slave_fd < 0)
2193 return edk2_error();
2194 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
2195 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2196 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
2197 #ifndef __hpux
2198 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
2199 #endif /* __hpux */
2200 #endif /* HAVE_CYGWIN */
2201 #endif /* HAVE_OPENPTY */
2202
2203 return Py_BuildValue("(ii)", master_fd, slave_fd);
2204
2205 }
2206 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
2207
2208 #ifdef HAVE_FORKPTY
2209 PyDoc_STRVAR(edk2_forkpty__doc__,
2210 "forkpty() -> (pid, master_fd)\n\n\
2211 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2212 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
2213 To both, return fd of newly opened pseudo-terminal.\n");
2214
2215 static PyObject *
edk2_forkpty(PyObject * self,PyObject * noargs)2216 edk2_forkpty(PyObject *self, PyObject *noargs)
2217 {
2218 int master_fd = -1, result = 0;
2219 pid_t pid;
2220
2221 _PyImport_AcquireLock();
2222 pid = forkpty(&master_fd, NULL, NULL, NULL);
2223 if (pid == 0) {
2224 /* child: this clobbers and resets the import lock. */
2225 PyOS_AfterFork();
2226 } else {
2227 /* parent: release the import lock. */
2228 result = _PyImport_ReleaseLock();
2229 }
2230 if (pid == -1)
2231 return edk2_error();
2232 if (result < 0) {
2233 /* Don't clobber the OSError if the fork failed. */
2234 PyErr_SetString(PyExc_RuntimeError,
2235 "not holding the import lock");
2236 return NULL;
2237 }
2238 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
2239 }
2240 #endif
2241
2242 PyDoc_STRVAR(edk2_getpid__doc__,
2243 "getpid() -> pid\n\n\
2244 Return the current process id");
2245
2246 static PyObject *
edk2_getpid(PyObject * self,PyObject * noargs)2247 edk2_getpid(PyObject *self, PyObject *noargs)
2248 {
2249 return PyLong_FromPid(getpid());
2250 }
2251
2252
2253 #ifdef HAVE_GETLOGIN
2254 PyDoc_STRVAR(edk2_getlogin__doc__,
2255 "getlogin() -> string\n\n\
2256 Return the actual login name.");
2257
2258 static PyObject *
edk2_getlogin(PyObject * self,PyObject * noargs)2259 edk2_getlogin(PyObject *self, PyObject *noargs)
2260 {
2261 PyObject *result = NULL;
2262 char *name;
2263 int old_errno = errno;
2264
2265 errno = 0;
2266 name = getlogin();
2267 if (name == NULL) {
2268 if (errno)
2269 edk2_error();
2270 else
2271 PyErr_SetString(PyExc_OSError,
2272 "unable to determine login name");
2273 }
2274 else
2275 result = PyString_FromString(name);
2276 errno = old_errno;
2277
2278 return result;
2279 }
2280 #endif
2281
2282 #ifdef HAVE_KILL
2283 PyDoc_STRVAR(edk2_kill__doc__,
2284 "kill(pid, sig)\n\n\
2285 Kill a process with a signal.");
2286
2287 static PyObject *
edk2_kill(PyObject * self,PyObject * args)2288 edk2_kill(PyObject *self, PyObject *args)
2289 {
2290 pid_t pid;
2291 int sig;
2292 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
2293 return NULL;
2294 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
2295 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2296 APIRET rc;
2297 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
2298 return os2_error(rc);
2299
2300 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2301 APIRET rc;
2302 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
2303 return os2_error(rc);
2304
2305 } else
2306 return NULL; /* Unrecognized Signal Requested */
2307 #else
2308 if (kill(pid, sig) == -1)
2309 return edk2_error();
2310 #endif
2311 Py_INCREF(Py_None);
2312 return Py_None;
2313 }
2314 #endif
2315
2316 #ifdef HAVE_PLOCK
2317
2318 #ifdef HAVE_SYS_LOCK_H
2319 #include <sys/lock.h>
2320 #endif
2321
2322 PyDoc_STRVAR(edk2_plock__doc__,
2323 "plock(op)\n\n\
2324 Lock program segments into memory.");
2325
2326 static PyObject *
edk2_plock(PyObject * self,PyObject * args)2327 edk2_plock(PyObject *self, PyObject *args)
2328 {
2329 int op;
2330 if (!PyArg_ParseTuple(args, "i:plock", &op))
2331 return NULL;
2332 if (plock(op) == -1)
2333 return edk2_error();
2334 Py_INCREF(Py_None);
2335 return Py_None;
2336 }
2337 #endif
2338
2339
2340 #ifdef HAVE_POPEN
2341 PyDoc_STRVAR(edk2_popen__doc__,
2342 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
2343 Open a pipe to/from a command returning a file object.");
2344
2345 static PyObject *
edk2_popen(PyObject * self,PyObject * args)2346 edk2_popen(PyObject *self, PyObject *args)
2347 {
2348 char *name;
2349 char *mode = "r";
2350 int bufsize = -1;
2351 FILE *fp;
2352 PyObject *f;
2353 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2354 return NULL;
2355 /* Strip mode of binary or text modifiers */
2356 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
2357 mode = "r";
2358 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
2359 mode = "w";
2360 Py_BEGIN_ALLOW_THREADS
2361 fp = popen(name, mode);
2362 Py_END_ALLOW_THREADS
2363 if (fp == NULL)
2364 return edk2_error();
2365 f = PyFile_FromFile(fp, name, mode, pclose);
2366 if (f != NULL)
2367 PyFile_SetBufSize(f, bufsize);
2368 return f;
2369 }
2370
2371 #endif /* HAVE_POPEN */
2372
2373
2374 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
2375 static PyObject *
wait_helper(pid_t pid,int status,struct rusage * ru)2376 wait_helper(pid_t pid, int status, struct rusage *ru)
2377 {
2378 PyObject *result;
2379 static PyObject *struct_rusage;
2380
2381 if (pid == -1)
2382 return edk2_error();
2383
2384 if (struct_rusage == NULL) {
2385 PyObject *m = PyImport_ImportModuleNoBlock("resource");
2386 if (m == NULL)
2387 return NULL;
2388 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
2389 Py_DECREF(m);
2390 if (struct_rusage == NULL)
2391 return NULL;
2392 }
2393
2394 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
2395 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
2396 if (!result)
2397 return NULL;
2398
2399 #ifndef doubletime
2400 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
2401 #endif
2402
2403 PyStructSequence_SET_ITEM(result, 0,
2404 PyFloat_FromDouble(doubletime(ru->ru_utime)));
2405 PyStructSequence_SET_ITEM(result, 1,
2406 PyFloat_FromDouble(doubletime(ru->ru_stime)));
2407 #define SET_INT(result, index, value)\
2408 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
2409 SET_INT(result, 2, ru->ru_maxrss);
2410 SET_INT(result, 3, ru->ru_ixrss);
2411 SET_INT(result, 4, ru->ru_idrss);
2412 SET_INT(result, 5, ru->ru_isrss);
2413 SET_INT(result, 6, ru->ru_minflt);
2414 SET_INT(result, 7, ru->ru_majflt);
2415 SET_INT(result, 8, ru->ru_nswap);
2416 SET_INT(result, 9, ru->ru_inblock);
2417 SET_INT(result, 10, ru->ru_oublock);
2418 SET_INT(result, 11, ru->ru_msgsnd);
2419 SET_INT(result, 12, ru->ru_msgrcv);
2420 SET_INT(result, 13, ru->ru_nsignals);
2421 SET_INT(result, 14, ru->ru_nvcsw);
2422 SET_INT(result, 15, ru->ru_nivcsw);
2423 #undef SET_INT
2424
2425 if (PyErr_Occurred()) {
2426 Py_DECREF(result);
2427 return NULL;
2428 }
2429
2430 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
2431 }
2432 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
2433
2434 #ifdef HAVE_WAIT3
2435 PyDoc_STRVAR(edk2_wait3__doc__,
2436 "wait3(options) -> (pid, status, rusage)\n\n\
2437 Wait for completion of a child process.");
2438
2439 static PyObject *
edk2_wait3(PyObject * self,PyObject * args)2440 edk2_wait3(PyObject *self, PyObject *args)
2441 {
2442 pid_t pid;
2443 int options;
2444 struct rusage ru;
2445 WAIT_TYPE status;
2446 WAIT_STATUS_INT(status) = 0;
2447
2448 if (!PyArg_ParseTuple(args, "i:wait3", &options))
2449 return NULL;
2450
2451 Py_BEGIN_ALLOW_THREADS
2452 pid = wait3(&status, options, &ru);
2453 Py_END_ALLOW_THREADS
2454
2455 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
2456 }
2457 #endif /* HAVE_WAIT3 */
2458
2459 #ifdef HAVE_WAIT4
2460 PyDoc_STRVAR(edk2_wait4__doc__,
2461 "wait4(pid, options) -> (pid, status, rusage)\n\n\
2462 Wait for completion of a given child process.");
2463
2464 static PyObject *
edk2_wait4(PyObject * self,PyObject * args)2465 edk2_wait4(PyObject *self, PyObject *args)
2466 {
2467 pid_t pid;
2468 int options;
2469 struct rusage ru;
2470 WAIT_TYPE status;
2471 WAIT_STATUS_INT(status) = 0;
2472
2473 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
2474 return NULL;
2475
2476 Py_BEGIN_ALLOW_THREADS
2477 pid = wait4(pid, &status, options, &ru);
2478 Py_END_ALLOW_THREADS
2479
2480 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
2481 }
2482 #endif /* HAVE_WAIT4 */
2483
2484 #ifdef HAVE_WAITPID
2485 PyDoc_STRVAR(edk2_waitpid__doc__,
2486 "waitpid(pid, options) -> (pid, status)\n\n\
2487 Wait for completion of a given child process.");
2488
2489 static PyObject *
edk2_waitpid(PyObject * self,PyObject * args)2490 edk2_waitpid(PyObject *self, PyObject *args)
2491 {
2492 pid_t pid;
2493 int options;
2494 WAIT_TYPE status;
2495 WAIT_STATUS_INT(status) = 0;
2496
2497 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
2498 return NULL;
2499 Py_BEGIN_ALLOW_THREADS
2500 pid = waitpid(pid, &status, options);
2501 Py_END_ALLOW_THREADS
2502 if (pid == -1)
2503 return edk2_error();
2504
2505 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
2506 }
2507
2508 #elif defined(HAVE_CWAIT)
2509
2510 /* MS C has a variant of waitpid() that's usable for most purposes. */
2511 PyDoc_STRVAR(edk2_waitpid__doc__,
2512 "waitpid(pid, options) -> (pid, status << 8)\n\n"
2513 "Wait for completion of a given process. options is ignored on Windows.");
2514
2515 static PyObject *
edk2_waitpid(PyObject * self,PyObject * args)2516 edk2_waitpid(PyObject *self, PyObject *args)
2517 {
2518 Py_intptr_t pid;
2519 int status, options;
2520
2521 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
2522 return NULL;
2523 Py_BEGIN_ALLOW_THREADS
2524 pid = _cwait(&status, pid, options);
2525 Py_END_ALLOW_THREADS
2526 if (pid == -1)
2527 return edk2_error();
2528
2529 /* shift the status left a byte so this is more like the POSIX waitpid */
2530 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
2531 }
2532 #endif /* HAVE_WAITPID || HAVE_CWAIT */
2533
2534 #ifdef HAVE_WAIT
2535 PyDoc_STRVAR(edk2_wait__doc__,
2536 "wait() -> (pid, status)\n\n\
2537 Wait for completion of a child process.");
2538
2539 static PyObject *
edk2_wait(PyObject * self,PyObject * noargs)2540 edk2_wait(PyObject *self, PyObject *noargs)
2541 {
2542 pid_t pid;
2543 WAIT_TYPE status;
2544 WAIT_STATUS_INT(status) = 0;
2545
2546 Py_BEGIN_ALLOW_THREADS
2547 pid = wait(&status);
2548 Py_END_ALLOW_THREADS
2549 if (pid == -1)
2550 return edk2_error();
2551
2552 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
2553 }
2554 #endif
2555
2556
2557 PyDoc_STRVAR(edk2_lstat__doc__,
2558 "lstat(path) -> stat result\n\n\
2559 Like stat(path), but do not follow symbolic links.");
2560
2561 static PyObject *
edk2_lstat(PyObject * self,PyObject * args)2562 edk2_lstat(PyObject *self, PyObject *args)
2563 {
2564 #ifdef HAVE_LSTAT
2565 return edk2_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
2566 #else /* !HAVE_LSTAT */
2567 return edk2_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
2568 #endif /* !HAVE_LSTAT */
2569 }
2570
2571
2572 #ifdef HAVE_READLINK
2573 PyDoc_STRVAR(edk2_readlink__doc__,
2574 "readlink(path) -> path\n\n\
2575 Return a string representing the path to which the symbolic link points.");
2576
2577 static PyObject *
edk2_readlink(PyObject * self,PyObject * args)2578 edk2_readlink(PyObject *self, PyObject *args)
2579 {
2580 PyObject* v;
2581 char buf[MAXPATHLEN];
2582 char *path;
2583 int n;
2584 #ifdef Py_USING_UNICODE
2585 int arg_is_unicode = 0;
2586 #endif
2587
2588 if (!PyArg_ParseTuple(args, "et:readlink",
2589 Py_FileSystemDefaultEncoding, &path))
2590 return NULL;
2591 #ifdef Py_USING_UNICODE
2592 v = PySequence_GetItem(args, 0);
2593 if (v == NULL) {
2594 PyMem_Free(path);
2595 return NULL;
2596 }
2597
2598 if (PyUnicode_Check(v)) {
2599 arg_is_unicode = 1;
2600 }
2601 Py_DECREF(v);
2602 #endif
2603
2604 Py_BEGIN_ALLOW_THREADS
2605 n = readlink(path, buf, (int) sizeof buf);
2606 Py_END_ALLOW_THREADS
2607 if (n < 0)
2608 return edk2_error_with_allocated_filename(path);
2609
2610 PyMem_Free(path);
2611 v = PyString_FromStringAndSize(buf, n);
2612 #ifdef Py_USING_UNICODE
2613 if (arg_is_unicode) {
2614 PyObject *w;
2615
2616 w = PyUnicode_FromEncodedObject(v,
2617 Py_FileSystemDefaultEncoding,
2618 "strict");
2619 if (w != NULL) {
2620 Py_DECREF(v);
2621 v = w;
2622 }
2623 else {
2624 /* fall back to the original byte string, as
2625 discussed in patch #683592 */
2626 PyErr_Clear();
2627 }
2628 }
2629 #endif
2630 return v;
2631 }
2632 #endif /* HAVE_READLINK */
2633
2634
2635 #ifdef HAVE_SYMLINK
2636 PyDoc_STRVAR(edk2_symlink__doc__,
2637 "symlink(src, dst)\n\n\
2638 Create a symbolic link pointing to src named dst.");
2639
2640 static PyObject *
edk2_symlink(PyObject * self,PyObject * args)2641 edk2_symlink(PyObject *self, PyObject *args)
2642 {
2643 return edk2_2str(args, "etet:symlink", symlink);
2644 }
2645 #endif /* HAVE_SYMLINK */
2646
2647
2648 #ifdef HAVE_TIMES
2649 #define NEED_TICKS_PER_SECOND
2650 static long ticks_per_second = -1;
2651 static PyObject *
edk2_times(PyObject * self,PyObject * noargs)2652 edk2_times(PyObject *self, PyObject *noargs)
2653 {
2654 struct tms t;
2655 clock_t c;
2656 errno = 0;
2657 c = times(&t);
2658 if (c == (clock_t) -1)
2659 return edk2_error();
2660 return Py_BuildValue("ddddd",
2661 (double)t.tms_utime / ticks_per_second,
2662 (double)t.tms_stime / ticks_per_second,
2663 (double)t.tms_cutime / ticks_per_second,
2664 (double)t.tms_cstime / ticks_per_second,
2665 (double)c / ticks_per_second);
2666 }
2667 #endif /* HAVE_TIMES */
2668
2669
2670 #ifdef HAVE_TIMES
2671 PyDoc_STRVAR(edk2_times__doc__,
2672 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
2673 Return a tuple of floating point numbers indicating process times.");
2674 #endif
2675
2676
2677 #ifdef HAVE_GETSID
2678 PyDoc_STRVAR(edk2_getsid__doc__,
2679 "getsid(pid) -> sid\n\n\
2680 Call the system call getsid().");
2681
2682 static PyObject *
edk2_getsid(PyObject * self,PyObject * args)2683 edk2_getsid(PyObject *self, PyObject *args)
2684 {
2685 pid_t pid;
2686 int sid;
2687 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
2688 return NULL;
2689 sid = getsid(pid);
2690 if (sid < 0)
2691 return edk2_error();
2692 return PyInt_FromLong((long)sid);
2693 }
2694 #endif /* HAVE_GETSID */
2695
2696
2697 #ifdef HAVE_SETSID
2698 PyDoc_STRVAR(edk2_setsid__doc__,
2699 "setsid()\n\n\
2700 Call the system call setsid().");
2701
2702 static PyObject *
edk2_setsid(PyObject * self,PyObject * noargs)2703 edk2_setsid(PyObject *self, PyObject *noargs)
2704 {
2705 if (setsid() < 0)
2706 return edk2_error();
2707 Py_INCREF(Py_None);
2708 return Py_None;
2709 }
2710 #endif /* HAVE_SETSID */
2711
2712 #ifdef HAVE_SETPGID
2713 PyDoc_STRVAR(edk2_setpgid__doc__,
2714 "setpgid(pid, pgrp)\n\n\
2715 Call the system call setpgid().");
2716
2717 static PyObject *
edk2_setpgid(PyObject * self,PyObject * args)2718 edk2_setpgid(PyObject *self, PyObject *args)
2719 {
2720 pid_t pid;
2721 int pgrp;
2722 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
2723 return NULL;
2724 if (setpgid(pid, pgrp) < 0)
2725 return edk2_error();
2726 Py_INCREF(Py_None);
2727 return Py_None;
2728 }
2729 #endif /* HAVE_SETPGID */
2730
2731
2732 #ifdef HAVE_TCGETPGRP
2733 PyDoc_STRVAR(edk2_tcgetpgrp__doc__,
2734 "tcgetpgrp(fd) -> pgid\n\n\
2735 Return the process group associated with the terminal given by a fd.");
2736
2737 static PyObject *
edk2_tcgetpgrp(PyObject * self,PyObject * args)2738 edk2_tcgetpgrp(PyObject *self, PyObject *args)
2739 {
2740 int fd;
2741 pid_t pgid;
2742 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
2743 return NULL;
2744 pgid = tcgetpgrp(fd);
2745 if (pgid < 0)
2746 return edk2_error();
2747 return PyLong_FromPid(pgid);
2748 }
2749 #endif /* HAVE_TCGETPGRP */
2750
2751
2752 #ifdef HAVE_TCSETPGRP
2753 PyDoc_STRVAR(edk2_tcsetpgrp__doc__,
2754 "tcsetpgrp(fd, pgid)\n\n\
2755 Set the process group associated with the terminal given by a fd.");
2756
2757 static PyObject *
edk2_tcsetpgrp(PyObject * self,PyObject * args)2758 edk2_tcsetpgrp(PyObject *self, PyObject *args)
2759 {
2760 int fd;
2761 pid_t pgid;
2762 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
2763 return NULL;
2764 if (tcsetpgrp(fd, pgid) < 0)
2765 return edk2_error();
2766 Py_INCREF(Py_None);
2767 return Py_None;
2768 }
2769 #endif /* HAVE_TCSETPGRP */
2770
2771 /* Functions acting on file descriptors */
2772
2773 PyDoc_STRVAR(edk2_open__doc__,
2774 "open(filename, flag [, mode=0777]) -> fd\n\n\
2775 Open a file (for low level IO).");
2776
2777 static PyObject *
edk2_open(PyObject * self,PyObject * args)2778 edk2_open(PyObject *self, PyObject *args)
2779 {
2780 char *file = NULL;
2781 int flag;
2782 int mode = 0777;
2783 int fd;
2784
2785 if (!PyArg_ParseTuple(args, "eti|i",
2786 Py_FileSystemDefaultEncoding, &file,
2787 &flag, &mode))
2788 return NULL;
2789
2790 Py_BEGIN_ALLOW_THREADS
2791 fd = open(file, flag, mode);
2792 Py_END_ALLOW_THREADS
2793 if (fd < 0)
2794 return edk2_error_with_allocated_filename(file);
2795 PyMem_Free(file);
2796 return PyInt_FromLong((long)fd);
2797 }
2798
2799
2800 PyDoc_STRVAR(edk2_close__doc__,
2801 "close(fd)\n\n\
2802 Close a file descriptor (for low level IO).");
2803
2804 static PyObject *
edk2_close(PyObject * self,PyObject * args)2805 edk2_close(PyObject *self, PyObject *args)
2806 {
2807 int fd, res;
2808 if (!PyArg_ParseTuple(args, "i:close", &fd))
2809 return NULL;
2810 if (!_PyVerify_fd(fd))
2811 return edk2_error();
2812 Py_BEGIN_ALLOW_THREADS
2813 res = close(fd);
2814 Py_END_ALLOW_THREADS
2815 if (res < 0)
2816 return edk2_error();
2817 Py_INCREF(Py_None);
2818 return Py_None;
2819 }
2820
2821
2822 PyDoc_STRVAR(edk2_closerange__doc__,
2823 "closerange(fd_low, fd_high)\n\n\
2824 Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
2825
2826 static PyObject *
edk2_closerange(PyObject * self,PyObject * args)2827 edk2_closerange(PyObject *self, PyObject *args)
2828 {
2829 int fd_from, fd_to, i;
2830 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
2831 return NULL;
2832 Py_BEGIN_ALLOW_THREADS
2833 for (i = fd_from; i < fd_to; i++)
2834 if (_PyVerify_fd(i))
2835 close(i);
2836 Py_END_ALLOW_THREADS
2837 Py_RETURN_NONE;
2838 }
2839
2840
2841 PyDoc_STRVAR(edk2_dup__doc__,
2842 "dup(fd) -> fd2\n\n\
2843 Return a duplicate of a file descriptor.");
2844
2845 static PyObject *
edk2_dup(PyObject * self,PyObject * args)2846 edk2_dup(PyObject *self, PyObject *args)
2847 {
2848 int fd;
2849 if (!PyArg_ParseTuple(args, "i:dup", &fd))
2850 return NULL;
2851 if (!_PyVerify_fd(fd))
2852 return edk2_error();
2853 Py_BEGIN_ALLOW_THREADS
2854 fd = dup(fd);
2855 Py_END_ALLOW_THREADS
2856 if (fd < 0)
2857 return edk2_error();
2858 return PyInt_FromLong((long)fd);
2859 }
2860
2861
2862 PyDoc_STRVAR(edk2_dup2__doc__,
2863 "dup2(old_fd, new_fd)\n\n\
2864 Duplicate file descriptor.");
2865
2866 static PyObject *
edk2_dup2(PyObject * self,PyObject * args)2867 edk2_dup2(PyObject *self, PyObject *args)
2868 {
2869 int fd, fd2, res;
2870 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
2871 return NULL;
2872 if (!_PyVerify_fd_dup2(fd, fd2))
2873 return edk2_error();
2874 Py_BEGIN_ALLOW_THREADS
2875 res = dup2(fd, fd2);
2876 Py_END_ALLOW_THREADS
2877 if (res < 0)
2878 return edk2_error();
2879 Py_INCREF(Py_None);
2880 return Py_None;
2881 }
2882
2883
2884 PyDoc_STRVAR(edk2_lseek__doc__,
2885 "lseek(fd, pos, how) -> newpos\n\n\
2886 Set the current position of a file descriptor.");
2887
2888 static PyObject *
edk2_lseek(PyObject * self,PyObject * args)2889 edk2_lseek(PyObject *self, PyObject *args)
2890 {
2891 int fd, how;
2892 off_t pos, res;
2893 PyObject *posobj;
2894 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
2895 return NULL;
2896 #ifdef SEEK_SET
2897 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
2898 switch (how) {
2899 case 0: how = SEEK_SET; break;
2900 case 1: how = SEEK_CUR; break;
2901 case 2: how = SEEK_END; break;
2902 }
2903 #endif /* SEEK_END */
2904
2905 #if !defined(HAVE_LARGEFILE_SUPPORT)
2906 pos = PyInt_AsLong(posobj);
2907 #else
2908 pos = PyLong_Check(posobj) ?
2909 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
2910 #endif
2911 if (PyErr_Occurred())
2912 return NULL;
2913
2914 if (!_PyVerify_fd(fd))
2915 return edk2_error();
2916 Py_BEGIN_ALLOW_THREADS
2917 res = lseek(fd, pos, how);
2918 Py_END_ALLOW_THREADS
2919 if (res < 0)
2920 return edk2_error();
2921
2922 #if !defined(HAVE_LARGEFILE_SUPPORT)
2923 return PyInt_FromLong(res);
2924 #else
2925 return PyLong_FromLongLong(res);
2926 #endif
2927 }
2928
2929
2930 PyDoc_STRVAR(edk2_read__doc__,
2931 "read(fd, buffersize) -> string\n\n\
2932 Read a file descriptor.");
2933
2934 static PyObject *
edk2_read(PyObject * self,PyObject * args)2935 edk2_read(PyObject *self, PyObject *args)
2936 {
2937 int fd, size, n;
2938 PyObject *buffer;
2939 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
2940 return NULL;
2941 if (size < 0) {
2942 errno = EINVAL;
2943 return edk2_error();
2944 }
2945 buffer = PyString_FromStringAndSize((char *)NULL, size);
2946 if (buffer == NULL)
2947 return NULL;
2948 if (!_PyVerify_fd(fd)) {
2949 Py_DECREF(buffer);
2950 return edk2_error();
2951 }
2952 Py_BEGIN_ALLOW_THREADS
2953 n = read(fd, PyString_AsString(buffer), size);
2954 Py_END_ALLOW_THREADS
2955 if (n < 0) {
2956 Py_DECREF(buffer);
2957 return edk2_error();
2958 }
2959 if (n != size)
2960 _PyString_Resize(&buffer, n);
2961 return buffer;
2962 }
2963
2964
2965 PyDoc_STRVAR(edk2_write__doc__,
2966 "write(fd, string) -> byteswritten\n\n\
2967 Write a string to a file descriptor.");
2968
2969 static PyObject *
edk2_write(PyObject * self,PyObject * args)2970 edk2_write(PyObject *self, PyObject *args)
2971 {
2972 Py_buffer pbuf;
2973 int fd;
2974 Py_ssize_t size;
2975
2976 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
2977 return NULL;
2978 if (!_PyVerify_fd(fd)) {
2979 PyBuffer_Release(&pbuf);
2980 return edk2_error();
2981 }
2982 Py_BEGIN_ALLOW_THREADS
2983 size = write(fd, pbuf.buf, (size_t)pbuf.len);
2984 Py_END_ALLOW_THREADS
2985 PyBuffer_Release(&pbuf);
2986 if (size < 0)
2987 return edk2_error();
2988 return PyInt_FromSsize_t(size);
2989 }
2990
2991
2992 PyDoc_STRVAR(edk2_fstat__doc__,
2993 "fstat(fd) -> stat result\n\n\
2994 Like stat(), but for an open file descriptor.");
2995
2996 static PyObject *
edk2_fstat(PyObject * self,PyObject * args)2997 edk2_fstat(PyObject *self, PyObject *args)
2998 {
2999 int fd;
3000 STRUCT_STAT st;
3001 int res;
3002 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
3003 return NULL;
3004 if (!_PyVerify_fd(fd))
3005 return edk2_error();
3006 Py_BEGIN_ALLOW_THREADS
3007 res = FSTAT(fd, &st);
3008 Py_END_ALLOW_THREADS
3009 if (res != 0) {
3010 return edk2_error();
3011 }
3012
3013 return _pystat_fromstructstat(&st);
3014 }
3015
3016
3017 PyDoc_STRVAR(edk2_fdopen__doc__,
3018 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
3019 Return an open file object connected to a file descriptor.");
3020
3021 static PyObject *
edk2_fdopen(PyObject * self,PyObject * args)3022 edk2_fdopen(PyObject *self, PyObject *args)
3023 {
3024 int fd;
3025 char *orgmode = "r";
3026 int bufsize = -1;
3027 FILE *fp;
3028 PyObject *f;
3029 char *mode;
3030 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
3031 return NULL;
3032
3033 /* Sanitize mode. See fileobject.c */
3034 mode = PyMem_MALLOC(strlen(orgmode)+3);
3035 if (!mode) {
3036 PyErr_NoMemory();
3037 return NULL;
3038 }
3039 strcpy(mode, orgmode);
3040 if (_PyFile_SanitizeMode(mode)) {
3041 PyMem_FREE(mode);
3042 return NULL;
3043 }
3044 if (!_PyVerify_fd(fd))
3045 return edk2_error();
3046 Py_BEGIN_ALLOW_THREADS
3047 #if defined(HAVE_FCNTL_H)
3048 if (mode[0] == 'a') {
3049 /* try to make sure the O_APPEND flag is set */
3050 int flags;
3051 flags = fcntl(fd, F_GETFL);
3052 if (flags != -1)
3053 fcntl(fd, F_SETFL, flags | O_APPEND);
3054 fp = fdopen(fd, mode);
3055 if (fp == NULL && flags != -1)
3056 /* restore old mode if fdopen failed */
3057 fcntl(fd, F_SETFL, flags);
3058 } else {
3059 fp = fdopen(fd, mode);
3060 }
3061 #else
3062 fp = fdopen(fd, mode);
3063 #endif
3064 Py_END_ALLOW_THREADS
3065 PyMem_FREE(mode);
3066 if (fp == NULL)
3067 return edk2_error();
3068 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
3069 if (f != NULL)
3070 PyFile_SetBufSize(f, bufsize);
3071 return f;
3072 }
3073
3074 PyDoc_STRVAR(edk2_isatty__doc__,
3075 "isatty(fd) -> bool\n\n\
3076 Return True if the file descriptor 'fd' is an open file descriptor\n\
3077 connected to the slave end of a terminal.");
3078
3079 static PyObject *
edk2_isatty(PyObject * self,PyObject * args)3080 edk2_isatty(PyObject *self, PyObject *args)
3081 {
3082 int fd;
3083 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3084 return NULL;
3085 if (!_PyVerify_fd(fd))
3086 return PyBool_FromLong(0);
3087 return PyBool_FromLong(isatty(fd));
3088 }
3089
3090 #ifdef HAVE_PIPE
3091 PyDoc_STRVAR(edk2_pipe__doc__,
3092 "pipe() -> (read_end, write_end)\n\n\
3093 Create a pipe.");
3094
3095 static PyObject *
edk2_pipe(PyObject * self,PyObject * noargs)3096 edk2_pipe(PyObject *self, PyObject *noargs)
3097 {
3098 int fds[2];
3099 int res;
3100 Py_BEGIN_ALLOW_THREADS
3101 res = pipe(fds);
3102 Py_END_ALLOW_THREADS
3103 if (res != 0)
3104 return edk2_error();
3105 return Py_BuildValue("(ii)", fds[0], fds[1]);
3106 }
3107 #endif /* HAVE_PIPE */
3108
3109
3110 #ifdef HAVE_MKFIFO
3111 PyDoc_STRVAR(edk2_mkfifo__doc__,
3112 "mkfifo(filename [, mode=0666])\n\n\
3113 Create a FIFO (a POSIX named pipe).");
3114
3115 static PyObject *
edk2_mkfifo(PyObject * self,PyObject * args)3116 edk2_mkfifo(PyObject *self, PyObject *args)
3117 {
3118 char *filename;
3119 int mode = 0666;
3120 int res;
3121 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
3122 return NULL;
3123 Py_BEGIN_ALLOW_THREADS
3124 res = mkfifo(filename, mode);
3125 Py_END_ALLOW_THREADS
3126 if (res < 0)
3127 return edk2_error();
3128 Py_INCREF(Py_None);
3129 return Py_None;
3130 }
3131 #endif
3132
3133
3134 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
3135 PyDoc_STRVAR(edk2_mknod__doc__,
3136 "mknod(filename [, mode=0600, device])\n\n\
3137 Create a filesystem node (file, device special file or named pipe)\n\
3138 named filename. mode specifies both the permissions to use and the\n\
3139 type of node to be created, being combined (bitwise OR) with one of\n\
3140 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
3141 device defines the newly created device special file (probably using\n\
3142 os.makedev()), otherwise it is ignored.");
3143
3144
3145 static PyObject *
edk2_mknod(PyObject * self,PyObject * args)3146 edk2_mknod(PyObject *self, PyObject *args)
3147 {
3148 char *filename;
3149 int mode = 0600;
3150 int device = 0;
3151 int res;
3152 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
3153 return NULL;
3154 Py_BEGIN_ALLOW_THREADS
3155 res = mknod(filename, mode, device);
3156 Py_END_ALLOW_THREADS
3157 if (res < 0)
3158 return edk2_error();
3159 Py_INCREF(Py_None);
3160 return Py_None;
3161 }
3162 #endif
3163
3164 #ifdef HAVE_DEVICE_MACROS
3165 PyDoc_STRVAR(edk2_major__doc__,
3166 "major(device) -> major number\n\
3167 Extracts a device major number from a raw device number.");
3168
3169 static PyObject *
edk2_major(PyObject * self,PyObject * args)3170 edk2_major(PyObject *self, PyObject *args)
3171 {
3172 int device;
3173 if (!PyArg_ParseTuple(args, "i:major", &device))
3174 return NULL;
3175 return PyInt_FromLong((long)major(device));
3176 }
3177
3178 PyDoc_STRVAR(edk2_minor__doc__,
3179 "minor(device) -> minor number\n\
3180 Extracts a device minor number from a raw device number.");
3181
3182 static PyObject *
edk2_minor(PyObject * self,PyObject * args)3183 edk2_minor(PyObject *self, PyObject *args)
3184 {
3185 int device;
3186 if (!PyArg_ParseTuple(args, "i:minor", &device))
3187 return NULL;
3188 return PyInt_FromLong((long)minor(device));
3189 }
3190
3191 PyDoc_STRVAR(edk2_makedev__doc__,
3192 "makedev(major, minor) -> device number\n\
3193 Composes a raw device number from the major and minor device numbers.");
3194
3195 static PyObject *
edk2_makedev(PyObject * self,PyObject * args)3196 edk2_makedev(PyObject *self, PyObject *args)
3197 {
3198 int major, minor;
3199 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
3200 return NULL;
3201 return PyInt_FromLong((long)makedev(major, minor));
3202 }
3203 #endif /* device macros */
3204
3205
3206 #ifdef HAVE_FTRUNCATE
3207 PyDoc_STRVAR(edk2_ftruncate__doc__,
3208 "ftruncate(fd, length)\n\n\
3209 Truncate a file to a specified length.");
3210
3211 static PyObject *
edk2_ftruncate(PyObject * self,PyObject * args)3212 edk2_ftruncate(PyObject *self, PyObject *args)
3213 {
3214 int fd;
3215 off_t length;
3216 int res;
3217 PyObject *lenobj;
3218
3219 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
3220 return NULL;
3221
3222 #if !defined(HAVE_LARGEFILE_SUPPORT)
3223 length = PyInt_AsLong(lenobj);
3224 #else
3225 length = PyLong_Check(lenobj) ?
3226 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3227 #endif
3228 if (PyErr_Occurred())
3229 return NULL;
3230
3231 Py_BEGIN_ALLOW_THREADS
3232 res = ftruncate(fd, length);
3233 Py_END_ALLOW_THREADS
3234 if (res < 0)
3235 return edk2_error();
3236 Py_INCREF(Py_None);
3237 return Py_None;
3238 }
3239 #endif
3240
3241 #ifdef HAVE_PUTENV
3242 PyDoc_STRVAR(edk2_putenv__doc__,
3243 "putenv(key, value)\n\n\
3244 Change or add an environment variable.");
3245
3246 /* Save putenv() parameters as values here, so we can collect them when they
3247 * get re-set with another call for the same key. */
3248 static PyObject *edk2_putenv_garbage;
3249
3250 static PyObject *
edk2_putenv(PyObject * self,PyObject * args)3251 edk2_putenv(PyObject *self, PyObject *args)
3252 {
3253 char *s1, *s2;
3254 char *newenv;
3255 PyObject *newstr;
3256 size_t len;
3257
3258 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
3259 return NULL;
3260
3261 /* XXX This can leak memory -- not easy to fix :-( */
3262 len = strlen(s1) + strlen(s2) + 2;
3263 /* len includes space for a trailing \0; the size arg to
3264 PyString_FromStringAndSize does not count that */
3265 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
3266 if (newstr == NULL)
3267 return PyErr_NoMemory();
3268 newenv = PyString_AS_STRING(newstr);
3269 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
3270 if (putenv(newenv)) {
3271 Py_DECREF(newstr);
3272 edk2_error();
3273 return NULL;
3274 }
3275 /* Install the first arg and newstr in edk2_putenv_garbage;
3276 * this will cause previous value to be collected. This has to
3277 * happen after the real putenv() call because the old value
3278 * was still accessible until then. */
3279 if (PyDict_SetItem(edk2_putenv_garbage,
3280 PyTuple_GET_ITEM(args, 0), newstr)) {
3281 /* really not much we can do; just leak */
3282 PyErr_Clear();
3283 }
3284 else {
3285 Py_DECREF(newstr);
3286 }
3287
3288 Py_INCREF(Py_None);
3289 return Py_None;
3290 }
3291 #endif /* putenv */
3292
3293 #ifdef HAVE_UNSETENV
3294 PyDoc_STRVAR(edk2_unsetenv__doc__,
3295 "unsetenv(key)\n\n\
3296 Delete an environment variable.");
3297
3298 static PyObject *
edk2_unsetenv(PyObject * self,PyObject * args)3299 edk2_unsetenv(PyObject *self, PyObject *args)
3300 {
3301 char *s1;
3302
3303 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
3304 return NULL;
3305
3306 unsetenv(s1);
3307
3308 /* Remove the key from edk2_putenv_garbage;
3309 * this will cause it to be collected. This has to
3310 * happen after the real unsetenv() call because the
3311 * old value was still accessible until then.
3312 */
3313 if (PyDict_DelItem(edk2_putenv_garbage,
3314 PyTuple_GET_ITEM(args, 0))) {
3315 /* really not much we can do; just leak */
3316 PyErr_Clear();
3317 }
3318
3319 Py_INCREF(Py_None);
3320 return Py_None;
3321 }
3322 #endif /* unsetenv */
3323
3324 PyDoc_STRVAR(edk2_strerror__doc__,
3325 "strerror(code) -> string\n\n\
3326 Translate an error code to a message string.");
3327
3328 static PyObject *
edk2_strerror(PyObject * self,PyObject * args)3329 edk2_strerror(PyObject *self, PyObject *args)
3330 {
3331 int code;
3332 char *message;
3333 if (!PyArg_ParseTuple(args, "i:strerror", &code))
3334 return NULL;
3335 message = strerror(code);
3336 if (message == NULL) {
3337 PyErr_SetString(PyExc_ValueError,
3338 "strerror() argument out of range");
3339 return NULL;
3340 }
3341 return PyString_FromString(message);
3342 }
3343
3344
3345 #ifdef HAVE_SYS_WAIT_H
3346
3347 #ifdef WCOREDUMP
3348 PyDoc_STRVAR(edk2_WCOREDUMP__doc__,
3349 "WCOREDUMP(status) -> bool\n\n\
3350 Return True if the process returning 'status' was dumped to a core file.");
3351
3352 static PyObject *
edk2_WCOREDUMP(PyObject * self,PyObject * args)3353 edk2_WCOREDUMP(PyObject *self, PyObject *args)
3354 {
3355 WAIT_TYPE status;
3356 WAIT_STATUS_INT(status) = 0;
3357
3358 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
3359 return NULL;
3360
3361 return PyBool_FromLong(WCOREDUMP(status));
3362 }
3363 #endif /* WCOREDUMP */
3364
3365 #ifdef WIFCONTINUED
3366 PyDoc_STRVAR(edk2_WIFCONTINUED__doc__,
3367 "WIFCONTINUED(status) -> bool\n\n\
3368 Return True if the process returning 'status' was continued from a\n\
3369 job control stop.");
3370
3371 static PyObject *
edk2_WIFCONTINUED(PyObject * self,PyObject * args)3372 edk2_WIFCONTINUED(PyObject *self, PyObject *args)
3373 {
3374 WAIT_TYPE status;
3375 WAIT_STATUS_INT(status) = 0;
3376
3377 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
3378 return NULL;
3379
3380 return PyBool_FromLong(WIFCONTINUED(status));
3381 }
3382 #endif /* WIFCONTINUED */
3383
3384 #ifdef WIFSTOPPED
3385 PyDoc_STRVAR(edk2_WIFSTOPPED__doc__,
3386 "WIFSTOPPED(status) -> bool\n\n\
3387 Return True if the process returning 'status' was stopped.");
3388
3389 static PyObject *
edk2_WIFSTOPPED(PyObject * self,PyObject * args)3390 edk2_WIFSTOPPED(PyObject *self, PyObject *args)
3391 {
3392 WAIT_TYPE status;
3393 WAIT_STATUS_INT(status) = 0;
3394
3395 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
3396 return NULL;
3397
3398 return PyBool_FromLong(WIFSTOPPED(status));
3399 }
3400 #endif /* WIFSTOPPED */
3401
3402 #ifdef WIFSIGNALED
3403 PyDoc_STRVAR(edk2_WIFSIGNALED__doc__,
3404 "WIFSIGNALED(status) -> bool\n\n\
3405 Return True if the process returning 'status' was terminated by a signal.");
3406
3407 static PyObject *
edk2_WIFSIGNALED(PyObject * self,PyObject * args)3408 edk2_WIFSIGNALED(PyObject *self, PyObject *args)
3409 {
3410 WAIT_TYPE status;
3411 WAIT_STATUS_INT(status) = 0;
3412
3413 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
3414 return NULL;
3415
3416 return PyBool_FromLong(WIFSIGNALED(status));
3417 }
3418 #endif /* WIFSIGNALED */
3419
3420 #ifdef WIFEXITED
3421 PyDoc_STRVAR(edk2_WIFEXITED__doc__,
3422 "WIFEXITED(status) -> bool\n\n\
3423 Return true if the process returning 'status' exited using the exit()\n\
3424 system call.");
3425
3426 static PyObject *
edk2_WIFEXITED(PyObject * self,PyObject * args)3427 edk2_WIFEXITED(PyObject *self, PyObject *args)
3428 {
3429 WAIT_TYPE status;
3430 WAIT_STATUS_INT(status) = 0;
3431
3432 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
3433 return NULL;
3434
3435 return PyBool_FromLong(WIFEXITED(status));
3436 }
3437 #endif /* WIFEXITED */
3438
3439 #ifdef WEXITSTATUS
3440 PyDoc_STRVAR(edk2_WEXITSTATUS__doc__,
3441 "WEXITSTATUS(status) -> integer\n\n\
3442 Return the process return code from 'status'.");
3443
3444 static PyObject *
edk2_WEXITSTATUS(PyObject * self,PyObject * args)3445 edk2_WEXITSTATUS(PyObject *self, PyObject *args)
3446 {
3447 WAIT_TYPE status;
3448 WAIT_STATUS_INT(status) = 0;
3449
3450 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
3451 return NULL;
3452
3453 return Py_BuildValue("i", WEXITSTATUS(status));
3454 }
3455 #endif /* WEXITSTATUS */
3456
3457 #ifdef WTERMSIG
3458 PyDoc_STRVAR(edk2_WTERMSIG__doc__,
3459 "WTERMSIG(status) -> integer\n\n\
3460 Return the signal that terminated the process that provided the 'status'\n\
3461 value.");
3462
3463 static PyObject *
edk2_WTERMSIG(PyObject * self,PyObject * args)3464 edk2_WTERMSIG(PyObject *self, PyObject *args)
3465 {
3466 WAIT_TYPE status;
3467 WAIT_STATUS_INT(status) = 0;
3468
3469 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
3470 return NULL;
3471
3472 return Py_BuildValue("i", WTERMSIG(status));
3473 }
3474 #endif /* WTERMSIG */
3475
3476 #ifdef WSTOPSIG
3477 PyDoc_STRVAR(edk2_WSTOPSIG__doc__,
3478 "WSTOPSIG(status) -> integer\n\n\
3479 Return the signal that stopped the process that provided\n\
3480 the 'status' value.");
3481
3482 static PyObject *
edk2_WSTOPSIG(PyObject * self,PyObject * args)3483 edk2_WSTOPSIG(PyObject *self, PyObject *args)
3484 {
3485 WAIT_TYPE status;
3486 WAIT_STATUS_INT(status) = 0;
3487
3488 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
3489 return NULL;
3490
3491 return Py_BuildValue("i", WSTOPSIG(status));
3492 }
3493 #endif /* WSTOPSIG */
3494
3495 #endif /* HAVE_SYS_WAIT_H */
3496
3497
3498 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
3499 #include <sys/statvfs.h>
3500
3501 static PyObject*
_pystatvfs_fromstructstatvfs(struct statvfs st)3502 _pystatvfs_fromstructstatvfs(struct statvfs st) {
3503 PyObject *v = PyStructSequence_New(&StatVFSResultType);
3504 if (v == NULL)
3505 return NULL;
3506
3507 #if !defined(HAVE_LARGEFILE_SUPPORT)
3508 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
3509 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
3510 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
3511 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
3512 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
3513 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
3514 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
3515 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
3516 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
3517 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
3518 #else
3519 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
3520 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
3521 PyStructSequence_SET_ITEM(v, 2,
3522 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
3523 PyStructSequence_SET_ITEM(v, 3,
3524 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
3525 PyStructSequence_SET_ITEM(v, 4,
3526 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
3527 PyStructSequence_SET_ITEM(v, 5,
3528 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
3529 PyStructSequence_SET_ITEM(v, 6,
3530 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
3531 PyStructSequence_SET_ITEM(v, 7,
3532 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
3533 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
3534 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
3535 #endif
3536
3537 return v;
3538 }
3539
3540 PyDoc_STRVAR(edk2_fstatvfs__doc__,
3541 "fstatvfs(fd) -> statvfs result\n\n\
3542 Perform an fstatvfs system call on the given fd.");
3543
3544 static PyObject *
edk2_fstatvfs(PyObject * self,PyObject * args)3545 edk2_fstatvfs(PyObject *self, PyObject *args)
3546 {
3547 int fd, res;
3548 struct statvfs st;
3549
3550 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
3551 return NULL;
3552 Py_BEGIN_ALLOW_THREADS
3553 res = fstatvfs(fd, &st);
3554 Py_END_ALLOW_THREADS
3555 if (res != 0)
3556 return edk2_error();
3557
3558 return _pystatvfs_fromstructstatvfs(st);
3559 }
3560 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
3561
3562
3563 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
3564 #include <sys/statvfs.h>
3565
3566 PyDoc_STRVAR(edk2_statvfs__doc__,
3567 "statvfs(path) -> statvfs result\n\n\
3568 Perform a statvfs system call on the given path.");
3569
3570 static PyObject *
edk2_statvfs(PyObject * self,PyObject * args)3571 edk2_statvfs(PyObject *self, PyObject *args)
3572 {
3573 char *path;
3574 int res;
3575 struct statvfs st;
3576 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
3577 return NULL;
3578 Py_BEGIN_ALLOW_THREADS
3579 res = statvfs(path, &st);
3580 Py_END_ALLOW_THREADS
3581 if (res != 0)
3582 return edk2_error_with_filename(path);
3583
3584 return _pystatvfs_fromstructstatvfs(st);
3585 }
3586 #endif /* HAVE_STATVFS */
3587
3588
3589 #ifdef HAVE_TEMPNAM
3590 PyDoc_STRVAR(edk2_tempnam__doc__,
3591 "tempnam([dir[, prefix]]) -> string\n\n\
3592 Return a unique name for a temporary file.\n\
3593 The directory and a prefix may be specified as strings; they may be omitted\n\
3594 or None if not needed.");
3595
3596 static PyObject *
edk2_tempnam(PyObject * self,PyObject * args)3597 edk2_tempnam(PyObject *self, PyObject *args)
3598 {
3599 PyObject *result = NULL;
3600 char *dir = NULL;
3601 char *pfx = NULL;
3602 char *name;
3603
3604 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
3605 return NULL;
3606
3607 if (PyErr_Warn(PyExc_RuntimeWarning,
3608 "tempnam is a potential security risk to your program") < 0)
3609 return NULL;
3610
3611 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
3612 "use the tempfile module", 1) < 0)
3613 return NULL;
3614
3615 name = tempnam(dir, pfx);
3616 if (name == NULL)
3617 return PyErr_NoMemory();
3618 result = PyString_FromString(name);
3619 free(name);
3620 return result;
3621 }
3622 #endif
3623
3624
3625 #ifdef HAVE_TMPFILE
3626 PyDoc_STRVAR(edk2_tmpfile__doc__,
3627 "tmpfile() -> file object\n\n\
3628 Create a temporary file with no directory entries.");
3629
3630 static PyObject *
edk2_tmpfile(PyObject * self,PyObject * noargs)3631 edk2_tmpfile(PyObject *self, PyObject *noargs)
3632 {
3633 FILE *fp;
3634
3635 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
3636 "use the tempfile module", 1) < 0)
3637 return NULL;
3638
3639 fp = tmpfile();
3640 if (fp == NULL)
3641 return edk2_error();
3642 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
3643 }
3644 #endif
3645
3646
3647 #ifdef HAVE_TMPNAM
3648 PyDoc_STRVAR(edk2_tmpnam__doc__,
3649 "tmpnam() -> string\n\n\
3650 Return a unique name for a temporary file.");
3651
3652 static PyObject *
edk2_tmpnam(PyObject * self,PyObject * noargs)3653 edk2_tmpnam(PyObject *self, PyObject *noargs)
3654 {
3655 char buffer[L_tmpnam];
3656 char *name;
3657
3658 if (PyErr_Warn(PyExc_RuntimeWarning,
3659 "tmpnam is a potential security risk to your program") < 0)
3660 return NULL;
3661
3662 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
3663 "use the tempfile module", 1) < 0)
3664 return NULL;
3665
3666 #ifdef USE_TMPNAM_R
3667 name = tmpnam_r(buffer);
3668 #else
3669 name = tmpnam(buffer);
3670 #endif
3671 if (name == NULL) {
3672 PyObject *err = Py_BuildValue("is", 0,
3673 #ifdef USE_TMPNAM_R
3674 "unexpected NULL from tmpnam_r"
3675 #else
3676 "unexpected NULL from tmpnam"
3677 #endif
3678 );
3679 PyErr_SetObject(PyExc_OSError, err);
3680 Py_XDECREF(err);
3681 return NULL;
3682 }
3683 return PyString_FromString(buffer);
3684 }
3685 #endif
3686
3687 PyDoc_STRVAR(edk2_abort__doc__,
3688 "abort() -> does not return!\n\n\
3689 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
3690 in the hardest way possible on the hosting operating system.");
3691
3692 static PyObject *
edk2_abort(PyObject * self,PyObject * noargs)3693 edk2_abort(PyObject *self, PyObject *noargs)
3694 {
3695 abort();
3696 /*NOTREACHED*/
3697 Py_FatalError("abort() called from Python code didn't abort!");
3698 return NULL;
3699 }
3700
3701 static PyMethodDef edk2_methods[] = {
3702 {"access", edk2_access, METH_VARARGS, edk2_access__doc__},
3703 #ifdef HAVE_TTYNAME
3704 {"ttyname", edk2_ttyname, METH_VARARGS, edk2_ttyname__doc__},
3705 #endif
3706 {"chdir", edk2_chdir, METH_VARARGS, edk2_chdir__doc__},
3707 #ifdef HAVE_CHFLAGS
3708 {"chflags", edk2_chflags, METH_VARARGS, edk2_chflags__doc__},
3709 #endif /* HAVE_CHFLAGS */
3710 {"chmod", edk2_chmod, METH_VARARGS, edk2_chmod__doc__},
3711 #ifdef HAVE_FCHMOD
3712 {"fchmod", edk2_fchmod, METH_VARARGS, edk2_fchmod__doc__},
3713 #endif /* HAVE_FCHMOD */
3714 #ifdef HAVE_CHOWN
3715 {"chown", edk2_chown, METH_VARARGS, edk2_chown__doc__},
3716 #endif /* HAVE_CHOWN */
3717 #ifdef HAVE_LCHMOD
3718 {"lchmod", edk2_lchmod, METH_VARARGS, edk2_lchmod__doc__},
3719 #endif /* HAVE_LCHMOD */
3720 #ifdef HAVE_FCHOWN
3721 {"fchown", edk2_fchown, METH_VARARGS, edk2_fchown__doc__},
3722 #endif /* HAVE_FCHOWN */
3723 #ifdef HAVE_LCHFLAGS
3724 {"lchflags", edk2_lchflags, METH_VARARGS, edk2_lchflags__doc__},
3725 #endif /* HAVE_LCHFLAGS */
3726 #ifdef HAVE_LCHOWN
3727 {"lchown", edk2_lchown, METH_VARARGS, edk2_lchown__doc__},
3728 #endif /* HAVE_LCHOWN */
3729 #ifdef HAVE_CHROOT
3730 {"chroot", edk2_chroot, METH_VARARGS, edk2_chroot__doc__},
3731 #endif
3732 #ifdef HAVE_CTERMID
3733 {"ctermid", edk2_ctermid, METH_NOARGS, edk2_ctermid__doc__},
3734 #endif
3735 #ifdef HAVE_GETCWD
3736 {"getcwd", edk2_getcwd, METH_NOARGS, edk2_getcwd__doc__},
3737 #ifdef Py_USING_UNICODE
3738 {"getcwdu", edk2_getcwdu, METH_NOARGS, edk2_getcwdu__doc__},
3739 #endif
3740 #endif
3741 #ifdef HAVE_LINK
3742 {"link", edk2_link, METH_VARARGS, edk2_link__doc__},
3743 #endif /* HAVE_LINK */
3744 {"listdir", edk2_listdir, METH_VARARGS, edk2_listdir__doc__},
3745 {"lstat", edk2_lstat, METH_VARARGS, edk2_lstat__doc__},
3746 {"mkdir", edk2_mkdir, METH_VARARGS, edk2_mkdir__doc__},
3747 #ifdef HAVE_NICE
3748 {"nice", edk2_nice, METH_VARARGS, edk2_nice__doc__},
3749 #endif /* HAVE_NICE */
3750 #ifdef HAVE_READLINK
3751 {"readlink", edk2_readlink, METH_VARARGS, edk2_readlink__doc__},
3752 #endif /* HAVE_READLINK */
3753 {"rename", edk2_rename, METH_VARARGS, edk2_rename__doc__},
3754 {"rmdir", edk2_rmdir, METH_VARARGS, edk2_rmdir__doc__},
3755 {"stat", edk2_stat, METH_VARARGS, edk2_stat__doc__},
3756 //{"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
3757 #ifdef HAVE_SYMLINK
3758 {"symlink", edk2_symlink, METH_VARARGS, edk2_symlink__doc__},
3759 #endif /* HAVE_SYMLINK */
3760 #ifdef HAVE_SYSTEM
3761 {"system", edk2_system, METH_VARARGS, edk2_system__doc__},
3762 #endif
3763 {"umask", edk2_umask, METH_VARARGS, edk2_umask__doc__},
3764 #ifdef HAVE_UNAME
3765 {"uname", edk2_uname, METH_NOARGS, edk2_uname__doc__},
3766 #endif /* HAVE_UNAME */
3767 {"unlink", edk2_unlink, METH_VARARGS, edk2_unlink__doc__},
3768 {"remove", edk2_unlink, METH_VARARGS, edk2_remove__doc__},
3769 {"utime", edk2_utime, METH_VARARGS, edk2_utime__doc__},
3770 #ifdef HAVE_TIMES
3771 {"times", edk2_times, METH_NOARGS, edk2_times__doc__},
3772 #endif /* HAVE_TIMES */
3773 {"_exit", edk2__exit, METH_VARARGS, edk2__exit__doc__},
3774 #ifdef HAVE_EXECV
3775 {"execv", edk2_execv, METH_VARARGS, edk2_execv__doc__},
3776 {"execve", edk2_execve, METH_VARARGS, edk2_execve__doc__},
3777 #endif /* HAVE_EXECV */
3778 #ifdef HAVE_SPAWNV
3779 {"spawnv", edk2_spawnv, METH_VARARGS, edk2_spawnv__doc__},
3780 {"spawnve", edk2_spawnve, METH_VARARGS, edk2_spawnve__doc__},
3781 #if defined(PYOS_OS2)
3782 {"spawnvp", edk2_spawnvp, METH_VARARGS, edk2_spawnvp__doc__},
3783 {"spawnvpe", edk2_spawnvpe, METH_VARARGS, edk2_spawnvpe__doc__},
3784 #endif /* PYOS_OS2 */
3785 #endif /* HAVE_SPAWNV */
3786 #ifdef HAVE_FORK1
3787 {"fork1", edk2_fork1, METH_NOARGS, edk2_fork1__doc__},
3788 #endif /* HAVE_FORK1 */
3789 #ifdef HAVE_FORK
3790 {"fork", edk2_fork, METH_NOARGS, edk2_fork__doc__},
3791 #endif /* HAVE_FORK */
3792 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3793 {"openpty", edk2_openpty, METH_NOARGS, edk2_openpty__doc__},
3794 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
3795 #ifdef HAVE_FORKPTY
3796 {"forkpty", edk2_forkpty, METH_NOARGS, edk2_forkpty__doc__},
3797 #endif /* HAVE_FORKPTY */
3798 {"getpid", edk2_getpid, METH_NOARGS, edk2_getpid__doc__},
3799 #ifdef HAVE_GETPGRP
3800 {"getpgrp", edk2_getpgrp, METH_NOARGS, edk2_getpgrp__doc__},
3801 #endif /* HAVE_GETPGRP */
3802 #ifdef HAVE_GETPPID
3803 {"getppid", edk2_getppid, METH_NOARGS, edk2_getppid__doc__},
3804 #endif /* HAVE_GETPPID */
3805 #ifdef HAVE_GETLOGIN
3806 {"getlogin", edk2_getlogin, METH_NOARGS, edk2_getlogin__doc__},
3807 #endif
3808 #ifdef HAVE_KILL
3809 {"kill", edk2_kill, METH_VARARGS, edk2_kill__doc__},
3810 #endif /* HAVE_KILL */
3811 #ifdef HAVE_KILLPG
3812 {"killpg", edk2_killpg, METH_VARARGS, edk2_killpg__doc__},
3813 #endif /* HAVE_KILLPG */
3814 #ifdef HAVE_PLOCK
3815 {"plock", edk2_plock, METH_VARARGS, edk2_plock__doc__},
3816 #endif /* HAVE_PLOCK */
3817 #ifdef HAVE_POPEN
3818 {"popen", edk2_popen, METH_VARARGS, edk2_popen__doc__},
3819 #endif /* HAVE_POPEN */
3820 #ifdef HAVE_SETGROUPS
3821 {"setgroups", edk2_setgroups, METH_O, edk2_setgroups__doc__},
3822 #endif /* HAVE_SETGROUPS */
3823 #ifdef HAVE_INITGROUPS
3824 {"initgroups", edk2_initgroups, METH_VARARGS, edk2_initgroups__doc__},
3825 #endif /* HAVE_INITGROUPS */
3826 #ifdef HAVE_GETPGID
3827 {"getpgid", edk2_getpgid, METH_VARARGS, edk2_getpgid__doc__},
3828 #endif /* HAVE_GETPGID */
3829 #ifdef HAVE_SETPGRP
3830 {"setpgrp", edk2_setpgrp, METH_NOARGS, edk2_setpgrp__doc__},
3831 #endif /* HAVE_SETPGRP */
3832 #ifdef HAVE_WAIT
3833 {"wait", edk2_wait, METH_NOARGS, edk2_wait__doc__},
3834 #endif /* HAVE_WAIT */
3835 #ifdef HAVE_WAIT3
3836 {"wait3", edk2_wait3, METH_VARARGS, edk2_wait3__doc__},
3837 #endif /* HAVE_WAIT3 */
3838 #ifdef HAVE_WAIT4
3839 {"wait4", edk2_wait4, METH_VARARGS, edk2_wait4__doc__},
3840 #endif /* HAVE_WAIT4 */
3841 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
3842 {"waitpid", edk2_waitpid, METH_VARARGS, edk2_waitpid__doc__},
3843 #endif /* HAVE_WAITPID */
3844 #ifdef HAVE_GETSID
3845 {"getsid", edk2_getsid, METH_VARARGS, edk2_getsid__doc__},
3846 #endif /* HAVE_GETSID */
3847 #ifdef HAVE_SETSID
3848 {"setsid", edk2_setsid, METH_NOARGS, edk2_setsid__doc__},
3849 #endif /* HAVE_SETSID */
3850 #ifdef HAVE_SETPGID
3851 {"setpgid", edk2_setpgid, METH_VARARGS, edk2_setpgid__doc__},
3852 #endif /* HAVE_SETPGID */
3853 #ifdef HAVE_TCGETPGRP
3854 {"tcgetpgrp", edk2_tcgetpgrp, METH_VARARGS, edk2_tcgetpgrp__doc__},
3855 #endif /* HAVE_TCGETPGRP */
3856 #ifdef HAVE_TCSETPGRP
3857 {"tcsetpgrp", edk2_tcsetpgrp, METH_VARARGS, edk2_tcsetpgrp__doc__},
3858 #endif /* HAVE_TCSETPGRP */
3859 {"open", edk2_open, METH_VARARGS, edk2_open__doc__},
3860 {"close", edk2_close, METH_VARARGS, edk2_close__doc__},
3861 {"closerange", edk2_closerange, METH_VARARGS, edk2_closerange__doc__},
3862 {"dup", edk2_dup, METH_VARARGS, edk2_dup__doc__},
3863 {"dup2", edk2_dup2, METH_VARARGS, edk2_dup2__doc__},
3864 {"lseek", edk2_lseek, METH_VARARGS, edk2_lseek__doc__},
3865 {"read", edk2_read, METH_VARARGS, edk2_read__doc__},
3866 {"write", edk2_write, METH_VARARGS, edk2_write__doc__},
3867 {"fstat", edk2_fstat, METH_VARARGS, edk2_fstat__doc__},
3868 {"fdopen", edk2_fdopen, METH_VARARGS, edk2_fdopen__doc__},
3869 {"isatty", edk2_isatty, METH_VARARGS, edk2_isatty__doc__},
3870 #ifdef HAVE_PIPE
3871 {"pipe", edk2_pipe, METH_NOARGS, edk2_pipe__doc__},
3872 #endif
3873 #ifdef HAVE_MKFIFO
3874 {"mkfifo", edk2_mkfifo, METH_VARARGS, edk2_mkfifo__doc__},
3875 #endif
3876 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
3877 {"mknod", edk2_mknod, METH_VARARGS, edk2_mknod__doc__},
3878 #endif
3879 #ifdef HAVE_DEVICE_MACROS
3880 {"major", edk2_major, METH_VARARGS, edk2_major__doc__},
3881 {"minor", edk2_minor, METH_VARARGS, edk2_minor__doc__},
3882 {"makedev", edk2_makedev, METH_VARARGS, edk2_makedev__doc__},
3883 #endif
3884 #ifdef HAVE_FTRUNCATE
3885 {"ftruncate", edk2_ftruncate, METH_VARARGS, edk2_ftruncate__doc__},
3886 #endif
3887 #ifdef HAVE_PUTENV
3888 {"putenv", edk2_putenv, METH_VARARGS, edk2_putenv__doc__},
3889 #endif
3890 #ifdef HAVE_UNSETENV
3891 {"unsetenv", edk2_unsetenv, METH_VARARGS, edk2_unsetenv__doc__},
3892 #endif
3893 {"strerror", edk2_strerror, METH_VARARGS, edk2_strerror__doc__},
3894 #ifdef HAVE_FCHDIR
3895 {"fchdir", edk2_fchdir, METH_O, edk2_fchdir__doc__},
3896 #endif
3897 #ifdef HAVE_FSYNC
3898 {"fsync", edk2_fsync, METH_O, edk2_fsync__doc__},
3899 #endif
3900 #ifdef HAVE_FDATASYNC
3901 {"fdatasync", edk2_fdatasync, METH_O, edk2_fdatasync__doc__},
3902 #endif
3903 #ifdef HAVE_SYS_WAIT_H
3904 #ifdef WCOREDUMP
3905 {"WCOREDUMP", edk2_WCOREDUMP, METH_VARARGS, edk2_WCOREDUMP__doc__},
3906 #endif /* WCOREDUMP */
3907 #ifdef WIFCONTINUED
3908 {"WIFCONTINUED",edk2_WIFCONTINUED, METH_VARARGS, edk2_WIFCONTINUED__doc__},
3909 #endif /* WIFCONTINUED */
3910 #ifdef WIFSTOPPED
3911 {"WIFSTOPPED", edk2_WIFSTOPPED, METH_VARARGS, edk2_WIFSTOPPED__doc__},
3912 #endif /* WIFSTOPPED */
3913 #ifdef WIFSIGNALED
3914 {"WIFSIGNALED", edk2_WIFSIGNALED, METH_VARARGS, edk2_WIFSIGNALED__doc__},
3915 #endif /* WIFSIGNALED */
3916 #ifdef WIFEXITED
3917 {"WIFEXITED", edk2_WIFEXITED, METH_VARARGS, edk2_WIFEXITED__doc__},
3918 #endif /* WIFEXITED */
3919 #ifdef WEXITSTATUS
3920 {"WEXITSTATUS", edk2_WEXITSTATUS, METH_VARARGS, edk2_WEXITSTATUS__doc__},
3921 #endif /* WEXITSTATUS */
3922 #ifdef WTERMSIG
3923 {"WTERMSIG", edk2_WTERMSIG, METH_VARARGS, edk2_WTERMSIG__doc__},
3924 #endif /* WTERMSIG */
3925 #ifdef WSTOPSIG
3926 {"WSTOPSIG", edk2_WSTOPSIG, METH_VARARGS, edk2_WSTOPSIG__doc__},
3927 #endif /* WSTOPSIG */
3928 #endif /* HAVE_SYS_WAIT_H */
3929 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
3930 {"fstatvfs", edk2_fstatvfs, METH_VARARGS, edk2_fstatvfs__doc__},
3931 #endif
3932 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
3933 {"statvfs", edk2_statvfs, METH_VARARGS, edk2_statvfs__doc__},
3934 #endif
3935 #ifdef HAVE_TMPFILE
3936 {"tmpfile", edk2_tmpfile, METH_NOARGS, edk2_tmpfile__doc__},
3937 #endif
3938 #ifdef HAVE_TEMPNAM
3939 {"tempnam", edk2_tempnam, METH_VARARGS, edk2_tempnam__doc__},
3940 #endif
3941 #ifdef HAVE_TMPNAM
3942 {"tmpnam", edk2_tmpnam, METH_NOARGS, edk2_tmpnam__doc__},
3943 #endif
3944 #ifdef HAVE_CONFSTR
3945 {"confstr", edk2_confstr, METH_VARARGS, edk2_confstr__doc__},
3946 #endif
3947 #ifdef HAVE_SYSCONF
3948 {"sysconf", edk2_sysconf, METH_VARARGS, edk2_sysconf__doc__},
3949 #endif
3950 #ifdef HAVE_FPATHCONF
3951 {"fpathconf", edk2_fpathconf, METH_VARARGS, edk2_fpathconf__doc__},
3952 #endif
3953 #ifdef HAVE_PATHCONF
3954 {"pathconf", edk2_pathconf, METH_VARARGS, edk2_pathconf__doc__},
3955 #endif
3956 {"abort", edk2_abort, METH_NOARGS, edk2_abort__doc__},
3957
3958 {NULL, NULL} /* Sentinel */
3959 };
3960
3961
3962 static int
ins(PyObject * module,char * symbol,long value)3963 ins(PyObject *module, char *symbol, long value)
3964 {
3965 return PyModule_AddIntConstant(module, symbol, value);
3966 }
3967
3968 static int
all_ins(PyObject * d)3969 all_ins(PyObject *d)
3970 {
3971 #ifdef F_OK
3972 if (ins(d, "F_OK", (long)F_OK)) return -1;
3973 #endif
3974 #ifdef R_OK
3975 if (ins(d, "R_OK", (long)R_OK)) return -1;
3976 #endif
3977 #ifdef W_OK
3978 if (ins(d, "W_OK", (long)W_OK)) return -1;
3979 #endif
3980 #ifdef X_OK
3981 if (ins(d, "X_OK", (long)X_OK)) return -1;
3982 #endif
3983 #ifdef NGROUPS_MAX
3984 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
3985 #endif
3986 #ifdef TMP_MAX
3987 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
3988 #endif
3989 #ifdef WCONTINUED
3990 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
3991 #endif
3992 #ifdef WNOHANG
3993 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
3994 #endif
3995 #ifdef WUNTRACED
3996 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
3997 #endif
3998 #ifdef O_RDONLY
3999 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
4000 #endif
4001 #ifdef O_WRONLY
4002 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
4003 #endif
4004 #ifdef O_RDWR
4005 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
4006 #endif
4007 #ifdef O_NDELAY
4008 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
4009 #endif
4010 #ifdef O_NONBLOCK
4011 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
4012 #endif
4013 #ifdef O_APPEND
4014 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
4015 #endif
4016 #ifdef O_DSYNC
4017 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
4018 #endif
4019 #ifdef O_RSYNC
4020 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
4021 #endif
4022 #ifdef O_SYNC
4023 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
4024 #endif
4025 #ifdef O_NOCTTY
4026 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
4027 #endif
4028 #ifdef O_CREAT
4029 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
4030 #endif
4031 #ifdef O_EXCL
4032 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
4033 #endif
4034 #ifdef O_TRUNC
4035 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
4036 #endif
4037 #ifdef O_BINARY
4038 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
4039 #endif
4040 #ifdef O_TEXT
4041 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
4042 #endif
4043 #ifdef O_LARGEFILE
4044 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
4045 #endif
4046 #ifdef O_SHLOCK
4047 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
4048 #endif
4049 #ifdef O_EXLOCK
4050 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
4051 #endif
4052
4053 /* MS Windows */
4054 #ifdef O_NOINHERIT
4055 /* Don't inherit in child processes. */
4056 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
4057 #endif
4058 #ifdef _O_SHORT_LIVED
4059 /* Optimize for short life (keep in memory). */
4060 /* MS forgot to define this one with a non-underscore form too. */
4061 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
4062 #endif
4063 #ifdef O_TEMPORARY
4064 /* Automatically delete when last handle is closed. */
4065 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
4066 #endif
4067 #ifdef O_RANDOM
4068 /* Optimize for random access. */
4069 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
4070 #endif
4071 #ifdef O_SEQUENTIAL
4072 /* Optimize for sequential access. */
4073 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
4074 #endif
4075
4076 /* GNU extensions. */
4077 #ifdef O_ASYNC
4078 /* Send a SIGIO signal whenever input or output
4079 becomes available on file descriptor */
4080 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
4081 #endif
4082 #ifdef O_DIRECT
4083 /* Direct disk access. */
4084 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
4085 #endif
4086 #ifdef O_DIRECTORY
4087 /* Must be a directory. */
4088 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
4089 #endif
4090 #ifdef O_NOFOLLOW
4091 /* Do not follow links. */
4092 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
4093 #endif
4094 #ifdef O_NOATIME
4095 /* Do not update the access time. */
4096 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
4097 #endif
4098
4099 /* These come from sysexits.h */
4100 #ifdef EX_OK
4101 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
4102 #endif /* EX_OK */
4103 #ifdef EX_USAGE
4104 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
4105 #endif /* EX_USAGE */
4106 #ifdef EX_DATAERR
4107 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
4108 #endif /* EX_DATAERR */
4109 #ifdef EX_NOINPUT
4110 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
4111 #endif /* EX_NOINPUT */
4112 #ifdef EX_NOUSER
4113 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
4114 #endif /* EX_NOUSER */
4115 #ifdef EX_NOHOST
4116 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
4117 #endif /* EX_NOHOST */
4118 #ifdef EX_UNAVAILABLE
4119 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
4120 #endif /* EX_UNAVAILABLE */
4121 #ifdef EX_SOFTWARE
4122 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
4123 #endif /* EX_SOFTWARE */
4124 #ifdef EX_OSERR
4125 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
4126 #endif /* EX_OSERR */
4127 #ifdef EX_OSFILE
4128 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
4129 #endif /* EX_OSFILE */
4130 #ifdef EX_CANTCREAT
4131 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
4132 #endif /* EX_CANTCREAT */
4133 #ifdef EX_IOERR
4134 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
4135 #endif /* EX_IOERR */
4136 #ifdef EX_TEMPFAIL
4137 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
4138 #endif /* EX_TEMPFAIL */
4139 #ifdef EX_PROTOCOL
4140 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
4141 #endif /* EX_PROTOCOL */
4142 #ifdef EX_NOPERM
4143 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
4144 #endif /* EX_NOPERM */
4145 #ifdef EX_CONFIG
4146 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
4147 #endif /* EX_CONFIG */
4148 #ifdef EX_NOTFOUND
4149 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
4150 #endif /* EX_NOTFOUND */
4151
4152 #ifdef HAVE_SPAWNV
4153 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
4154 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
4155 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
4156 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
4157 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
4158 #endif
4159 return 0;
4160 }
4161
4162 #define INITFUNC initedk2
4163 #define MODNAME "edk2"
4164
4165 PyMODINIT_FUNC
INITFUNC(void)4166 INITFUNC(void)
4167 {
4168 PyObject *m;
4169
4170 #ifndef UEFI_C_SOURCE
4171 PyObject *v;
4172 #endif
4173
4174 m = Py_InitModule3(MODNAME,
4175 edk2_methods,
4176 edk2__doc__);
4177 if (m == NULL)
4178 return;
4179
4180 #ifndef UEFI_C_SOURCE
4181 /* Initialize environ dictionary */
4182 v = convertenviron();
4183 Py_XINCREF(v);
4184 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
4185 return;
4186 Py_DECREF(v);
4187 #endif /* UEFI_C_SOURCE */
4188
4189 if (all_ins(m))
4190 return;
4191
4192 Py_INCREF(PyExc_OSError);
4193 PyModule_AddObject(m, "error", PyExc_OSError);
4194
4195 #ifdef HAVE_PUTENV
4196 if (edk2_putenv_garbage == NULL)
4197 edk2_putenv_garbage = PyDict_New();
4198 #endif
4199
4200 if (!initialized) {
4201 stat_result_desc.name = MODNAME ".stat_result";
4202 stat_result_desc.fields[2].name = PyStructSequence_UnnamedField;
4203 stat_result_desc.fields[3].name = PyStructSequence_UnnamedField;
4204 stat_result_desc.fields[4].name = PyStructSequence_UnnamedField;
4205 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
4206 structseq_new = StatResultType.tp_new;
4207 StatResultType.tp_new = statresult_new;
4208
4209 //statvfs_result_desc.name = MODNAME ".statvfs_result";
4210 //PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
4211 #ifdef NEED_TICKS_PER_SECOND
4212 # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
4213 ticks_per_second = sysconf(_SC_CLK_TCK);
4214 # elif defined(HZ)
4215 ticks_per_second = HZ;
4216 # else
4217 ticks_per_second = 60; /* magic fallback value; may be bogus */
4218 # endif
4219 #endif
4220 }
4221 Py_INCREF((PyObject*) &StatResultType);
4222 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
4223 //Py_INCREF((PyObject*) &StatVFSResultType);
4224 //PyModule_AddObject(m, "statvfs_result",
4225 // (PyObject*) &StatVFSResultType);
4226 initialized = 1;
4227
4228 }
4229
4230 #ifdef __cplusplus
4231 }
4232 #endif
4233
4234
4235