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