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