]>
Commit | Line | Data |
---|---|---|
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 | |
26 | extern "C" {\r | |
27 | #endif\r | |
28 | \r | |
29 | PyDoc_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 | |
161 | extern char **environ;\r | |
162 | \r | |
163 | static PyObject *\r | |
164 | convertenviron(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 | |
204 | static PyObject *\r | |
42fa19ca | 205 | edk2_error(void)\r |
3ec97ca4 DM |
206 | {\r |
207 | return PyErr_SetFromErrno(PyExc_OSError);\r | |
208 | }\r | |
209 | static PyObject *\r | |
42fa19ca | 210 | edk2_error_with_filename(char* name)\r |
3ec97ca4 DM |
211 | {\r |
212 | return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);\r | |
213 | }\r | |
214 | \r | |
215 | \r | |
216 | static PyObject *\r | |
42fa19ca | 217 | edk2_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 | |
247 | static PyObject *\r | |
42fa19ca | 248 | edk2_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 | |
265 | static PyObject *\r | |
42fa19ca | 266 | edk2_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 | |
288 | PyDoc_STRVAR(stat_result__doc__,\r | |
289 | "stat_result: Result from stat or lstat.\n\n\\r | |
290 | This object may be accessed either as a tuple of\n\\r | |
291 | (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\\r | |
292 | or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\\r | |
293 | \n\\r | |
294 | Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\\r | |
295 | or st_flags, they are available as attributes only.\n\\r | |
296 | \n\\r | |
297 | See os.stat for more information.");\r | |
298 | \r | |
299 | static 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 | |
371 | static 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 | |
379 | PyDoc_STRVAR(statvfs_result__doc__,\r | |
380 | "statvfs_result: Result from statvfs or fstatvfs.\n\n\\r | |
381 | This object may be accessed either as a tuple of\n\\r | |
382 | (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\\r | |
383 | or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\\r | |
384 | \n\\r | |
385 | See os.statvfs for more information.");\r | |
386 | \r | |
387 | static 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 | |
401 | static 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 | |
408 | static PyTypeObject StatVFSResultType;\r | |
409 | #endif\r | |
410 | \r | |
411 | static int initialized;\r | |
412 | static PyTypeObject StatResultType;\r | |
413 | static newfunc structseq_new;\r | |
414 | \r | |
415 | static PyObject *\r | |
416 | statresult_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 | |
445 | PyDoc_STRVAR(stat_float_times__doc__,\r | |
446 | "stat_float_times([newval]) -> oldval\n\n\\r | |
447 | Determine whether os.[lf]stat represents time stamps as float objects.\n\\r | |
448 | If newval is True, future calls to stat() return floats, if it is False,\n\\r | |
449 | future calls return ints. \n\\r | |
450 | If newval is omitted, return the current setting.\n");\r | |
451 | \r | |
452 | static PyObject*\r | |
453 | stat_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 | |
468 | static void\r | |
469 | fill_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 |
491 | static 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 | |
559 | static PyObject *\r | |
42fa19ca | 560 | edk2_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 | 593 | PyDoc_STRVAR(edk2_access__doc__,\r |
3ec97ca4 DM |
594 | "access(path, mode) -> True if granted, False otherwise\n\n\\r |
595 | Use the real uid/gid to test for access to a path. Note that most\n\\r | |
596 | operations will use the effective uid/gid, therefore this routine can\n\\r | |
597 | be used in a suid/sgid environment to test if the invoking user has the\n\\r | |
598 | specified access to the path. The mode argument can be F_OK to test\n\\r | |
599 | existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");\r | |
600 | \r | |
601 | static PyObject *\r | |
42fa19ca | 602 | edk2_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 | 631 | PyDoc_STRVAR(edk2_chdir__doc__,\r |
3ec97ca4 DM |
632 | "chdir(path)\n\n\\r |
633 | Change the current working directory to the specified path.");\r | |
634 | \r | |
635 | static PyObject *\r | |
42fa19ca | 636 | edk2_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 | 641 | PyDoc_STRVAR(edk2_chmod__doc__,\r |
3ec97ca4 DM |
642 | "chmod(path, mode)\n\n\\r |
643 | Change the access permissions of a file.");\r | |
644 | \r | |
645 | static PyObject *\r | |
42fa19ca | 646 | edk2_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 | 665 | PyDoc_STRVAR(edk2_fchmod__doc__,\r |
3ec97ca4 DM |
666 | "fchmod(fd, mode)\n\n\\r |
667 | Change the access permissions of the file given by file\n\\r | |
668 | descriptor fd.");\r | |
669 | \r | |
670 | static PyObject *\r | |
42fa19ca | 671 | edk2_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 | 686 | PyDoc_STRVAR(edk2_lchmod__doc__,\r |
3ec97ca4 DM |
687 | "lchmod(path, mode)\n\n\\r |
688 | Change the access permissions of a file. If path is a symlink, this\n\\r | |
689 | affects the link itself rather than the target.");\r | |
690 | \r | |
691 | static PyObject *\r | |
42fa19ca | 692 | edk2_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 | 712 | PyDoc_STRVAR(edk2_chflags__doc__,\r |
3ec97ca4 DM |
713 | "chflags(path, flags)\n\n\\r |
714 | Set file flags.");\r | |
715 | \r | |
716 | static PyObject *\r | |
42fa19ca | 717 | edk2_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 | 737 | PyDoc_STRVAR(edk2_lchflags__doc__,\r |
3ec97ca4 DM |
738 | "lchflags(path, flags)\n\n\\r |
739 | Set file flags.\n\\r | |
740 | This function will not follow symbolic links.");\r | |
741 | \r | |
742 | static PyObject *\r | |
42fa19ca | 743 | edk2_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 | 763 | PyDoc_STRVAR(edk2_chroot__doc__,\r |
3ec97ca4 DM |
764 | "chroot(path)\n\n\\r |
765 | Change root directory to path.");\r | |
766 | \r | |
767 | static PyObject *\r | |
42fa19ca | 768 | edk2_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 | 775 | PyDoc_STRVAR(edk2_fsync__doc__,\r |
3ec97ca4 DM |
776 | "fsync(fildes)\n\n\\r |
777 | force write of file with filedescriptor to disk.");\r | |
778 | \r | |
779 | static PyObject *\r | |
42fa19ca | 780 | edk2_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 | |
789 | extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */\r | |
790 | #endif\r | |
791 | \r | |
42fa19ca | 792 | PyDoc_STRVAR(edk2_fdatasync__doc__,\r |
3ec97ca4 DM |
793 | "fdatasync(fildes)\n\n\\r |
794 | force write of file with filedescriptor to disk.\n\\r | |
795 | does not force update of metadata.");\r | |
796 | \r | |
797 | static PyObject *\r | |
42fa19ca | 798 | edk2_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 | 806 | PyDoc_STRVAR(edk2_chown__doc__,\r |
3ec97ca4 DM |
807 | "chown(path, uid, gid)\n\n\\r |
808 | Change the owner and group id of path to the numeric uid and gid.");\r | |
809 | \r | |
810 | static PyObject *\r | |
42fa19ca | 811 | edk2_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 | 832 | PyDoc_STRVAR(edk2_fchown__doc__,\r |
3ec97ca4 DM |
833 | "fchown(fd, uid, gid)\n\n\\r |
834 | Change the owner and group id of the file given by file descriptor\n\\r | |
835 | fd to the numeric uid and gid.");\r | |
836 | \r | |
837 | static PyObject *\r | |
42fa19ca | 838 | edk2_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 | 855 | PyDoc_STRVAR(edk2_lchown__doc__,\r |
3ec97ca4 DM |
856 | "lchown(path, uid, gid)\n\n\\r |
857 | Change the owner and group id of path to the numeric uid and gid.\n\\r | |
858 | This function will not follow symbolic links.");\r | |
859 | \r | |
860 | static PyObject *\r | |
42fa19ca | 861 | edk2_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 | 883 | PyDoc_STRVAR(edk2_getcwd__doc__,\r |
3ec97ca4 DM |
884 | "getcwd() -> path\n\n\\r |
885 | Return a string representing the current working directory.");\r | |
886 | \r | |
887 | static PyObject *\r | |
42fa19ca | 888 | edk2_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 | 920 | PyDoc_STRVAR(edk2_getcwdu__doc__,\r |
3ec97ca4 DM |
921 | "getcwdu() -> path\n\n\\r |
922 | Return a unicode string representing the current working directory.");\r | |
923 | \r | |
924 | static PyObject *\r | |
42fa19ca | 925 | edk2_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 | 941 | PyDoc_STRVAR(edk2_listdir__doc__,\r |
3ec97ca4 DM |
942 | "listdir(path) -> list_of_strings\n\n\\r |
943 | Return 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 | |
947 | The list is in arbitrary order. It does not include the special\n\\r | |
948 | entries '.' and '..' even if they are present in the directory.");\r | |
949 | \r | |
950 | static PyObject *\r | |
42fa19ca | 951 | edk2_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 | 1064 | PyDoc_STRVAR(edk2_mkdir__doc__,\r |
3ec97ca4 DM |
1065 | "mkdir(path [, mode=0777])\n\n\\r |
1066 | Create a directory.");\r | |
1067 | \r | |
1068 | static PyObject *\r | |
42fa19ca | 1069 | edk2_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 | 1096 | PyDoc_STRVAR(edk2_nice__doc__,\r |
3ec97ca4 DM |
1097 | "nice(inc) -> new_priority\n\n\\r |
1098 | Decrease the priority of process by inc and return the new priority.");\r | |
1099 | \r | |
1100 | static PyObject *\r | |
42fa19ca | 1101 | edk2_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 | 1131 | PyDoc_STRVAR(edk2_rename__doc__,\r |
3ec97ca4 DM |
1132 | "rename(old, new)\n\n\\r |
1133 | Rename a file or directory.");\r | |
1134 | \r | |
1135 | static PyObject *\r | |
42fa19ca | 1136 | edk2_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 | 1142 | PyDoc_STRVAR(edk2_rmdir__doc__,\r |
3ec97ca4 DM |
1143 | "rmdir(path)\n\n\\r |
1144 | Remove a directory.");\r | |
1145 | \r | |
1146 | static PyObject *\r | |
42fa19ca | 1147 | edk2_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 | 1153 | PyDoc_STRVAR(edk2_stat__doc__,\r |
3ec97ca4 DM |
1154 | "stat(path) -> stat result\n\n\\r |
1155 | Perform a stat system call on the given path.");\r | |
1156 | \r | |
1157 | static PyObject *\r | |
42fa19ca | 1158 | edk2_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 | 1165 | PyDoc_STRVAR(edk2_system__doc__,\r |
3ec97ca4 DM |
1166 | "system(command) -> exit_status\n\n\\r |
1167 | Execute the command (a string) in a subshell.");\r | |
1168 | \r | |
1169 | static PyObject *\r | |
42fa19ca | 1170 | edk2_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 | 1184 | PyDoc_STRVAR(edk2_umask__doc__,\r |
3ec97ca4 DM |
1185 | "umask(new_mask) -> old_mask\n\n\\r |
1186 | Set the current numeric umask and return the previous umask.");\r | |
1187 | \r | |
1188 | static PyObject *\r | |
42fa19ca | 1189 | edk2_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 | 1201 | PyDoc_STRVAR(edk2_unlink__doc__,\r |
3ec97ca4 DM |
1202 | "unlink(path)\n\n\\r |
1203 | Remove a file (same as remove(path)).");\r | |
1204 | \r | |
42fa19ca | 1205 | PyDoc_STRVAR(edk2_remove__doc__,\r |
3ec97ca4 DM |
1206 | "remove(path)\n\n\\r |
1207 | Remove a file (same as unlink(path)).");\r | |
1208 | \r | |
1209 | static PyObject *\r | |
42fa19ca | 1210 | edk2_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 | |
1216 | static int\r | |
1217 | extract_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 | 1253 | PyDoc_STRVAR(edk2_utime__doc__,\r |
3ec97ca4 DM |
1254 | "utime(path, (atime, mtime))\n\\r |
1255 | utime(path, None)\n\n\\r | |
1256 | Set the access and modified time of the file to the given values. If the\n\\r | |
1257 | second form is used, set the access and modified times to the current time.");\r | |
1258 | \r | |
1259 | static PyObject *\r | |
42fa19ca | 1260 | edk2_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 | 1340 | PyDoc_STRVAR(edk2__exit__doc__,\r |
3ec97ca4 DM |
1341 | "_exit(status)\n\n\\r |
1342 | Exit to the system with specified status, without normal exit processing.");\r | |
1343 | \r | |
1344 | static PyObject *\r | |
42fa19ca | 1345 | edk2__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 | |
1355 | static void\r | |
1356 | free_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 | 1367 | PyDoc_STRVAR(edk2_execv__doc__,\r |
3ec97ca4 DM |
1368 | "execv(path, args)\n\n\\r |
1369 | Execute 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 | |
1374 | static PyObject *\r | |
42fa19ca | 1375 | edk2_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 | 1438 | PyDoc_STRVAR(edk2_execve__doc__,\r |
3ec97ca4 DM |
1439 | "execve(path, args, env)\n\n\\r |
1440 | Execute 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 | |
1446 | static PyObject *\r | |
42fa19ca | 1447 | edk2_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 | 1583 | PyDoc_STRVAR(edk2_spawnv__doc__,\r |
3ec97ca4 DM |
1584 | "spawnv(mode, path, args)\n\n\\r |
1585 | Execute 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 | |
1591 | static PyObject *\r | |
42fa19ca | 1592 | edk2_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 | 1670 | PyDoc_STRVAR(edk2_spawnve__doc__,\r |
3ec97ca4 DM |
1671 | "spawnve(mode, path, args, env)\n\n\\r |
1672 | Execute 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 | |
1679 | static PyObject *\r | |
42fa19ca | 1680 | edk2_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 | 1825 | PyDoc_STRVAR(edk2_spawnvp__doc__,\r |
3ec97ca4 DM |
1826 | "spawnvp(mode, file, args)\n\n\\r |
1827 | Execute the program 'file' in a new process, using the environment\n\\r | |
1828 | search 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 | |
1834 | static PyObject *\r | |
42fa19ca | 1835 | edk2_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 | 1903 | PyDoc_STRVAR(edk2_spawnvpe__doc__,\r |
3ec97ca4 DM |
1904 | "spawnvpe(mode, file, args, env)\n\n\\r |
1905 | Execute the program 'file' in a new process, using the environment\n\\r | |
1906 | search 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 | |
1913 | static PyObject *\r | |
42fa19ca | 1914 | edk2_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 | 2051 | PyDoc_STRVAR(edk2_fork1__doc__,\r |
3ec97ca4 DM |
2052 | "fork1() -> pid\n\n\\r |
2053 | Fork a child process with a single multiplexed (i.e., not bound) thread.\n\\r | |
2054 | \n\\r | |
2055 | Return 0 to child process and PID of child to parent process.");\r | |
2056 | \r | |
2057 | static PyObject *\r | |
42fa19ca | 2058 | edk2_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 | 2085 | PyDoc_STRVAR(edk2_fork__doc__,\r |
3ec97ca4 DM |
2086 | "fork() -> pid\n\n\\r |
2087 | Fork a child process.\n\\r | |
2088 | Return 0 to child process and PID of child to parent process.");\r | |
2089 | \r | |
2090 | static PyObject *\r | |
42fa19ca | 2091 | edk2_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 | 2143 | PyDoc_STRVAR(edk2_openpty__doc__,\r |
3ec97ca4 DM |
2144 | "openpty() -> (master_fd, slave_fd)\n\n\\r |
2145 | Open a pseudo-terminal, returning open fd's for both master and slave end.\n");\r | |
2146 | \r | |
2147 | static PyObject *\r | |
42fa19ca | 2148 | edk2_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 | 2209 | PyDoc_STRVAR(edk2_forkpty__doc__,\r |
3ec97ca4 DM |
2210 | "forkpty() -> (pid, master_fd)\n\n\\r |
2211 | Fork a new process with a new pseudo-terminal as controlling tty.\n\n\\r | |
2212 | Like fork(), return 0 as pid to child process, and PID of child to parent.\n\\r | |
2213 | To both, return fd of newly opened pseudo-terminal.\n");\r | |
2214 | \r | |
2215 | static PyObject *\r | |
42fa19ca | 2216 | edk2_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 | 2242 | PyDoc_STRVAR(edk2_getpid__doc__,\r |
3ec97ca4 DM |
2243 | "getpid() -> pid\n\n\\r |
2244 | Return the current process id");\r | |
2245 | \r | |
2246 | static PyObject *\r | |
42fa19ca | 2247 | edk2_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 | 2254 | PyDoc_STRVAR(edk2_getlogin__doc__,\r |
3ec97ca4 DM |
2255 | "getlogin() -> string\n\n\\r |
2256 | Return the actual login name.");\r | |
2257 | \r | |
2258 | static PyObject *\r | |
42fa19ca | 2259 | edk2_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 | 2283 | PyDoc_STRVAR(edk2_kill__doc__,\r |
3ec97ca4 DM |
2284 | "kill(pid, sig)\n\n\\r |
2285 | Kill a process with a signal.");\r | |
2286 | \r | |
2287 | static PyObject *\r | |
42fa19ca | 2288 | edk2_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 | 2322 | PyDoc_STRVAR(edk2_plock__doc__,\r |
3ec97ca4 DM |
2323 | "plock(op)\n\n\\r |
2324 | Lock program segments into memory.");\r | |
2325 | \r | |
2326 | static PyObject *\r | |
42fa19ca | 2327 | edk2_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 | 2341 | PyDoc_STRVAR(edk2_popen__doc__,\r |
3ec97ca4 DM |
2342 | "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\\r |
2343 | Open a pipe to/from a command returning a file object.");\r | |
2344 | \r | |
3ec97ca4 | 2345 | static PyObject *\r |
42fa19ca | 2346 | edk2_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 | 2375 | static PyObject *\r |
173523c2 | 2376 | wait_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 | 2435 | PyDoc_STRVAR(edk2_wait3__doc__,\r |
173523c2 DM |
2436 | "wait3(options) -> (pid, status, rusage)\n\n\\r |
2437 | Wait for completion of a child process.");\r | |
3ec97ca4 DM |
2438 | \r |
2439 | static PyObject *\r | |
42fa19ca | 2440 | edk2_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 | 2460 | PyDoc_STRVAR(edk2_wait4__doc__,\r |
173523c2 DM |
2461 | "wait4(pid, options) -> (pid, status, rusage)\n\n\\r |
2462 | Wait for completion of a given child process.");\r | |
3ec97ca4 DM |
2463 | \r |
2464 | static PyObject *\r | |
42fa19ca | 2465 | edk2_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 | 2485 | PyDoc_STRVAR(edk2_waitpid__doc__,\r |
173523c2 DM |
2486 | "waitpid(pid, options) -> (pid, status)\n\n\\r |
2487 | Wait for completion of a given child process.");\r | |
3ec97ca4 DM |
2488 | \r |
2489 | static PyObject *\r | |
42fa19ca | 2490 | edk2_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 | 2511 | PyDoc_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 | 2515 | static PyObject *\r |
42fa19ca | 2516 | edk2_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 | 2535 | PyDoc_STRVAR(edk2_wait__doc__,\r |
173523c2 DM |
2536 | "wait() -> (pid, status)\n\n\\r |
2537 | Wait for completion of a child process.");\r | |
3ec97ca4 | 2538 | \r |
173523c2 | 2539 | static PyObject *\r |
42fa19ca | 2540 | edk2_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 | 2557 | PyDoc_STRVAR(edk2_lstat__doc__,\r |
173523c2 DM |
2558 | "lstat(path) -> stat result\n\n\\r |
2559 | Like stat(path), but do not follow symbolic links.");\r | |
3ec97ca4 | 2560 | \r |
173523c2 | 2561 | static PyObject *\r |
42fa19ca | 2562 | edk2_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 | 2573 | PyDoc_STRVAR(edk2_readlink__doc__,\r |
173523c2 DM |
2574 | "readlink(path) -> path\n\n\\r |
2575 | Return a string representing the path to which the symbolic link points.");\r | |
3ec97ca4 | 2576 | \r |
173523c2 | 2577 | static PyObject *\r |
42fa19ca | 2578 | edk2_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 | 2636 | PyDoc_STRVAR(edk2_symlink__doc__,\r |
173523c2 DM |
2637 | "symlink(src, dst)\n\n\\r |
2638 | Create a symbolic link pointing to src named dst.");\r | |
3ec97ca4 DM |
2639 | \r |
2640 | static PyObject *\r | |
42fa19ca | 2641 | edk2_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 | |
2650 | static long ticks_per_second = -1;\r | |
3ec97ca4 | 2651 | static PyObject *\r |
42fa19ca | 2652 | edk2_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 | 2671 | PyDoc_STRVAR(edk2_times__doc__,\r |
173523c2 DM |
2672 | "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\\r |
2673 | Return 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 | 2678 | PyDoc_STRVAR(edk2_getsid__doc__,\r |
173523c2 DM |
2679 | "getsid(pid) -> sid\n\n\\r |
2680 | Call the system call getsid().");\r | |
3ec97ca4 DM |
2681 | \r |
2682 | static PyObject *\r | |
42fa19ca | 2683 | edk2_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 | 2698 | PyDoc_STRVAR(edk2_setsid__doc__,\r |
173523c2 DM |
2699 | "setsid()\n\n\\r |
2700 | Call the system call setsid().");\r | |
3ec97ca4 | 2701 | \r |
173523c2 | 2702 | static PyObject *\r |
42fa19ca | 2703 | edk2_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 | 2713 | PyDoc_STRVAR(edk2_setpgid__doc__,\r |
173523c2 DM |
2714 | "setpgid(pid, pgrp)\n\n\\r |
2715 | Call the system call setpgid().");\r | |
3ec97ca4 DM |
2716 | \r |
2717 | static PyObject *\r | |
42fa19ca | 2718 | edk2_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 | 2733 | PyDoc_STRVAR(edk2_tcgetpgrp__doc__,\r |
173523c2 DM |
2734 | "tcgetpgrp(fd) -> pgid\n\n\\r |
2735 | Return the process group associated with the terminal given by a fd.");\r | |
3ec97ca4 DM |
2736 | \r |
2737 | static PyObject *\r | |
42fa19ca | 2738 | edk2_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 | 2753 | PyDoc_STRVAR(edk2_tcsetpgrp__doc__,\r |
173523c2 DM |
2754 | "tcsetpgrp(fd, pgid)\n\n\\r |
2755 | Set the process group associated with the terminal given by a fd.");\r | |
3ec97ca4 | 2756 | \r |
173523c2 | 2757 | static PyObject *\r |
42fa19ca | 2758 | edk2_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 | 2773 | PyDoc_STRVAR(edk2_open__doc__,\r |
173523c2 DM |
2774 | "open(filename, flag [, mode=0777]) -> fd\n\n\\r |
2775 | Open a file (for low level IO).");\r | |
3ec97ca4 | 2776 | \r |
3ec97ca4 | 2777 | static PyObject *\r |
42fa19ca | 2778 | edk2_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 | 2800 | PyDoc_STRVAR(edk2_close__doc__,\r |
173523c2 DM |
2801 | "close(fd)\n\n\\r |
2802 | Close a file descriptor (for low level IO).");\r | |
3ec97ca4 DM |
2803 | \r |
2804 | static PyObject *\r | |
42fa19ca | 2805 | edk2_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 | 2822 | PyDoc_STRVAR(edk2_closerange__doc__,\r |
173523c2 DM |
2823 | "closerange(fd_low, fd_high)\n\n\\r |
2824 | Closes all file descriptors in [fd_low, fd_high), ignoring errors.");\r | |
3ec97ca4 DM |
2825 | \r |
2826 | static PyObject *\r | |
42fa19ca | 2827 | edk2_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 | 2841 | PyDoc_STRVAR(edk2_dup__doc__,\r |
173523c2 DM |
2842 | "dup(fd) -> fd2\n\n\\r |
2843 | Return a duplicate of a file descriptor.");\r | |
3ec97ca4 DM |
2844 | \r |
2845 | static PyObject *\r | |
42fa19ca | 2846 | edk2_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 | 2862 | PyDoc_STRVAR(edk2_dup2__doc__,\r |
173523c2 DM |
2863 | "dup2(old_fd, new_fd)\n\n\\r |
2864 | Duplicate file descriptor.");\r | |
3ec97ca4 DM |
2865 | \r |
2866 | static PyObject *\r | |
42fa19ca | 2867 | edk2_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 | 2884 | PyDoc_STRVAR(edk2_lseek__doc__,\r |
173523c2 DM |
2885 | "lseek(fd, pos, how) -> newpos\n\n\\r |
2886 | Set the current position of a file descriptor.");\r | |
3ec97ca4 DM |
2887 | \r |
2888 | static PyObject *\r | |
42fa19ca | 2889 | edk2_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 | 2930 | PyDoc_STRVAR(edk2_read__doc__,\r |
173523c2 DM |
2931 | "read(fd, buffersize) -> string\n\n\\r |
2932 | Read a file descriptor.");\r | |
3ec97ca4 DM |
2933 | \r |
2934 | static PyObject *\r | |
42fa19ca | 2935 | edk2_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 | 2965 | PyDoc_STRVAR(edk2_write__doc__,\r |
173523c2 DM |
2966 | "write(fd, string) -> byteswritten\n\n\\r |
2967 | Write a string to a file descriptor.");\r | |
3ec97ca4 DM |
2968 | \r |
2969 | static PyObject *\r | |
42fa19ca | 2970 | edk2_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 | 2992 | PyDoc_STRVAR(edk2_fstat__doc__,\r |
173523c2 DM |
2993 | "fstat(fd) -> stat result\n\n\\r |
2994 | Like stat(), but for an open file descriptor.");\r | |
3ec97ca4 DM |
2995 | \r |
2996 | static PyObject *\r | |
42fa19ca | 2997 | edk2_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 | 3017 | PyDoc_STRVAR(edk2_fdopen__doc__,\r |
173523c2 DM |
3018 | "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\\r |
3019 | Return an open file object connected to a file descriptor.");\r | |
3ec97ca4 DM |
3020 | \r |
3021 | static PyObject *\r | |
42fa19ca | 3022 | edk2_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 | 3074 | PyDoc_STRVAR(edk2_isatty__doc__,\r |
173523c2 DM |
3075 | "isatty(fd) -> bool\n\n\\r |
3076 | Return True if the file descriptor 'fd' is an open file descriptor\n\\r | |
3077 | connected to the slave end of a terminal.");\r | |
3ec97ca4 DM |
3078 | \r |
3079 | static PyObject *\r | |
42fa19ca | 3080 | edk2_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 | 3091 | PyDoc_STRVAR(edk2_pipe__doc__,\r |
173523c2 DM |
3092 | "pipe() -> (read_end, write_end)\n\n\\r |
3093 | Create a pipe.");\r | |
3ec97ca4 | 3094 | \r |
173523c2 | 3095 | static PyObject *\r |
42fa19ca | 3096 | edk2_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 | 3111 | PyDoc_STRVAR(edk2_mkfifo__doc__,\r |
173523c2 DM |
3112 | "mkfifo(filename [, mode=0666])\n\n\\r |
3113 | Create a FIFO (a POSIX named pipe).");\r | |
3ec97ca4 DM |
3114 | \r |
3115 | static PyObject *\r | |
42fa19ca | 3116 | edk2_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 | 3135 | PyDoc_STRVAR(edk2_mknod__doc__,\r |
173523c2 DM |
3136 | "mknod(filename [, mode=0600, device])\n\n\\r |
3137 | Create a filesystem node (file, device special file or named pipe)\n\\r | |
3138 | named filename. mode specifies both the permissions to use and the\n\\r | |
3139 | type of node to be created, being combined (bitwise OR) with one of\n\\r | |
3140 | S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\\r | |
3141 | device defines the newly created device special file (probably using\n\\r | |
3142 | os.makedev()), otherwise it is ignored.");\r | |
3143 | \r | |
3ec97ca4 DM |
3144 | \r |
3145 | static PyObject *\r | |
42fa19ca | 3146 | edk2_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 | 3165 | PyDoc_STRVAR(edk2_major__doc__,\r |
173523c2 DM |
3166 | "major(device) -> major number\n\\r |
3167 | Extracts a device major number from a raw device number.");\r | |
3ec97ca4 DM |
3168 | \r |
3169 | static PyObject *\r | |
42fa19ca | 3170 | edk2_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 | 3178 | PyDoc_STRVAR(edk2_minor__doc__,\r |
173523c2 DM |
3179 | "minor(device) -> minor number\n\\r |
3180 | Extracts a device minor number from a raw device number.");\r | |
3ec97ca4 DM |
3181 | \r |
3182 | static PyObject *\r | |
42fa19ca | 3183 | edk2_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 | 3191 | PyDoc_STRVAR(edk2_makedev__doc__,\r |
173523c2 DM |
3192 | "makedev(major, minor) -> device number\n\\r |
3193 | Composes a raw device number from the major and minor device numbers.");\r | |
3194 | \r | |
3ec97ca4 | 3195 | static PyObject *\r |
42fa19ca | 3196 | edk2_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 | 3207 | PyDoc_STRVAR(edk2_ftruncate__doc__,\r |
173523c2 DM |
3208 | "ftruncate(fd, length)\n\n\\r |
3209 | Truncate a file to a specified length.");\r | |
3ec97ca4 DM |
3210 | \r |
3211 | static PyObject *\r | |
42fa19ca | 3212 | edk2_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 | 3242 | PyDoc_STRVAR(edk2_putenv__doc__,\r |
173523c2 DM |
3243 | "putenv(key, value)\n\n\\r |
3244 | Change 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 | 3248 | static PyObject *edk2_putenv_garbage;\r |
3ec97ca4 DM |
3249 | \r |
3250 | static PyObject *\r | |
42fa19ca | 3251 | edk2_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 | 3294 | PyDoc_STRVAR(edk2_unsetenv__doc__,\r |
173523c2 DM |
3295 | "unsetenv(key)\n\n\\r |
3296 | Delete an environment variable.");\r | |
3ec97ca4 DM |
3297 | \r |
3298 | static PyObject *\r | |
42fa19ca | 3299 | edk2_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 | 3324 | PyDoc_STRVAR(edk2_strerror__doc__,\r |
173523c2 DM |
3325 | "strerror(code) -> string\n\n\\r |
3326 | Translate an error code to a message string.");\r | |
3ec97ca4 DM |
3327 | \r |
3328 | static PyObject *\r | |
42fa19ca | 3329 | edk2_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 | 3348 | PyDoc_STRVAR(edk2_WCOREDUMP__doc__,\r |
173523c2 DM |
3349 | "WCOREDUMP(status) -> bool\n\n\\r |
3350 | Return True if the process returning 'status' was dumped to a core file.");\r | |
3ec97ca4 DM |
3351 | \r |
3352 | static PyObject *\r | |
42fa19ca | 3353 | edk2_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 | 3366 | PyDoc_STRVAR(edk2_WIFCONTINUED__doc__,\r |
173523c2 DM |
3367 | "WIFCONTINUED(status) -> bool\n\n\\r |
3368 | Return True if the process returning 'status' was continued from a\n\\r | |
3369 | job control stop.");\r | |
3ec97ca4 DM |
3370 | \r |
3371 | static PyObject *\r | |
42fa19ca | 3372 | edk2_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 | 3385 | PyDoc_STRVAR(edk2_WIFSTOPPED__doc__,\r |
173523c2 DM |
3386 | "WIFSTOPPED(status) -> bool\n\n\\r |
3387 | Return True if the process returning 'status' was stopped.");\r | |
3ec97ca4 DM |
3388 | \r |
3389 | static PyObject *\r | |
42fa19ca | 3390 | edk2_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 | 3403 | PyDoc_STRVAR(edk2_WIFSIGNALED__doc__,\r |
173523c2 DM |
3404 | "WIFSIGNALED(status) -> bool\n\n\\r |
3405 | Return True if the process returning 'status' was terminated by a signal.");\r | |
3ec97ca4 DM |
3406 | \r |
3407 | static PyObject *\r | |
42fa19ca | 3408 | edk2_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 | 3421 | PyDoc_STRVAR(edk2_WIFEXITED__doc__,\r |
173523c2 DM |
3422 | "WIFEXITED(status) -> bool\n\n\\r |
3423 | Return true if the process returning 'status' exited using the exit()\n\\r | |
3424 | system call.");\r | |
3ec97ca4 DM |
3425 | \r |
3426 | static PyObject *\r | |
42fa19ca | 3427 | edk2_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 | 3440 | PyDoc_STRVAR(edk2_WEXITSTATUS__doc__,\r |
173523c2 DM |
3441 | "WEXITSTATUS(status) -> integer\n\n\\r |
3442 | Return the process return code from 'status'.");\r | |
3ec97ca4 DM |
3443 | \r |
3444 | static PyObject *\r | |
42fa19ca | 3445 | edk2_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 | 3458 | PyDoc_STRVAR(edk2_WTERMSIG__doc__,\r |
173523c2 DM |
3459 | "WTERMSIG(status) -> integer\n\n\\r |
3460 | Return the signal that terminated the process that provided the 'status'\n\\r | |
3461 | value.");\r | |
3462 | \r | |
3463 | static PyObject *\r | |
42fa19ca | 3464 | edk2_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 | 3477 | PyDoc_STRVAR(edk2_WSTOPSIG__doc__,\r |
173523c2 DM |
3478 | "WSTOPSIG(status) -> integer\n\n\\r |
3479 | Return the signal that stopped the process that provided\n\\r | |
3480 | the 'status' value.");\r | |
3ec97ca4 DM |
3481 | \r |
3482 | static PyObject *\r | |
42fa19ca | 3483 | edk2_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 | |
3501 | static 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 | 3540 | PyDoc_STRVAR(edk2_fstatvfs__doc__,\r |
173523c2 DM |
3541 | "fstatvfs(fd) -> statvfs result\n\n\\r |
3542 | Perform an fstatvfs system call on the given fd.");\r | |
3543 | \r | |
3544 | static PyObject *\r | |
42fa19ca | 3545 | edk2_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 | 3566 | PyDoc_STRVAR(edk2_statvfs__doc__,\r |
173523c2 DM |
3567 | "statvfs(path) -> statvfs result\n\n\\r |
3568 | Perform a statvfs system call on the given path.");\r | |
3569 | \r | |
3570 | static PyObject *\r | |
42fa19ca | 3571 | edk2_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 | 3590 | PyDoc_STRVAR(edk2_tempnam__doc__,\r |
173523c2 DM |
3591 | "tempnam([dir[, prefix]]) -> string\n\n\\r |
3592 | Return a unique name for a temporary file.\n\\r | |
3593 | The directory and a prefix may be specified as strings; they may be omitted\n\\r | |
3594 | or None if not needed.");\r | |
3ec97ca4 DM |
3595 | \r |
3596 | static PyObject *\r | |
42fa19ca | 3597 | edk2_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 | 3626 | PyDoc_STRVAR(edk2_tmpfile__doc__,\r |
173523c2 DM |
3627 | "tmpfile() -> file object\n\n\\r |
3628 | Create a temporary file with no directory entries.");\r | |
3629 | \r | |
3630 | static PyObject *\r | |
42fa19ca | 3631 | edk2_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 | 3648 | PyDoc_STRVAR(edk2_tmpnam__doc__,\r |
173523c2 DM |
3649 | "tmpnam() -> string\n\n\\r |
3650 | Return a unique name for a temporary file.");\r | |
3651 | \r | |
3652 | static PyObject *\r | |
42fa19ca | 3653 | edk2_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 | 3687 | PyDoc_STRVAR(edk2_abort__doc__,\r |
173523c2 DM |
3688 | "abort() -> does not return!\n\n\\r |
3689 | Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\\r | |
3690 | in the hardest way possible on the hosting operating system.");\r | |
3ec97ca4 | 3691 | \r |
173523c2 | 3692 | static PyObject *\r |
42fa19ca | 3693 | edk2_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 |
3701 | static 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 | |
3962 | static int\r | |
3963 | ins(PyObject *module, char *symbol, long value)\r | |
3964 | {\r | |
3965 | return PyModule_AddIntConstant(module, symbol, value);\r | |
3966 | }\r | |
3967 | \r | |
3968 | static int\r | |
3969 | all_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 | |
4165 | PyMODINIT_FUNC\r | |
4166 | INITFUNC(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 |