1 |
|
2 | /* OVM_MAIN: POSIX module implementation stripped down for Oil */
|
3 |
|
4 | #define PY_SSIZE_T_CLEAN
|
5 |
|
6 | #include "Python.h"
|
7 | #include "structseq.h"
|
8 |
|
9 | #ifdef __cplusplus
|
10 | extern "C" {
|
11 | #endif
|
12 |
|
13 | /* OVM_MAIN: For getting unused variable warnings while still keeping
|
14 | * "comments" */
|
15 |
|
16 | #define PyDoc_STRVAR_remove(name,str)
|
17 |
|
18 | PyDoc_STRVAR(posix__doc__,
|
19 | "This module provides access to operating system functionality that is\n\
|
20 | standardized by the C Standard and the POSIX standard (a thinly\n\
|
21 | disguised Unix interface). Refer to the library manual and\n\
|
22 | corresponding Unix manual entries for more information on calls.");
|
23 |
|
24 | /* OVM_MAIN: Turning off Unicode in build/setup_posix.py didn't work.
|
25 | *
|
26 | * If we don't turn it off we get build errors.
|
27 | * */
|
28 | #undef Py_USING_UNICODE
|
29 |
|
30 | #ifndef Py_USING_UNICODE
|
31 | /* This is used in signatures of functions. */
|
32 | #define Py_UNICODE void
|
33 | #endif
|
34 |
|
35 | #ifdef HAVE_SYS_TYPES_H
|
36 | #include <sys/types.h>
|
37 | #endif /* HAVE_SYS_TYPES_H */
|
38 |
|
39 | #ifdef HAVE_SYS_STAT_H
|
40 | #include <sys/stat.h>
|
41 | #endif /* HAVE_SYS_STAT_H */
|
42 |
|
43 | #ifdef HAVE_SYS_WAIT_H
|
44 | #include <sys/wait.h> /* For WNOHANG */
|
45 | #endif
|
46 |
|
47 | #ifdef HAVE_SIGNAL_H
|
48 | #include <signal.h>
|
49 | #endif
|
50 |
|
51 | #ifdef HAVE_FCNTL_H
|
52 | #include <fcntl.h>
|
53 | #endif /* HAVE_FCNTL_H */
|
54 |
|
55 | /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
|
56 | #if defined(HAVE_SYS_RESOURCE_H)
|
57 | #include <sys/resource.h>
|
58 | #endif
|
59 |
|
60 | /* Unix functions that the configure script doesn't check for */
|
61 | #define HAVE_EXECV 1
|
62 | #define HAVE_FORK 1
|
63 | #define HAVE_GETCWD 1
|
64 | #define HAVE_GETEGID 1
|
65 | #define HAVE_GETEUID 1
|
66 | #define HAVE_GETGID 1
|
67 | #define HAVE_GETPPID 1
|
68 | #define HAVE_GETUID 1
|
69 | #define HAVE_KILL 1
|
70 | #define HAVE_PIPE 1
|
71 | #define HAVE_WAIT 1
|
72 |
|
73 | #ifndef HAVE_UNISTD_H
|
74 | extern int mkdir(const char *, mode_t);
|
75 | extern int chdir(const char *);
|
76 | extern int rmdir(const char *);
|
77 | extern int chmod(const char *, mode_t);
|
78 | extern int chown(const char *, uid_t, gid_t);
|
79 | extern char *getcwd(char *, int);
|
80 | extern char *strerror(int);
|
81 | extern int link(const char *, const char *);
|
82 | extern int rename(const char *, const char *);
|
83 | extern int stat(const char *, struct stat *);
|
84 | extern int unlink(const char *);
|
85 | extern int pclose(FILE *);
|
86 | #ifdef HAVE_SYMLINK
|
87 | extern int symlink(const char *, const char *);
|
88 | #endif /* HAVE_SYMLINK */
|
89 | #ifdef HAVE_LSTAT
|
90 | extern int lstat(const char *, struct stat *);
|
91 | #endif /* HAVE_LSTAT */
|
92 | #endif /* !HAVE_UNISTD_H */
|
93 |
|
94 | #ifdef HAVE_UTIME_H
|
95 | #include <utime.h>
|
96 | #endif /* HAVE_UTIME_H */
|
97 |
|
98 | #ifdef HAVE_SYS_UTIME_H
|
99 | #include <sys/utime.h>
|
100 | #define HAVE_UTIME_H /* pretend we do for the rest of this file */
|
101 | #endif /* HAVE_SYS_UTIME_H */
|
102 |
|
103 | #ifdef HAVE_SYS_TIMES_H
|
104 | #include <sys/times.h>
|
105 | #endif /* HAVE_SYS_TIMES_H */
|
106 |
|
107 | #ifdef HAVE_SYS_PARAM_H
|
108 | #include <sys/param.h>
|
109 | #endif /* HAVE_SYS_PARAM_H */
|
110 |
|
111 | #ifdef HAVE_SYS_UTSNAME_H
|
112 | #include <sys/utsname.h>
|
113 | #endif /* HAVE_SYS_UTSNAME_H */
|
114 |
|
115 | #ifdef HAVE_DIRENT_H
|
116 | #include <dirent.h>
|
117 | #define NAMLEN(dirent) strlen((dirent)->d_name)
|
118 | #else
|
119 | #if defined(__WATCOMC__) && !defined(__QNX__)
|
120 | #include <direct.h>
|
121 | #define NAMLEN(dirent) strlen((dirent)->d_name)
|
122 | #else
|
123 | #define dirent direct
|
124 | #define NAMLEN(dirent) (dirent)->d_namlen
|
125 | #endif
|
126 | #ifdef HAVE_SYS_NDIR_H
|
127 | #include <sys/ndir.h>
|
128 | #endif
|
129 | #ifdef HAVE_SYS_DIR_H
|
130 | #include <sys/dir.h>
|
131 | #endif
|
132 | #ifdef HAVE_NDIR_H
|
133 | #include <ndir.h>
|
134 | #endif
|
135 | #endif
|
136 |
|
137 | #ifndef MAXPATHLEN
|
138 | #if defined(PATH_MAX) && PATH_MAX > 1024
|
139 | #define MAXPATHLEN PATH_MAX
|
140 | #else
|
141 | #define MAXPATHLEN 1024
|
142 | #endif
|
143 | #endif /* MAXPATHLEN */
|
144 |
|
145 | #define WAIT_TYPE int
|
146 | #define WAIT_STATUS_INT(s) (s)
|
147 |
|
148 | /* Issue #1983: pid_t can be longer than a C long on some systems */
|
149 | #if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
|
150 | #define PARSE_PID "i"
|
151 | #define PyLong_FromPid PyInt_FromLong
|
152 | #define PyLong_AsPid PyInt_AsLong
|
153 | #elif SIZEOF_PID_T == SIZEOF_LONG
|
154 | #define PARSE_PID "l"
|
155 | #define PyLong_FromPid PyInt_FromLong
|
156 | #define PyLong_AsPid PyInt_AsLong
|
157 | #elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
|
158 | #define PARSE_PID "L"
|
159 | #define PyLong_FromPid PyLong_FromLongLong
|
160 | #define PyLong_AsPid PyInt_AsLongLong
|
161 | #else
|
162 | #error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
|
163 | #endif /* SIZEOF_PID_T */
|
164 |
|
165 | /* Don't use the "_r" form if we don't need it (also, won't have a
|
166 | prototype for it, at least on Solaris -- maybe others as well?). */
|
167 | #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
|
168 | #define USE_CTERMID_R
|
169 | #endif
|
170 |
|
171 | #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
|
172 | #define USE_TMPNAM_R
|
173 | #endif
|
174 |
|
175 | #if defined(MAJOR_IN_MKDEV)
|
176 | #include <sys/mkdev.h>
|
177 | #else
|
178 | #if defined(MAJOR_IN_SYSMACROS)
|
179 | #include <sys/sysmacros.h>
|
180 | #endif
|
181 | #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
|
182 | #include <sys/mkdev.h>
|
183 | #endif
|
184 | #endif
|
185 |
|
186 |
|
187 | PyObject *
|
188 | _PyInt_FromUid(uid_t uid)
|
189 | {
|
190 | if (uid <= LONG_MAX)
|
191 | return PyInt_FromLong(uid);
|
192 | return PyLong_FromUnsignedLong(uid);
|
193 | }
|
194 |
|
195 | PyObject *
|
196 | _PyInt_FromGid(gid_t gid)
|
197 | {
|
198 | if (gid <= LONG_MAX)
|
199 | return PyInt_FromLong(gid);
|
200 | return PyLong_FromUnsignedLong(gid);
|
201 | }
|
202 |
|
203 | int
|
204 | _Py_Uid_Converter(PyObject *obj, void *p)
|
205 | {
|
206 | int overflow;
|
207 | long result;
|
208 | if (PyFloat_Check(obj)) {
|
209 | PyErr_SetString(PyExc_TypeError,
|
210 | "integer argument expected, got float");
|
211 | return 0;
|
212 | }
|
213 | result = PyLong_AsLongAndOverflow(obj, &overflow);
|
214 | if (overflow < 0)
|
215 | goto OverflowDown;
|
216 | if (!overflow && result == -1) {
|
217 | /* error or -1 */
|
218 | if (PyErr_Occurred())
|
219 | return 0;
|
220 | *(uid_t *)p = (uid_t)-1;
|
221 | }
|
222 | else {
|
223 | /* unsigned uid_t */
|
224 | unsigned long uresult;
|
225 | if (overflow > 0) {
|
226 | uresult = PyLong_AsUnsignedLong(obj);
|
227 | if (PyErr_Occurred()) {
|
228 | if (PyErr_ExceptionMatches(PyExc_OverflowError))
|
229 | goto OverflowUp;
|
230 | return 0;
|
231 | }
|
232 | } else {
|
233 | if (result < 0)
|
234 | goto OverflowDown;
|
235 | uresult = result;
|
236 | }
|
237 | if (sizeof(uid_t) < sizeof(long) &&
|
238 | (unsigned long)(uid_t)uresult != uresult)
|
239 | goto OverflowUp;
|
240 | *(uid_t *)p = (uid_t)uresult;
|
241 | }
|
242 | return 1;
|
243 |
|
244 | OverflowDown:
|
245 | PyErr_SetString(PyExc_OverflowError,
|
246 | "user id is less than minimum");
|
247 | return 0;
|
248 |
|
249 | OverflowUp:
|
250 | PyErr_SetString(PyExc_OverflowError,
|
251 | "user id is greater than maximum");
|
252 | return 0;
|
253 | }
|
254 |
|
255 | int
|
256 | _Py_Gid_Converter(PyObject *obj, void *p)
|
257 | {
|
258 | int overflow;
|
259 | long result;
|
260 | if (PyFloat_Check(obj)) {
|
261 | PyErr_SetString(PyExc_TypeError,
|
262 | "integer argument expected, got float");
|
263 | return 0;
|
264 | }
|
265 | result = PyLong_AsLongAndOverflow(obj, &overflow);
|
266 | if (overflow < 0)
|
267 | goto OverflowDown;
|
268 | if (!overflow && result == -1) {
|
269 | /* error or -1 */
|
270 | if (PyErr_Occurred())
|
271 | return 0;
|
272 | *(gid_t *)p = (gid_t)-1;
|
273 | }
|
274 | else {
|
275 | /* unsigned gid_t */
|
276 | unsigned long uresult;
|
277 | if (overflow > 0) {
|
278 | uresult = PyLong_AsUnsignedLong(obj);
|
279 | if (PyErr_Occurred()) {
|
280 | if (PyErr_ExceptionMatches(PyExc_OverflowError))
|
281 | goto OverflowUp;
|
282 | return 0;
|
283 | }
|
284 | } else {
|
285 | if (result < 0)
|
286 | goto OverflowDown;
|
287 | uresult = result;
|
288 | }
|
289 | if (sizeof(gid_t) < sizeof(long) &&
|
290 | (unsigned long)(gid_t)uresult != uresult)
|
291 | goto OverflowUp;
|
292 | *(gid_t *)p = (gid_t)uresult;
|
293 | }
|
294 | return 1;
|
295 |
|
296 | OverflowDown:
|
297 | PyErr_SetString(PyExc_OverflowError,
|
298 | "group id is less than minimum");
|
299 | return 0;
|
300 |
|
301 | OverflowUp:
|
302 | PyErr_SetString(PyExc_OverflowError,
|
303 | "group id is greater than maximum");
|
304 | return 0;
|
305 | }
|
306 |
|
307 |
|
308 | #ifdef HAVE_LONG_LONG
|
309 | static PyObject *
|
310 | _PyInt_FromDev(PY_LONG_LONG v)
|
311 | {
|
312 | if (LONG_MIN <= v && v <= LONG_MAX)
|
313 | return PyInt_FromLong((long)v);
|
314 | else
|
315 | return PyLong_FromLongLong(v);
|
316 | }
|
317 | #else
|
318 | # define _PyInt_FromDev PyInt_FromLong
|
319 | #endif
|
320 |
|
321 | #if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
|
322 | /* On Darwin/MacOSX a shared library or framework has no access to
|
323 | ** environ directly, we must obtain it with _NSGetEnviron(). See also
|
324 | ** man environ(7).
|
325 | */
|
326 | #include <crt_externs.h>
|
327 | static char **environ;
|
328 | #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
|
329 | extern char **environ;
|
330 | #endif /* !_MSC_VER */
|
331 |
|
332 | static PyObject *
|
333 | convertenviron(void)
|
334 | {
|
335 | PyObject *d;
|
336 | char **e;
|
337 | d = PyDict_New();
|
338 | if (d == NULL)
|
339 | return NULL;
|
340 | #if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
|
341 | if (environ == NULL)
|
342 | environ = *_NSGetEnviron();
|
343 | #endif
|
344 | if (environ == NULL)
|
345 | return d;
|
346 | /* This part ignores errors */
|
347 | for (e = environ; *e != NULL; e++) {
|
348 | PyObject *k;
|
349 | PyObject *v;
|
350 | char *p = strchr(*e, '=');
|
351 | if (p == NULL)
|
352 | continue;
|
353 | k = PyString_FromStringAndSize(*e, (int)(p-*e));
|
354 | if (k == NULL) {
|
355 | PyErr_Clear();
|
356 | continue;
|
357 | }
|
358 | v = PyString_FromString(p+1);
|
359 | if (v == NULL) {
|
360 | PyErr_Clear();
|
361 | Py_DECREF(k);
|
362 | continue;
|
363 | }
|
364 | if (PyDict_GetItem(d, k) == NULL) {
|
365 | if (PyDict_SetItem(d, k, v) != 0)
|
366 | PyErr_Clear();
|
367 | }
|
368 | Py_DECREF(k);
|
369 | Py_DECREF(v);
|
370 | }
|
371 | return d;
|
372 | }
|
373 |
|
374 |
|
375 | /* Set a POSIX-specific error from errno, and return NULL */
|
376 |
|
377 | static PyObject *
|
378 | posix_error(void)
|
379 | {
|
380 | return PyErr_SetFromErrno(PyExc_OSError);
|
381 | }
|
382 | static PyObject *
|
383 | posix_error_with_filename(char* name)
|
384 | {
|
385 | return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
|
386 | }
|
387 |
|
388 | static PyObject *
|
389 | posix_error_with_allocated_filename(char* name)
|
390 | {
|
391 | PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
|
392 | PyMem_Free(name);
|
393 | return rc;
|
394 | }
|
395 |
|
396 | /* POSIX generic methods */
|
397 |
|
398 | static PyObject *
|
399 | posix_1str(PyObject *args, char *format, int (*func)(const char*))
|
400 | {
|
401 | char *path1 = NULL;
|
402 | int res;
|
403 | if (!PyArg_ParseTuple(args, format,
|
404 | Py_FileSystemDefaultEncoding, &path1))
|
405 | return NULL;
|
406 | Py_BEGIN_ALLOW_THREADS
|
407 | res = (*func)(path1);
|
408 | Py_END_ALLOW_THREADS
|
409 | if (res < 0)
|
410 | return posix_error_with_allocated_filename(path1);
|
411 | PyMem_Free(path1);
|
412 | Py_INCREF(Py_None);
|
413 | return Py_None;
|
414 | }
|
415 |
|
416 | static PyObject *
|
417 | posix_2str(PyObject *args,
|
418 | char *format,
|
419 | int (*func)(const char *, const char *))
|
420 | {
|
421 | char *path1 = NULL, *path2 = NULL;
|
422 | int res;
|
423 | if (!PyArg_ParseTuple(args, format,
|
424 | Py_FileSystemDefaultEncoding, &path1,
|
425 | Py_FileSystemDefaultEncoding, &path2))
|
426 | return NULL;
|
427 | Py_BEGIN_ALLOW_THREADS
|
428 | res = (*func)(path1, path2);
|
429 | Py_END_ALLOW_THREADS
|
430 | PyMem_Free(path1);
|
431 | PyMem_Free(path2);
|
432 | if (res != 0)
|
433 | /* XXX how to report both path1 and path2??? */
|
434 | return posix_error();
|
435 | Py_INCREF(Py_None);
|
436 | return Py_None;
|
437 | }
|
438 |
|
439 | /* choose the appropriate stat and fstat functions and return structs */
|
440 | # define STAT stat
|
441 | # define FSTAT fstat
|
442 | # define STRUCT_STAT struct stat
|
443 |
|
444 | PyDoc_STRVAR(stat_result__doc__,
|
445 | "stat_result: Result from stat or lstat.\n\n\
|
446 | This object may be accessed either as a tuple of\n\
|
447 | (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
|
448 | or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
|
449 | \n\
|
450 | Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
|
451 | or st_flags, they are available as attributes only.\n\
|
452 | \n\
|
453 | See os.stat for more information.");
|
454 |
|
455 | static PyStructSequence_Field stat_result_fields[] = {
|
456 | {"st_mode", "protection bits"},
|
457 | {"st_ino", "inode"},
|
458 | {"st_dev", "device"},
|
459 | {"st_nlink", "number of hard links"},
|
460 | {"st_uid", "user ID of owner"},
|
461 | {"st_gid", "group ID of owner"},
|
462 | {"st_size", "total size, in bytes"},
|
463 | /* The NULL is replaced with PyStructSequence_UnnamedField later. */
|
464 | {NULL, "integer time of last access"},
|
465 | {NULL, "integer time of last modification"},
|
466 | {NULL, "integer time of last change"},
|
467 | {"st_atime", "time of last access"},
|
468 | {"st_mtime", "time of last modification"},
|
469 | {"st_ctime", "time of last change"},
|
470 | #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
471 | {"st_blksize", "blocksize for filesystem I/O"},
|
472 | #endif
|
473 | #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
|
474 | {"st_blocks", "number of blocks allocated"},
|
475 | #endif
|
476 | #ifdef HAVE_STRUCT_STAT_ST_RDEV
|
477 | {"st_rdev", "device type (if inode device)"},
|
478 | #endif
|
479 | #ifdef HAVE_STRUCT_STAT_ST_FLAGS
|
480 | {"st_flags", "user defined flags for file"},
|
481 | #endif
|
482 | #ifdef HAVE_STRUCT_STAT_ST_GEN
|
483 | {"st_gen", "generation number"},
|
484 | #endif
|
485 | #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
|
486 | {"st_birthtime", "time of creation"},
|
487 | #endif
|
488 | {0}
|
489 | };
|
490 |
|
491 | #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
492 | #define ST_BLKSIZE_IDX 13
|
493 | #else
|
494 | #define ST_BLKSIZE_IDX 12
|
495 | #endif
|
496 |
|
497 | #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
|
498 | #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
|
499 | #else
|
500 | #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
|
501 | #endif
|
502 |
|
503 | #ifdef HAVE_STRUCT_STAT_ST_RDEV
|
504 | #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
|
505 | #else
|
506 | #define ST_RDEV_IDX ST_BLOCKS_IDX
|
507 | #endif
|
508 |
|
509 | #ifdef HAVE_STRUCT_STAT_ST_FLAGS
|
510 | #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
|
511 | #else
|
512 | #define ST_FLAGS_IDX ST_RDEV_IDX
|
513 | #endif
|
514 |
|
515 | #ifdef HAVE_STRUCT_STAT_ST_GEN
|
516 | #define ST_GEN_IDX (ST_FLAGS_IDX+1)
|
517 | #else
|
518 | #define ST_GEN_IDX ST_FLAGS_IDX
|
519 | #endif
|
520 |
|
521 | #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
|
522 | #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
|
523 | #else
|
524 | #define ST_BIRTHTIME_IDX ST_GEN_IDX
|
525 | #endif
|
526 |
|
527 | static PyStructSequence_Desc stat_result_desc = {
|
528 | "stat_result", /* name */
|
529 | stat_result__doc__, /* doc */
|
530 | stat_result_fields,
|
531 | 10
|
532 | };
|
533 |
|
534 | static int initialized;
|
535 | static PyTypeObject StatResultType;
|
536 | static newfunc structseq_new;
|
537 |
|
538 | static PyObject *
|
539 | statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
540 | {
|
541 | PyStructSequence *result;
|
542 | int i;
|
543 |
|
544 | result = (PyStructSequence*)structseq_new(type, args, kwds);
|
545 | if (!result)
|
546 | return NULL;
|
547 | /* If we have been initialized from a tuple,
|
548 | st_?time might be set to None. Initialize it
|
549 | from the int slots. */
|
550 | for (i = 7; i <= 9; i++) {
|
551 | if (result->ob_item[i+3] == Py_None) {
|
552 | Py_DECREF(Py_None);
|
553 | Py_INCREF(result->ob_item[i]);
|
554 | result->ob_item[i+3] = result->ob_item[i];
|
555 | }
|
556 | }
|
557 | return (PyObject*)result;
|
558 | }
|
559 |
|
560 |
|
561 |
|
562 | /* If true, st_?time is float. */
|
563 | static int _stat_float_times = 1;
|
564 |
|
565 | PyDoc_STRVAR_remove(stat_float_times__doc__,
|
566 | "stat_float_times([newval]) -> oldval\n\n\
|
567 | Determine whether os.[lf]stat represents time stamps as float objects.\n\
|
568 | If newval is True, future calls to stat() return floats, if it is False,\n\
|
569 | future calls return ints. \n\
|
570 | If newval is omitted, return the current setting.\n");
|
571 |
|
572 | static PyObject*
|
573 | stat_float_times(PyObject* self, PyObject *args)
|
574 | {
|
575 | int newval = -1;
|
576 | if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
|
577 | return NULL;
|
578 | if (newval == -1)
|
579 | /* Return old value */
|
580 | return PyBool_FromLong(_stat_float_times);
|
581 | _stat_float_times = newval;
|
582 | Py_INCREF(Py_None);
|
583 | return Py_None;
|
584 | }
|
585 |
|
586 | static void
|
587 | fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
|
588 | {
|
589 | PyObject *fval,*ival;
|
590 | #if SIZEOF_TIME_T > SIZEOF_LONG
|
591 | ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
|
592 | #else
|
593 | ival = PyInt_FromLong((long)sec);
|
594 | #endif
|
595 | if (!ival)
|
596 | return;
|
597 | if (_stat_float_times) {
|
598 | fval = PyFloat_FromDouble(sec + 1e-9*nsec);
|
599 | } else {
|
600 | fval = ival;
|
601 | Py_INCREF(fval);
|
602 | }
|
603 | PyStructSequence_SET_ITEM(v, index, ival);
|
604 | PyStructSequence_SET_ITEM(v, index+3, fval);
|
605 | }
|
606 |
|
607 | /* pack a system stat C structure into the Python stat tuple
|
608 | (used by posix_stat() and posix_fstat()) */
|
609 | static PyObject*
|
610 | _pystat_fromstructstat(STRUCT_STAT *st)
|
611 | {
|
612 | unsigned long ansec, mnsec, cnsec;
|
613 | PyObject *v = PyStructSequence_New(&StatResultType);
|
614 | if (v == NULL)
|
615 | return NULL;
|
616 |
|
617 | PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
|
618 | #ifdef HAVE_LARGEFILE_SUPPORT
|
619 | PyStructSequence_SET_ITEM(v, 1,
|
620 | PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
|
621 | #else
|
622 | PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
|
623 | #endif
|
624 | #ifdef MS_WINDOWS
|
625 | PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
|
626 | #else
|
627 | PyStructSequence_SET_ITEM(v, 2, _PyInt_FromDev(st->st_dev));
|
628 | #endif
|
629 | PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
|
630 | #if defined(MS_WINDOWS)
|
631 | PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong(0));
|
632 | PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong(0));
|
633 | #else
|
634 | PyStructSequence_SET_ITEM(v, 4, _PyInt_FromUid(st->st_uid));
|
635 | PyStructSequence_SET_ITEM(v, 5, _PyInt_FromGid(st->st_gid));
|
636 | #endif
|
637 | #ifdef HAVE_LARGEFILE_SUPPORT
|
638 | PyStructSequence_SET_ITEM(v, 6,
|
639 | PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
|
640 | #else
|
641 | PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
|
642 | #endif
|
643 |
|
644 | #if defined(HAVE_STAT_TV_NSEC)
|
645 | ansec = st->st_atim.tv_nsec;
|
646 | mnsec = st->st_mtim.tv_nsec;
|
647 | cnsec = st->st_ctim.tv_nsec;
|
648 | #elif defined(HAVE_STAT_TV_NSEC2)
|
649 | ansec = st->st_atimespec.tv_nsec;
|
650 | mnsec = st->st_mtimespec.tv_nsec;
|
651 | cnsec = st->st_ctimespec.tv_nsec;
|
652 | #elif defined(HAVE_STAT_NSEC)
|
653 | ansec = st->st_atime_nsec;
|
654 | mnsec = st->st_mtime_nsec;
|
655 | cnsec = st->st_ctime_nsec;
|
656 | #else
|
657 | ansec = mnsec = cnsec = 0;
|
658 | #endif
|
659 | fill_time(v, 7, st->st_atime, ansec);
|
660 | fill_time(v, 8, st->st_mtime, mnsec);
|
661 | fill_time(v, 9, st->st_ctime, cnsec);
|
662 |
|
663 | #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
664 | PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
|
665 | PyInt_FromLong((long)st->st_blksize));
|
666 | #endif
|
667 | #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
|
668 | PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
|
669 | PyInt_FromLong((long)st->st_blocks));
|
670 | #endif
|
671 | #ifdef HAVE_STRUCT_STAT_ST_RDEV
|
672 | PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
|
673 | PyInt_FromLong((long)st->st_rdev));
|
674 | #endif
|
675 | #ifdef HAVE_STRUCT_STAT_ST_GEN
|
676 | PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
|
677 | PyInt_FromLong((long)st->st_gen));
|
678 | #endif
|
679 | #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
|
680 | {
|
681 | PyObject *val;
|
682 | unsigned long bsec,bnsec;
|
683 | bsec = (long)st->st_birthtime;
|
684 | #ifdef HAVE_STAT_TV_NSEC2
|
685 | bnsec = st->st_birthtimespec.tv_nsec;
|
686 | #else
|
687 | bnsec = 0;
|
688 | #endif
|
689 | if (_stat_float_times) {
|
690 | val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
|
691 | } else {
|
692 | val = PyInt_FromLong((long)bsec);
|
693 | }
|
694 | PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
|
695 | val);
|
696 | }
|
697 | #endif
|
698 | #ifdef HAVE_STRUCT_STAT_ST_FLAGS
|
699 | PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
|
700 | PyInt_FromLong((long)st->st_flags));
|
701 | #endif
|
702 |
|
703 | if (PyErr_Occurred()) {
|
704 | Py_DECREF(v);
|
705 | return NULL;
|
706 | }
|
707 |
|
708 | return v;
|
709 | }
|
710 |
|
711 | static PyObject *
|
712 | posix_do_stat(PyObject *self, PyObject *args,
|
713 | char *format,
|
714 | int (*statfunc)(const char *, STRUCT_STAT *),
|
715 | char *wformat,
|
716 | int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
|
717 | {
|
718 | STRUCT_STAT st;
|
719 | char *path = NULL; /* pass this to stat; do not free() it */
|
720 | char *pathfree = NULL; /* this memory must be free'd */
|
721 | int res;
|
722 | PyObject *result;
|
723 |
|
724 | if (!PyArg_ParseTuple(args, format,
|
725 | Py_FileSystemDefaultEncoding, &path))
|
726 | return NULL;
|
727 | pathfree = path;
|
728 |
|
729 | Py_BEGIN_ALLOW_THREADS
|
730 | res = (*statfunc)(path, &st);
|
731 | Py_END_ALLOW_THREADS
|
732 |
|
733 | if (res != 0) {
|
734 | result = posix_error_with_filename(pathfree);
|
735 | }
|
736 | else
|
737 | result = _pystat_fromstructstat(&st);
|
738 |
|
739 | PyMem_Free(pathfree);
|
740 | return result;
|
741 | }
|
742 |
|
743 | /* POSIX methods */
|
744 |
|
745 | PyDoc_STRVAR_remove(posix_access__doc__,
|
746 | "access(path, mode) -> True if granted, False otherwise\n\n\
|
747 | Use the real uid/gid to test for access to a path. Note that most\n\
|
748 | operations will use the effective uid/gid, therefore this routine can\n\
|
749 | be used in a suid/sgid environment to test if the invoking user has the\n\
|
750 | specified access to the path. The mode argument can be F_OK to test\n\
|
751 | existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
|
752 |
|
753 | static PyObject *
|
754 | posix_access(PyObject *self, PyObject *args)
|
755 | {
|
756 | char *path;
|
757 | int mode;
|
758 |
|
759 | int res;
|
760 | if (!PyArg_ParseTuple(args, "eti:access",
|
761 | Py_FileSystemDefaultEncoding, &path, &mode))
|
762 | return NULL;
|
763 | Py_BEGIN_ALLOW_THREADS
|
764 | res = access(path, mode);
|
765 | Py_END_ALLOW_THREADS
|
766 | PyMem_Free(path);
|
767 | return PyBool_FromLong(res == 0);
|
768 | }
|
769 |
|
770 | PyDoc_STRVAR_remove(posix_chdir__doc__,
|
771 | "chdir(path)\n\n\
|
772 | Change the current working directory to the specified path.");
|
773 |
|
774 | static PyObject *
|
775 | posix_chdir(PyObject *self, PyObject *args)
|
776 | {
|
777 | return posix_1str(args, "et:chdir", chdir);
|
778 | }
|
779 |
|
780 | /* OVM_MAIN: Do we need this Solaris workaround??? */
|
781 |
|
782 | #ifdef HAVE_GETCWD
|
783 | PyDoc_STRVAR_remove(posix_getcwd__doc__,
|
784 | "getcwd() -> path\n\n\
|
785 | Return a string representing the current working directory.");
|
786 |
|
787 | #if (defined(__sun) && defined(__SVR4)) || \
|
788 | defined(__OpenBSD__) || \
|
789 | defined(__NetBSD__)
|
790 | /* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
|
791 | static PyObject *
|
792 | posix_getcwd(PyObject *self, PyObject *noargs)
|
793 | {
|
794 | char buf[PATH_MAX+2];
|
795 | char *res;
|
796 |
|
797 | Py_BEGIN_ALLOW_THREADS
|
798 | res = getcwd(buf, sizeof buf);
|
799 | Py_END_ALLOW_THREADS
|
800 |
|
801 | if (res == NULL)
|
802 | return posix_error();
|
803 |
|
804 | return PyString_FromString(buf);
|
805 | }
|
806 | #else
|
807 | static PyObject *
|
808 | posix_getcwd(PyObject *self, PyObject *noargs)
|
809 | {
|
810 | int bufsize_incr = 1024;
|
811 | int bufsize = 0;
|
812 | char *tmpbuf = NULL;
|
813 | char *res = NULL;
|
814 | PyObject *dynamic_return;
|
815 |
|
816 | Py_BEGIN_ALLOW_THREADS
|
817 | do {
|
818 | bufsize = bufsize + bufsize_incr;
|
819 | tmpbuf = malloc(bufsize);
|
820 | if (tmpbuf == NULL) {
|
821 | break;
|
822 | }
|
823 | res = getcwd(tmpbuf, bufsize);
|
824 |
|
825 | if (res == NULL) {
|
826 | free(tmpbuf);
|
827 | }
|
828 | } while ((res == NULL) && (errno == ERANGE));
|
829 | Py_END_ALLOW_THREADS
|
830 |
|
831 | if (res == NULL)
|
832 | return posix_error();
|
833 |
|
834 | dynamic_return = PyString_FromString(tmpbuf);
|
835 | free(tmpbuf);
|
836 |
|
837 | return dynamic_return;
|
838 | }
|
839 | #endif /* getcwd() NULL/ERANGE workaround. */
|
840 | #endif /* HAVE_GETCWD */
|
841 |
|
842 | PyDoc_STRVAR_remove(posix_listdir__doc__,
|
843 | "listdir(path) -> list_of_strings\n\n\
|
844 | Return a list containing the names of the entries in the directory.\n\
|
845 | \n\
|
846 | path: path of directory to list\n\
|
847 | \n\
|
848 | The list is in arbitrary order. It does not include the special\n\
|
849 | entries '.' and '..' even if they are present in the directory.");
|
850 |
|
851 | static PyObject *
|
852 | posix_listdir(PyObject *self, PyObject *args)
|
853 | {
|
854 | char *name = NULL;
|
855 | PyObject *d, *v;
|
856 | DIR *dirp;
|
857 | struct dirent *ep;
|
858 |
|
859 | errno = 0;
|
860 | if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
|
861 | return NULL;
|
862 | Py_BEGIN_ALLOW_THREADS
|
863 | dirp = opendir(name);
|
864 | Py_END_ALLOW_THREADS
|
865 | if (dirp == NULL) {
|
866 | return posix_error_with_allocated_filename(name);
|
867 | }
|
868 | if ((d = PyList_New(0)) == NULL) {
|
869 | Py_BEGIN_ALLOW_THREADS
|
870 | closedir(dirp);
|
871 | Py_END_ALLOW_THREADS
|
872 | PyMem_Free(name);
|
873 | return NULL;
|
874 | }
|
875 | for (;;) {
|
876 | errno = 0;
|
877 | Py_BEGIN_ALLOW_THREADS
|
878 | ep = readdir(dirp);
|
879 | Py_END_ALLOW_THREADS
|
880 | if (ep == NULL) {
|
881 | if (errno == 0) {
|
882 | break;
|
883 | } else {
|
884 | Py_BEGIN_ALLOW_THREADS
|
885 | closedir(dirp);
|
886 | Py_END_ALLOW_THREADS
|
887 | Py_DECREF(d);
|
888 | return posix_error_with_allocated_filename(name);
|
889 | }
|
890 | }
|
891 | if (ep->d_name[0] == '.' &&
|
892 | (NAMLEN(ep) == 1 ||
|
893 | (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
|
894 | continue;
|
895 | v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
|
896 | if (v == NULL) {
|
897 | Py_DECREF(d);
|
898 | d = NULL;
|
899 | break;
|
900 | }
|
901 | if (PyList_Append(d, v) != 0) {
|
902 | Py_DECREF(v);
|
903 | Py_DECREF(d);
|
904 | d = NULL;
|
905 | break;
|
906 | }
|
907 | Py_DECREF(v);
|
908 | }
|
909 | Py_BEGIN_ALLOW_THREADS
|
910 | closedir(dirp);
|
911 | Py_END_ALLOW_THREADS
|
912 | PyMem_Free(name);
|
913 |
|
914 | return d;
|
915 | } /* end of posix_listdir */
|
916 |
|
917 | PyDoc_STRVAR_remove(posix_mkdir__doc__,
|
918 | "mkdir(path [, mode=0777])\n\n\
|
919 | Create a directory.");
|
920 |
|
921 | static PyObject *
|
922 | posix_mkdir(PyObject *self, PyObject *args)
|
923 | {
|
924 | int res;
|
925 | char *path = NULL;
|
926 | int mode = 0777;
|
927 |
|
928 | if (!PyArg_ParseTuple(args, "et|i:mkdir",
|
929 | Py_FileSystemDefaultEncoding, &path, &mode))
|
930 | return NULL;
|
931 | Py_BEGIN_ALLOW_THREADS
|
932 | res = mkdir(path, mode);
|
933 | Py_END_ALLOW_THREADS
|
934 | if (res < 0)
|
935 | return posix_error_with_allocated_filename(path);
|
936 | PyMem_Free(path);
|
937 | Py_INCREF(Py_None);
|
938 | return Py_None;
|
939 | }
|
940 |
|
941 |
|
942 | PyDoc_STRVAR_remove(posix_rename__doc__,
|
943 | "rename(old, new)\n\n\
|
944 | Rename a file or directory.");
|
945 |
|
946 | static PyObject *
|
947 | posix_rename(PyObject *self, PyObject *args)
|
948 | {
|
949 | return posix_2str(args, "etet:rename", rename);
|
950 | }
|
951 |
|
952 |
|
953 | PyDoc_STRVAR_remove(posix_rmdir__doc__,
|
954 | "rmdir(path)\n\n\
|
955 | Remove a directory.");
|
956 |
|
957 | static PyObject *
|
958 | posix_rmdir(PyObject *self, PyObject *args)
|
959 | {
|
960 | return posix_1str(args, "et:rmdir", rmdir);
|
961 | }
|
962 |
|
963 |
|
964 | PyDoc_STRVAR_remove(posix_stat__doc__,
|
965 | "stat(path) -> stat result\n\n\
|
966 | Perform a stat system call on the given path.");
|
967 |
|
968 | static PyObject *
|
969 | posix_stat(PyObject *self, PyObject *args)
|
970 | {
|
971 | return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
|
972 | }
|
973 |
|
974 | PyDoc_STRVAR_remove(posix_umask__doc__,
|
975 | "umask(new_mask) -> old_mask\n\n\
|
976 | Set the current numeric umask and return the previous umask.");
|
977 |
|
978 | static PyObject *
|
979 | posix_umask(PyObject *self, PyObject *args)
|
980 | {
|
981 | int i;
|
982 | if (!PyArg_ParseTuple(args, "i:umask", &i))
|
983 | return NULL;
|
984 | i = (int)umask(i);
|
985 | if (i < 0)
|
986 | return posix_error();
|
987 | return PyInt_FromLong((long)i);
|
988 | }
|
989 |
|
990 |
|
991 | PyDoc_STRVAR_remove(posix_unlink__doc__,
|
992 | "unlink(path)\n\n\
|
993 | Remove a file (same as remove(path)).");
|
994 |
|
995 | PyDoc_STRVAR_remove(posix_remove__doc__,
|
996 | "remove(path)\n\n\
|
997 | Remove a file (same as unlink(path)).");
|
998 |
|
999 | static PyObject *
|
1000 | posix_unlink(PyObject *self, PyObject *args)
|
1001 | {
|
1002 | return posix_1str(args, "et:remove", unlink);
|
1003 | }
|
1004 |
|
1005 |
|
1006 | #ifdef HAVE_UNAME
|
1007 | PyDoc_STRVAR_remove(posix_uname__doc__,
|
1008 | "uname() -> (sysname, nodename, release, version, machine)\n\n\
|
1009 | Return a tuple identifying the current operating system.");
|
1010 |
|
1011 | static PyObject *
|
1012 | posix_uname(PyObject *self, PyObject *noargs)
|
1013 | {
|
1014 | struct utsname u;
|
1015 | int res;
|
1016 |
|
1017 | Py_BEGIN_ALLOW_THREADS
|
1018 | res = uname(&u);
|
1019 | Py_END_ALLOW_THREADS
|
1020 | if (res < 0)
|
1021 | return posix_error();
|
1022 | return Py_BuildValue("(sssss)",
|
1023 | u.sysname,
|
1024 | u.nodename,
|
1025 | u.release,
|
1026 | u.version,
|
1027 | u.machine);
|
1028 | }
|
1029 | #endif /* HAVE_UNAME */
|
1030 |
|
1031 | /* Process operations */
|
1032 |
|
1033 | PyDoc_STRVAR_remove(posix__exit__doc__,
|
1034 | "_exit(status)\n\n\
|
1035 | Exit to the system with specified status, without normal exit processing.");
|
1036 |
|
1037 | static PyObject *
|
1038 | posix__exit(PyObject *self, PyObject *args)
|
1039 | {
|
1040 | int sts;
|
1041 | if (!PyArg_ParseTuple(args, "i:_exit", &sts))
|
1042 | return NULL;
|
1043 | _exit(sts);
|
1044 | return NULL; /* Make gcc -Wall happy */
|
1045 | }
|
1046 |
|
1047 | #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
|
1048 | static void
|
1049 | free_string_array(char **array, Py_ssize_t count)
|
1050 | {
|
1051 | Py_ssize_t i;
|
1052 | for (i = 0; i < count; i++)
|
1053 | PyMem_Free(array[i]);
|
1054 | PyMem_DEL(array);
|
1055 | }
|
1056 | #endif
|
1057 |
|
1058 |
|
1059 | #ifdef HAVE_EXECV
|
1060 | PyDoc_STRVAR_remove(posix_execv__doc__,
|
1061 | "execv(path, args)\n\n\
|
1062 | Execute an executable path with arguments, replacing current process.\n\
|
1063 | \n\
|
1064 | path: path of executable file\n\
|
1065 | args: tuple or list of strings");
|
1066 |
|
1067 | static PyObject *
|
1068 | posix_execv(PyObject *self, PyObject *args)
|
1069 | {
|
1070 | char *path;
|
1071 | PyObject *argv;
|
1072 | char **argvlist;
|
1073 | Py_ssize_t i, argc;
|
1074 | PyObject *(*getitem)(PyObject *, Py_ssize_t);
|
1075 |
|
1076 | /* execv has two arguments: (path, argv), where
|
1077 | argv is a list or tuple of strings. */
|
1078 |
|
1079 | if (!PyArg_ParseTuple(args, "etO:execv",
|
1080 | Py_FileSystemDefaultEncoding,
|
1081 | &path, &argv))
|
1082 | return NULL;
|
1083 | if (PyList_Check(argv)) {
|
1084 | argc = PyList_Size(argv);
|
1085 | getitem = PyList_GetItem;
|
1086 | }
|
1087 | else if (PyTuple_Check(argv)) {
|
1088 | argc = PyTuple_Size(argv);
|
1089 | getitem = PyTuple_GetItem;
|
1090 | }
|
1091 | else {
|
1092 | PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
|
1093 | PyMem_Free(path);
|
1094 | return NULL;
|
1095 | }
|
1096 | if (argc < 1) {
|
1097 | PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
|
1098 | PyMem_Free(path);
|
1099 | return NULL;
|
1100 | }
|
1101 |
|
1102 | argvlist = PyMem_NEW(char *, argc+1);
|
1103 | if (argvlist == NULL) {
|
1104 | PyMem_Free(path);
|
1105 | return PyErr_NoMemory();
|
1106 | }
|
1107 | for (i = 0; i < argc; i++) {
|
1108 | if (!PyArg_Parse((*getitem)(argv, i), "et",
|
1109 | Py_FileSystemDefaultEncoding,
|
1110 | &argvlist[i])) {
|
1111 | free_string_array(argvlist, i);
|
1112 | PyErr_SetString(PyExc_TypeError,
|
1113 | "execv() arg 2 must contain only strings");
|
1114 | PyMem_Free(path);
|
1115 | return NULL;
|
1116 |
|
1117 | }
|
1118 | }
|
1119 | argvlist[argc] = NULL;
|
1120 |
|
1121 | execv(path, argvlist);
|
1122 |
|
1123 | /* If we get here it's definitely an error */
|
1124 |
|
1125 | free_string_array(argvlist, argc);
|
1126 | PyMem_Free(path);
|
1127 | return posix_error();
|
1128 | }
|
1129 |
|
1130 |
|
1131 | PyDoc_STRVAR_remove(posix_execve__doc__,
|
1132 | "execve(path, args, env)\n\n\
|
1133 | Execute a path with arguments and environment, replacing current process.\n\
|
1134 | \n\
|
1135 | path: path of executable file\n\
|
1136 | args: tuple or list of arguments\n\
|
1137 | env: dictionary of strings mapping to strings");
|
1138 |
|
1139 | static PyObject *
|
1140 | posix_execve(PyObject *self, PyObject *args)
|
1141 | {
|
1142 | char *path;
|
1143 | PyObject *argv, *env;
|
1144 | char **argvlist;
|
1145 | char **envlist;
|
1146 | PyObject *key, *val, *keys=NULL, *vals=NULL;
|
1147 | Py_ssize_t i, pos, argc, envc;
|
1148 | PyObject *(*getitem)(PyObject *, Py_ssize_t);
|
1149 | Py_ssize_t lastarg = 0;
|
1150 |
|
1151 | /* execve has three arguments: (path, argv, env), where
|
1152 | argv is a list or tuple of strings and env is a dictionary
|
1153 | like posix.environ. */
|
1154 |
|
1155 | if (!PyArg_ParseTuple(args, "etOO:execve",
|
1156 | Py_FileSystemDefaultEncoding,
|
1157 | &path, &argv, &env))
|
1158 | return NULL;
|
1159 | if (PyList_Check(argv)) {
|
1160 | argc = PyList_Size(argv);
|
1161 | getitem = PyList_GetItem;
|
1162 | }
|
1163 | else if (PyTuple_Check(argv)) {
|
1164 | argc = PyTuple_Size(argv);
|
1165 | getitem = PyTuple_GetItem;
|
1166 | }
|
1167 | else {
|
1168 | PyErr_SetString(PyExc_TypeError,
|
1169 | "execve() arg 2 must be a tuple or list");
|
1170 | goto fail_0;
|
1171 | }
|
1172 | if (!PyMapping_Check(env)) {
|
1173 | PyErr_SetString(PyExc_TypeError,
|
1174 | "execve() arg 3 must be a mapping object");
|
1175 | goto fail_0;
|
1176 | }
|
1177 |
|
1178 | argvlist = PyMem_NEW(char *, argc+1);
|
1179 | if (argvlist == NULL) {
|
1180 | PyErr_NoMemory();
|
1181 | goto fail_0;
|
1182 | }
|
1183 | for (i = 0; i < argc; i++) {
|
1184 | if (!PyArg_Parse((*getitem)(argv, i),
|
1185 | "et;execve() arg 2 must contain only strings",
|
1186 | Py_FileSystemDefaultEncoding,
|
1187 | &argvlist[i]))
|
1188 | {
|
1189 | lastarg = i;
|
1190 | goto fail_1;
|
1191 | }
|
1192 | }
|
1193 | lastarg = argc;
|
1194 | argvlist[argc] = NULL;
|
1195 |
|
1196 | i = PyMapping_Size(env);
|
1197 | if (i < 0)
|
1198 | goto fail_1;
|
1199 | envlist = PyMem_NEW(char *, i + 1);
|
1200 | if (envlist == NULL) {
|
1201 | PyErr_NoMemory();
|
1202 | goto fail_1;
|
1203 | }
|
1204 | envc = 0;
|
1205 | keys = PyMapping_Keys(env);
|
1206 | vals = PyMapping_Values(env);
|
1207 | if (!keys || !vals)
|
1208 | goto fail_2;
|
1209 | if (!PyList_Check(keys) || !PyList_Check(vals)) {
|
1210 | PyErr_SetString(PyExc_TypeError,
|
1211 | "execve(): env.keys() or env.values() is not a list");
|
1212 | goto fail_2;
|
1213 | }
|
1214 |
|
1215 | for (pos = 0; pos < i; pos++) {
|
1216 | char *p, *k, *v;
|
1217 | size_t len;
|
1218 |
|
1219 | key = PyList_GetItem(keys, pos);
|
1220 | val = PyList_GetItem(vals, pos);
|
1221 | if (!key || !val)
|
1222 | goto fail_2;
|
1223 |
|
1224 | if (!PyArg_Parse(
|
1225 | key,
|
1226 | "s;execve() arg 3 contains a non-string key",
|
1227 | &k) ||
|
1228 | !PyArg_Parse(
|
1229 | val,
|
1230 | "s;execve() arg 3 contains a non-string value",
|
1231 | &v))
|
1232 | {
|
1233 | goto fail_2;
|
1234 | }
|
1235 |
|
1236 | len = PyString_Size(key) + PyString_Size(val) + 2;
|
1237 | p = PyMem_NEW(char, len);
|
1238 | if (p == NULL) {
|
1239 | PyErr_NoMemory();
|
1240 | goto fail_2;
|
1241 | }
|
1242 | PyOS_snprintf(p, len, "%s=%s", k, v);
|
1243 | envlist[envc++] = p;
|
1244 | }
|
1245 | envlist[envc] = 0;
|
1246 |
|
1247 | execve(path, argvlist, envlist);
|
1248 |
|
1249 | /* If we get here it's definitely an error */
|
1250 |
|
1251 | (void) posix_error();
|
1252 |
|
1253 | fail_2:
|
1254 | while (--envc >= 0)
|
1255 | PyMem_DEL(envlist[envc]);
|
1256 | PyMem_DEL(envlist);
|
1257 | fail_1:
|
1258 | free_string_array(argvlist, lastarg);
|
1259 | Py_XDECREF(vals);
|
1260 | Py_XDECREF(keys);
|
1261 | fail_0:
|
1262 | PyMem_Free(path);
|
1263 | return NULL;
|
1264 | }
|
1265 | #endif /* HAVE_EXECV */
|
1266 |
|
1267 | #ifdef HAVE_FORK
|
1268 | PyDoc_STRVAR_remove(posix_fork__doc__,
|
1269 | "fork() -> pid\n\n\
|
1270 | Fork a child process.\n\
|
1271 | Return 0 to child process and PID of child to parent process.");
|
1272 |
|
1273 | static PyObject *
|
1274 | posix_fork(PyObject *self, PyObject *noargs)
|
1275 | {
|
1276 | pid_t pid;
|
1277 | int result = 0;
|
1278 | _PyImport_AcquireLock();
|
1279 | pid = fork();
|
1280 | if (pid == 0) {
|
1281 | /* child: this clobbers and resets the import lock. */
|
1282 | PyOS_AfterFork();
|
1283 | } else {
|
1284 | /* parent: release the import lock. */
|
1285 | result = _PyImport_ReleaseLock();
|
1286 | }
|
1287 | if (pid == -1)
|
1288 | return posix_error();
|
1289 | if (result < 0) {
|
1290 | /* Don't clobber the OSError if the fork failed. */
|
1291 | PyErr_SetString(PyExc_RuntimeError,
|
1292 | "not holding the import lock");
|
1293 | return NULL;
|
1294 | }
|
1295 | return PyLong_FromPid(pid);
|
1296 | }
|
1297 | #endif
|
1298 |
|
1299 | #ifdef HAVE_GETEGID
|
1300 | PyDoc_STRVAR_remove(posix_getegid__doc__,
|
1301 | "getegid() -> egid\n\n\
|
1302 | Return the current process's effective group id.");
|
1303 |
|
1304 | static PyObject *
|
1305 | posix_getegid(PyObject *self, PyObject *noargs)
|
1306 | {
|
1307 | return _PyInt_FromGid(getegid());
|
1308 | }
|
1309 | #endif
|
1310 |
|
1311 |
|
1312 | #ifdef HAVE_GETEUID
|
1313 | PyDoc_STRVAR_remove(posix_geteuid__doc__,
|
1314 | "geteuid() -> euid\n\n\
|
1315 | Return the current process's effective user id.");
|
1316 |
|
1317 | static PyObject *
|
1318 | posix_geteuid(PyObject *self, PyObject *noargs)
|
1319 | {
|
1320 | return _PyInt_FromUid(geteuid());
|
1321 | }
|
1322 | #endif
|
1323 |
|
1324 |
|
1325 | #ifdef HAVE_GETGID
|
1326 | PyDoc_STRVAR_remove(posix_getgid__doc__,
|
1327 | "getgid() -> gid\n\n\
|
1328 | Return the current process's group id.");
|
1329 |
|
1330 | static PyObject *
|
1331 | posix_getgid(PyObject *self, PyObject *noargs)
|
1332 | {
|
1333 | return _PyInt_FromGid(getgid());
|
1334 | }
|
1335 | #endif
|
1336 |
|
1337 |
|
1338 | PyDoc_STRVAR_remove(posix_getpid__doc__,
|
1339 | "getpid() -> pid\n\n\
|
1340 | Return the current process id");
|
1341 |
|
1342 | static PyObject *
|
1343 | posix_getpid(PyObject *self, PyObject *noargs)
|
1344 | {
|
1345 | return PyLong_FromPid(getpid());
|
1346 | }
|
1347 |
|
1348 | #ifdef HAVE_GETPGID
|
1349 | PyDoc_STRVAR_remove(posix_getpgid__doc__,
|
1350 | "getpgid(pid) -> pgid\n\n\
|
1351 | Call the system call getpgid().");
|
1352 |
|
1353 | static PyObject *
|
1354 | posix_getpgid(PyObject *self, PyObject *args)
|
1355 | {
|
1356 | pid_t pid, pgid;
|
1357 | if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
|
1358 | return NULL;
|
1359 | pgid = getpgid(pid);
|
1360 | if (pgid < 0)
|
1361 | return posix_error();
|
1362 | return PyLong_FromPid(pgid);
|
1363 | }
|
1364 | #endif /* HAVE_GETPGID */
|
1365 |
|
1366 |
|
1367 | #ifdef HAVE_GETPPID
|
1368 | PyDoc_STRVAR_remove(posix_getppid__doc__,
|
1369 | "getppid() -> ppid\n\n\
|
1370 | Return the parent's process id.");
|
1371 |
|
1372 | static PyObject *
|
1373 | posix_getppid(PyObject *self, PyObject *noargs)
|
1374 | {
|
1375 | return PyLong_FromPid(getppid());
|
1376 | }
|
1377 | #endif
|
1378 |
|
1379 |
|
1380 | #ifdef HAVE_GETUID
|
1381 | PyDoc_STRVAR_remove(posix_getuid__doc__,
|
1382 | "getuid() -> uid\n\n\
|
1383 | Return the current process's user id.");
|
1384 |
|
1385 | static PyObject *
|
1386 | posix_getuid(PyObject *self, PyObject *noargs)
|
1387 | {
|
1388 | return _PyInt_FromUid(getuid());
|
1389 | }
|
1390 | #endif
|
1391 |
|
1392 |
|
1393 | #ifdef HAVE_KILL
|
1394 | PyDoc_STRVAR_remove(posix_kill__doc__,
|
1395 | "kill(pid, sig)\n\n\
|
1396 | Kill a process with a signal.");
|
1397 |
|
1398 | static PyObject *
|
1399 | posix_kill(PyObject *self, PyObject *args)
|
1400 | {
|
1401 | pid_t pid;
|
1402 | int sig;
|
1403 | if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
|
1404 | return NULL;
|
1405 | if (kill(pid, sig) == -1)
|
1406 | return posix_error();
|
1407 | Py_INCREF(Py_None);
|
1408 | return Py_None;
|
1409 | }
|
1410 | #endif
|
1411 |
|
1412 | #ifdef HAVE_KILLPG
|
1413 | PyDoc_STRVAR_remove(posix_killpg__doc__,
|
1414 | "killpg(pgid, sig)\n\n\
|
1415 | Kill a process group with a signal.");
|
1416 |
|
1417 | static PyObject *
|
1418 | posix_killpg(PyObject *self, PyObject *args)
|
1419 | {
|
1420 | int sig;
|
1421 | pid_t pgid;
|
1422 | /* XXX some man pages make the `pgid` parameter an int, others
|
1423 | a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
|
1424 | take the same type. Moreover, pid_t is always at least as wide as
|
1425 | int (else compilation of this module fails), which is safe. */
|
1426 | if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
|
1427 | return NULL;
|
1428 | if (killpg(pgid, sig) == -1)
|
1429 | return posix_error();
|
1430 | Py_INCREF(Py_None);
|
1431 | return Py_None;
|
1432 | }
|
1433 | #endif
|
1434 |
|
1435 | #ifdef HAVE_SETUID
|
1436 | PyDoc_STRVAR_remove(posix_setuid__doc__,
|
1437 | "setuid(uid)\n\n\
|
1438 | Set the current process's user id.");
|
1439 |
|
1440 | static PyObject *
|
1441 | posix_setuid(PyObject *self, PyObject *args)
|
1442 | {
|
1443 | uid_t uid;
|
1444 | if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
|
1445 | return NULL;
|
1446 | if (setuid(uid) < 0)
|
1447 | return posix_error();
|
1448 | Py_INCREF(Py_None);
|
1449 | return Py_None;
|
1450 | }
|
1451 | #endif /* HAVE_SETUID */
|
1452 |
|
1453 |
|
1454 | #ifdef HAVE_SETEUID
|
1455 | PyDoc_STRVAR_remove(posix_seteuid__doc__,
|
1456 | "seteuid(uid)\n\n\
|
1457 | Set the current process's effective user id.");
|
1458 |
|
1459 | static PyObject *
|
1460 | posix_seteuid (PyObject *self, PyObject *args)
|
1461 | {
|
1462 | uid_t euid;
|
1463 | if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
|
1464 | return NULL;
|
1465 | if (seteuid(euid) < 0) {
|
1466 | return posix_error();
|
1467 | } else {
|
1468 | Py_INCREF(Py_None);
|
1469 | return Py_None;
|
1470 | }
|
1471 | }
|
1472 | #endif /* HAVE_SETEUID */
|
1473 |
|
1474 | #ifdef HAVE_SETEGID
|
1475 | PyDoc_STRVAR_remove(posix_setegid__doc__,
|
1476 | "setegid(gid)\n\n\
|
1477 | Set the current process's effective group id.");
|
1478 |
|
1479 | static PyObject *
|
1480 | posix_setegid (PyObject *self, PyObject *args)
|
1481 | {
|
1482 | gid_t egid;
|
1483 | if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
|
1484 | return NULL;
|
1485 | if (setegid(egid) < 0) {
|
1486 | return posix_error();
|
1487 | } else {
|
1488 | Py_INCREF(Py_None);
|
1489 | return Py_None;
|
1490 | }
|
1491 | }
|
1492 | #endif /* HAVE_SETEGID */
|
1493 |
|
1494 | #ifdef HAVE_SETREUID
|
1495 | PyDoc_STRVAR_remove(posix_setreuid__doc__,
|
1496 | "setreuid(ruid, euid)\n\n\
|
1497 | Set the current process's real and effective user ids.");
|
1498 |
|
1499 | static PyObject *
|
1500 | posix_setreuid (PyObject *self, PyObject *args)
|
1501 | {
|
1502 | uid_t ruid, euid;
|
1503 | if (!PyArg_ParseTuple(args, "O&O&:setreuid",
|
1504 | _Py_Uid_Converter, &ruid,
|
1505 | _Py_Uid_Converter, &euid))
|
1506 | return NULL;
|
1507 | if (setreuid(ruid, euid) < 0) {
|
1508 | return posix_error();
|
1509 | } else {
|
1510 | Py_INCREF(Py_None);
|
1511 | return Py_None;
|
1512 | }
|
1513 | }
|
1514 | #endif /* HAVE_SETREUID */
|
1515 |
|
1516 | #ifdef HAVE_SETREGID
|
1517 | PyDoc_STRVAR_remove(posix_setregid__doc__,
|
1518 | "setregid(rgid, egid)\n\n\
|
1519 | Set the current process's real and effective group ids.");
|
1520 |
|
1521 | static PyObject *
|
1522 | posix_setregid (PyObject *self, PyObject *args)
|
1523 | {
|
1524 | gid_t rgid, egid;
|
1525 | if (!PyArg_ParseTuple(args, "O&O&:setregid",
|
1526 | _Py_Gid_Converter, &rgid,
|
1527 | _Py_Gid_Converter, &egid))
|
1528 | return NULL;
|
1529 | if (setregid(rgid, egid) < 0) {
|
1530 | return posix_error();
|
1531 | } else {
|
1532 | Py_INCREF(Py_None);
|
1533 | return Py_None;
|
1534 | }
|
1535 | }
|
1536 | #endif /* HAVE_SETREGID */
|
1537 |
|
1538 | #ifdef HAVE_SETGID
|
1539 | PyDoc_STRVAR_remove(posix_setgid__doc__,
|
1540 | "setgid(gid)\n\n\
|
1541 | Set the current process's group id.");
|
1542 |
|
1543 | static PyObject *
|
1544 | posix_setgid(PyObject *self, PyObject *args)
|
1545 | {
|
1546 | gid_t gid;
|
1547 | if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
|
1548 | return NULL;
|
1549 | if (setgid(gid) < 0)
|
1550 | return posix_error();
|
1551 | Py_INCREF(Py_None);
|
1552 | return Py_None;
|
1553 | }
|
1554 | #endif /* HAVE_SETGID */
|
1555 |
|
1556 | #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
|
1557 | static PyObject *
|
1558 | wait_helper(pid_t pid, int status, struct rusage *ru)
|
1559 | {
|
1560 | PyObject *result;
|
1561 | static PyObject *struct_rusage;
|
1562 |
|
1563 | if (pid == -1)
|
1564 | return posix_error();
|
1565 |
|
1566 | if (struct_rusage == NULL) {
|
1567 | PyObject *m = PyImport_ImportModuleNoBlock("resource");
|
1568 | if (m == NULL)
|
1569 | return NULL;
|
1570 | struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
|
1571 | Py_DECREF(m);
|
1572 | if (struct_rusage == NULL)
|
1573 | return NULL;
|
1574 | }
|
1575 |
|
1576 | /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
|
1577 | result = PyStructSequence_New((PyTypeObject*) struct_rusage);
|
1578 | if (!result)
|
1579 | return NULL;
|
1580 |
|
1581 | #ifndef doubletime
|
1582 | #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
|
1583 | #endif
|
1584 |
|
1585 | PyStructSequence_SET_ITEM(result, 0,
|
1586 | PyFloat_FromDouble(doubletime(ru->ru_utime)));
|
1587 | PyStructSequence_SET_ITEM(result, 1,
|
1588 | PyFloat_FromDouble(doubletime(ru->ru_stime)));
|
1589 | #define SET_INT(result, index, value)\
|
1590 | PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
|
1591 | SET_INT(result, 2, ru->ru_maxrss);
|
1592 | SET_INT(result, 3, ru->ru_ixrss);
|
1593 | SET_INT(result, 4, ru->ru_idrss);
|
1594 | SET_INT(result, 5, ru->ru_isrss);
|
1595 | SET_INT(result, 6, ru->ru_minflt);
|
1596 | SET_INT(result, 7, ru->ru_majflt);
|
1597 | SET_INT(result, 8, ru->ru_nswap);
|
1598 | SET_INT(result, 9, ru->ru_inblock);
|
1599 | SET_INT(result, 10, ru->ru_oublock);
|
1600 | SET_INT(result, 11, ru->ru_msgsnd);
|
1601 | SET_INT(result, 12, ru->ru_msgrcv);
|
1602 | SET_INT(result, 13, ru->ru_nsignals);
|
1603 | SET_INT(result, 14, ru->ru_nvcsw);
|
1604 | SET_INT(result, 15, ru->ru_nivcsw);
|
1605 | #undef SET_INT
|
1606 |
|
1607 | if (PyErr_Occurred()) {
|
1608 | Py_DECREF(result);
|
1609 | return NULL;
|
1610 | }
|
1611 |
|
1612 | return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
|
1613 | }
|
1614 | #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
|
1615 |
|
1616 | #ifdef HAVE_WAIT3
|
1617 | PyDoc_STRVAR_remove(posix_wait3__doc__,
|
1618 | "wait3(options) -> (pid, status, rusage)\n\n\
|
1619 | Wait for completion of a child process.");
|
1620 |
|
1621 | static PyObject *
|
1622 | posix_wait3(PyObject *self, PyObject *args)
|
1623 | {
|
1624 | pid_t pid;
|
1625 | int options;
|
1626 | struct rusage ru;
|
1627 | WAIT_TYPE status;
|
1628 | WAIT_STATUS_INT(status) = 0;
|
1629 |
|
1630 | if (!PyArg_ParseTuple(args, "i:wait3", &options))
|
1631 | return NULL;
|
1632 |
|
1633 | Py_BEGIN_ALLOW_THREADS
|
1634 | pid = wait3(&status, options, &ru);
|
1635 | Py_END_ALLOW_THREADS
|
1636 |
|
1637 | return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
|
1638 | }
|
1639 | #endif /* HAVE_WAIT3 */
|
1640 |
|
1641 | #ifdef HAVE_WAIT4
|
1642 | PyDoc_STRVAR_remove(posix_wait4__doc__,
|
1643 | "wait4(pid, options) -> (pid, status, rusage)\n\n\
|
1644 | Wait for completion of a given child process.");
|
1645 |
|
1646 | static PyObject *
|
1647 | posix_wait4(PyObject *self, PyObject *args)
|
1648 | {
|
1649 | pid_t pid;
|
1650 | int options;
|
1651 | struct rusage ru;
|
1652 | WAIT_TYPE status;
|
1653 | WAIT_STATUS_INT(status) = 0;
|
1654 |
|
1655 | if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
|
1656 | return NULL;
|
1657 |
|
1658 | Py_BEGIN_ALLOW_THREADS
|
1659 | pid = wait4(pid, &status, options, &ru);
|
1660 | Py_END_ALLOW_THREADS
|
1661 |
|
1662 | return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
|
1663 | }
|
1664 | #endif /* HAVE_WAIT4 */
|
1665 |
|
1666 | #ifdef HAVE_WAITPID
|
1667 | PyDoc_STRVAR_remove(posix_waitpid__doc__,
|
1668 | "waitpid(pid, options) -> (pid, status)\n\n\
|
1669 | Wait for completion of a given child process.");
|
1670 |
|
1671 | // NO PATCH HERE FOR EINTR !!! See core/process.py.
|
1672 | static PyObject *
|
1673 | posix_waitpid(PyObject *self, PyObject *args)
|
1674 | {
|
1675 | pid_t pid;
|
1676 | int options;
|
1677 | WAIT_TYPE status;
|
1678 | WAIT_STATUS_INT(status) = 0;
|
1679 |
|
1680 | if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
|
1681 | return NULL;
|
1682 | Py_BEGIN_ALLOW_THREADS
|
1683 | pid = waitpid(pid, &status, options);
|
1684 | Py_END_ALLOW_THREADS
|
1685 | if (pid == -1)
|
1686 | return posix_error();
|
1687 |
|
1688 | return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
|
1689 | }
|
1690 | #endif /* HAVE_WAITPID */
|
1691 |
|
1692 | #ifdef HAVE_WAIT
|
1693 | PyDoc_STRVAR_remove(posix_wait__doc__,
|
1694 | "wait() -> (pid, status)\n\n\
|
1695 | Wait for completion of a child process.");
|
1696 |
|
1697 | static PyObject *
|
1698 | posix_wait(PyObject *self, PyObject *noargs)
|
1699 | {
|
1700 | pid_t pid;
|
1701 | WAIT_TYPE status;
|
1702 | WAIT_STATUS_INT(status) = 0;
|
1703 |
|
1704 | // OVM_MAIN patch: Retry on EINTR.
|
1705 | while (1) {
|
1706 | Py_BEGIN_ALLOW_THREADS
|
1707 | pid = wait(&status);
|
1708 | Py_END_ALLOW_THREADS
|
1709 |
|
1710 | if (pid >= 0) { // success
|
1711 | break;
|
1712 | } else {
|
1713 | if (PyErr_CheckSignals()) {
|
1714 | return NULL; // Propagate KeyboardInterrupt
|
1715 | }
|
1716 | if (errno != EINTR) { // e.g. ECHILD
|
1717 | return posix_error();
|
1718 | }
|
1719 | }
|
1720 | // Otherwise, try again on EINTR.
|
1721 | }
|
1722 |
|
1723 | return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
|
1724 | }
|
1725 | #endif
|
1726 |
|
1727 |
|
1728 | PyDoc_STRVAR_remove(posix_lstat__doc__,
|
1729 | "lstat(path) -> stat result\n\n\
|
1730 | Like stat(path), but do not follow symbolic links.");
|
1731 |
|
1732 | static PyObject *
|
1733 | posix_lstat(PyObject *self, PyObject *args)
|
1734 | {
|
1735 | #ifdef HAVE_LSTAT
|
1736 | return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
|
1737 | #else /* !HAVE_LSTAT */
|
1738 | return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
|
1739 | #endif /* !HAVE_LSTAT */
|
1740 | }
|
1741 |
|
1742 |
|
1743 | #ifdef HAVE_READLINK
|
1744 | PyDoc_STRVAR_remove(posix_readlink__doc__,
|
1745 | "readlink(path) -> path\n\n\
|
1746 | Return a string representing the path to which the symbolic link points.");
|
1747 |
|
1748 | static PyObject *
|
1749 | posix_readlink(PyObject *self, PyObject *args)
|
1750 | {
|
1751 | PyObject* v;
|
1752 | char buf[MAXPATHLEN];
|
1753 | char *path;
|
1754 | int n;
|
1755 | #ifdef Py_USING_UNICODE
|
1756 | int arg_is_unicode = 0;
|
1757 | #endif
|
1758 |
|
1759 | if (!PyArg_ParseTuple(args, "et:readlink",
|
1760 | Py_FileSystemDefaultEncoding, &path))
|
1761 | return NULL;
|
1762 | #ifdef Py_USING_UNICODE
|
1763 | v = PySequence_GetItem(args, 0);
|
1764 | if (v == NULL) {
|
1765 | PyMem_Free(path);
|
1766 | return NULL;
|
1767 | }
|
1768 |
|
1769 | if (PyUnicode_Check(v)) {
|
1770 | arg_is_unicode = 1;
|
1771 | }
|
1772 | Py_DECREF(v);
|
1773 | #endif
|
1774 |
|
1775 | Py_BEGIN_ALLOW_THREADS
|
1776 | n = readlink(path, buf, (int) sizeof buf);
|
1777 | Py_END_ALLOW_THREADS
|
1778 | if (n < 0)
|
1779 | return posix_error_with_allocated_filename(path);
|
1780 |
|
1781 | PyMem_Free(path);
|
1782 | v = PyString_FromStringAndSize(buf, n);
|
1783 | #ifdef Py_USING_UNICODE
|
1784 | if (arg_is_unicode) {
|
1785 | PyObject *w;
|
1786 |
|
1787 | w = PyUnicode_FromEncodedObject(v,
|
1788 | Py_FileSystemDefaultEncoding,
|
1789 | "strict");
|
1790 | if (w != NULL) {
|
1791 | Py_DECREF(v);
|
1792 | v = w;
|
1793 | }
|
1794 | else {
|
1795 | /* fall back to the original byte string, as
|
1796 | discussed in patch #683592 */
|
1797 | PyErr_Clear();
|
1798 | }
|
1799 | }
|
1800 | #endif
|
1801 | return v;
|
1802 | }
|
1803 | #endif /* HAVE_READLINK */
|
1804 |
|
1805 |
|
1806 | #ifdef HAVE_SYMLINK
|
1807 | PyDoc_STRVAR_remove(posix_symlink__doc__,
|
1808 | "symlink(src, dst)\n\n\
|
1809 | Create a symbolic link pointing to src named dst.");
|
1810 |
|
1811 | static PyObject *
|
1812 | posix_symlink(PyObject *self, PyObject *args)
|
1813 | {
|
1814 | return posix_2str(args, "etet:symlink", symlink);
|
1815 | }
|
1816 | #endif /* HAVE_SYMLINK */
|
1817 |
|
1818 |
|
1819 | #ifdef HAVE_TIMES
|
1820 | #define NEED_TICKS_PER_SECOND
|
1821 | static long ticks_per_second = -1;
|
1822 | static PyObject *
|
1823 | posix_times(PyObject *self, PyObject *noargs)
|
1824 | {
|
1825 | struct tms t;
|
1826 | clock_t c;
|
1827 | errno = 0;
|
1828 | c = times(&t);
|
1829 | if (c == (clock_t) -1)
|
1830 | return posix_error();
|
1831 | return Py_BuildValue("ddddd",
|
1832 | (double)t.tms_utime / ticks_per_second,
|
1833 | (double)t.tms_stime / ticks_per_second,
|
1834 | (double)t.tms_cutime / ticks_per_second,
|
1835 | (double)t.tms_cstime / ticks_per_second,
|
1836 | (double)c / ticks_per_second);
|
1837 | }
|
1838 | #endif /* HAVE_TIMES */
|
1839 |
|
1840 |
|
1841 | #ifdef HAVE_TIMES
|
1842 | PyDoc_STRVAR_remove(posix_times__doc__,
|
1843 | "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
|
1844 | Return a tuple of floating point numbers indicating process times.");
|
1845 | #endif
|
1846 |
|
1847 |
|
1848 | #ifdef HAVE_GETSID
|
1849 | PyDoc_STRVAR_remove(posix_getsid__doc__,
|
1850 | "getsid(pid) -> sid\n\n\
|
1851 | Call the system call getsid().");
|
1852 |
|
1853 | static PyObject *
|
1854 | posix_getsid(PyObject *self, PyObject *args)
|
1855 | {
|
1856 | pid_t pid;
|
1857 | int sid;
|
1858 | if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
|
1859 | return NULL;
|
1860 | sid = getsid(pid);
|
1861 | if (sid < 0)
|
1862 | return posix_error();
|
1863 | return PyInt_FromLong((long)sid);
|
1864 | }
|
1865 | #endif /* HAVE_GETSID */
|
1866 |
|
1867 |
|
1868 | #ifdef HAVE_SETSID
|
1869 | PyDoc_STRVAR_remove(posix_setsid__doc__,
|
1870 | "setsid()\n\n\
|
1871 | Call the system call setsid().");
|
1872 |
|
1873 | static PyObject *
|
1874 | posix_setsid(PyObject *self, PyObject *noargs)
|
1875 | {
|
1876 | if (setsid() < 0)
|
1877 | return posix_error();
|
1878 | Py_INCREF(Py_None);
|
1879 | return Py_None;
|
1880 | }
|
1881 | #endif /* HAVE_SETSID */
|
1882 |
|
1883 | #ifdef HAVE_SETPGID
|
1884 | PyDoc_STRVAR_remove(posix_setpgid__doc__,
|
1885 | "setpgid(pid, pgrp)\n\n\
|
1886 | Call the system call setpgid().");
|
1887 |
|
1888 | static PyObject *
|
1889 | posix_setpgid(PyObject *self, PyObject *args)
|
1890 | {
|
1891 | pid_t pid;
|
1892 | int pgrp;
|
1893 | if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
|
1894 | return NULL;
|
1895 | if (setpgid(pid, pgrp) < 0)
|
1896 | return posix_error();
|
1897 | Py_INCREF(Py_None);
|
1898 | return Py_None;
|
1899 | }
|
1900 | #endif /* HAVE_SETPGID */
|
1901 |
|
1902 |
|
1903 | #ifdef HAVE_TCGETPGRP
|
1904 | PyDoc_STRVAR_remove(posix_tcgetpgrp__doc__,
|
1905 | "tcgetpgrp(fd) -> pgid\n\n\
|
1906 | Return the process group associated with the terminal given by a fd.");
|
1907 |
|
1908 | static PyObject *
|
1909 | posix_tcgetpgrp(PyObject *self, PyObject *args)
|
1910 | {
|
1911 | int fd;
|
1912 | pid_t pgid;
|
1913 | if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
|
1914 | return NULL;
|
1915 | pgid = tcgetpgrp(fd);
|
1916 | if (pgid < 0)
|
1917 | return posix_error();
|
1918 | return PyLong_FromPid(pgid);
|
1919 | }
|
1920 | #endif /* HAVE_TCGETPGRP */
|
1921 |
|
1922 |
|
1923 | #ifdef HAVE_TCSETPGRP
|
1924 | PyDoc_STRVAR_remove(posix_tcsetpgrp__doc__,
|
1925 | "tcsetpgrp(fd, pgid)\n\n\
|
1926 | Set the process group associated with the terminal given by a fd.");
|
1927 |
|
1928 | static PyObject *
|
1929 | posix_tcsetpgrp(PyObject *self, PyObject *args)
|
1930 | {
|
1931 | int fd;
|
1932 | pid_t pgid;
|
1933 | if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
|
1934 | return NULL;
|
1935 | if (tcsetpgrp(fd, pgid) < 0)
|
1936 | return posix_error();
|
1937 | Py_INCREF(Py_None);
|
1938 | return Py_None;
|
1939 | }
|
1940 | #endif /* HAVE_TCSETPGRP */
|
1941 |
|
1942 | /* Functions acting on file descriptors */
|
1943 |
|
1944 | PyDoc_STRVAR_remove(posix_open__doc__,
|
1945 | "open(filename, flag [, mode=0777]) -> fd\n\n\
|
1946 | Open a file (for low level IO).");
|
1947 |
|
1948 | static PyObject *
|
1949 | posix_open(PyObject *self, PyObject *args)
|
1950 | {
|
1951 | char *file = NULL;
|
1952 | int flag;
|
1953 | int mode = 0777;
|
1954 | int fd;
|
1955 |
|
1956 | if (!PyArg_ParseTuple(args, "eti|i",
|
1957 | Py_FileSystemDefaultEncoding, &file,
|
1958 | &flag, &mode))
|
1959 | return NULL;
|
1960 |
|
1961 | Py_BEGIN_ALLOW_THREADS
|
1962 | fd = open(file, flag, mode);
|
1963 | Py_END_ALLOW_THREADS
|
1964 | if (fd < 0)
|
1965 | return posix_error_with_allocated_filename(file);
|
1966 | PyMem_Free(file);
|
1967 | return PyInt_FromLong((long)fd);
|
1968 | }
|
1969 |
|
1970 |
|
1971 | PyDoc_STRVAR_remove(posix_close__doc__,
|
1972 | "close(fd)\n\n\
|
1973 | Close a file descriptor (for low level IO).");
|
1974 |
|
1975 | /*
|
1976 | The underscore at end of function name avoids a name clash with the libc
|
1977 | function posix_close.
|
1978 | */
|
1979 | static PyObject *
|
1980 | posix_close_(PyObject *self, PyObject *args)
|
1981 | {
|
1982 | int fd, res;
|
1983 | if (!PyArg_ParseTuple(args, "i:close", &fd))
|
1984 | return NULL;
|
1985 | if (!_PyVerify_fd(fd))
|
1986 | return posix_error();
|
1987 | Py_BEGIN_ALLOW_THREADS
|
1988 | res = close(fd);
|
1989 | Py_END_ALLOW_THREADS
|
1990 | if (res < 0)
|
1991 | return posix_error();
|
1992 | Py_INCREF(Py_None);
|
1993 | return Py_None;
|
1994 | }
|
1995 |
|
1996 | PyDoc_STRVAR_remove(posix_dup__doc__,
|
1997 | "dup(fd) -> fd2\n\n\
|
1998 | Return a duplicate of a file descriptor.");
|
1999 |
|
2000 | static PyObject *
|
2001 | posix_dup(PyObject *self, PyObject *args)
|
2002 | {
|
2003 | int fd;
|
2004 | if (!PyArg_ParseTuple(args, "i:dup", &fd))
|
2005 | return NULL;
|
2006 | if (!_PyVerify_fd(fd))
|
2007 | return posix_error();
|
2008 | Py_BEGIN_ALLOW_THREADS
|
2009 | fd = dup(fd);
|
2010 | Py_END_ALLOW_THREADS
|
2011 | if (fd < 0)
|
2012 | return posix_error();
|
2013 | return PyInt_FromLong((long)fd);
|
2014 | }
|
2015 |
|
2016 |
|
2017 | PyDoc_STRVAR_remove(posix_dup2__doc__,
|
2018 | "dup2(old_fd, new_fd)\n\n\
|
2019 | Duplicate file descriptor.");
|
2020 |
|
2021 | static PyObject *
|
2022 | posix_dup2(PyObject *self, PyObject *args)
|
2023 | {
|
2024 | int fd, fd2, res;
|
2025 | if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
|
2026 | return NULL;
|
2027 | Py_BEGIN_ALLOW_THREADS
|
2028 | res = dup2(fd, fd2);
|
2029 | Py_END_ALLOW_THREADS
|
2030 | if (res < 0)
|
2031 | return posix_error();
|
2032 | Py_INCREF(Py_None);
|
2033 | return Py_None;
|
2034 | }
|
2035 |
|
2036 |
|
2037 | PyDoc_STRVAR_remove(posix_read__doc__,
|
2038 | "read(fd, buffersize) -> string\n\n\
|
2039 | Read a file descriptor.");
|
2040 |
|
2041 | static PyObject *
|
2042 | posix_read(PyObject *self, PyObject *args)
|
2043 | {
|
2044 | int fd, size, n;
|
2045 | PyObject *buffer;
|
2046 | if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
|
2047 | return NULL;
|
2048 | if (size < 0) {
|
2049 | errno = EINVAL;
|
2050 | return posix_error();
|
2051 | }
|
2052 | buffer = PyString_FromStringAndSize((char *)NULL, size);
|
2053 | if (buffer == NULL)
|
2054 | return NULL;
|
2055 | if (!_PyVerify_fd(fd)) {
|
2056 | Py_DECREF(buffer);
|
2057 | return posix_error();
|
2058 | }
|
2059 | // NOTE: Unlike write(), not retrying on EINTR, because shell's 'read' builtin
|
2060 | // must handle it explicitly, run pending traps, and retry.
|
2061 | Py_BEGIN_ALLOW_THREADS
|
2062 | n = read(fd, PyString_AsString(buffer), size);
|
2063 | Py_END_ALLOW_THREADS
|
2064 | if (n < 0) {
|
2065 | Py_DECREF(buffer);
|
2066 | return posix_error();
|
2067 | }
|
2068 | if (n != size)
|
2069 | _PyString_Resize(&buffer, n);
|
2070 | return buffer;
|
2071 | }
|
2072 |
|
2073 |
|
2074 | PyDoc_STRVAR_remove(posix_write__doc__,
|
2075 | "write(fd, string) -> byteswritten\n\n\
|
2076 | Write a string to a file descriptor.");
|
2077 |
|
2078 | static PyObject *
|
2079 | posix_write(PyObject *self, PyObject *args)
|
2080 | {
|
2081 | Py_buffer pbuf;
|
2082 | int fd;
|
2083 | Py_ssize_t size, len;
|
2084 |
|
2085 | if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
|
2086 | return NULL;
|
2087 | if (!_PyVerify_fd(fd)) {
|
2088 | PyBuffer_Release(&pbuf);
|
2089 | return posix_error();
|
2090 | }
|
2091 | len = pbuf.len;
|
2092 |
|
2093 | // OVM_MAIN patch: Retry on EINTR.
|
2094 | while (1) {
|
2095 | Py_BEGIN_ALLOW_THREADS
|
2096 | size = write(fd, pbuf.buf, len);
|
2097 | Py_END_ALLOW_THREADS
|
2098 |
|
2099 | if (size >= 0) { // success
|
2100 | break;
|
2101 | } else {
|
2102 | if (PyErr_CheckSignals()) {
|
2103 | return NULL; // Propagate KeyboardInterrupt
|
2104 | }
|
2105 | if (errno != EINTR) {
|
2106 | return posix_error();
|
2107 | }
|
2108 | }
|
2109 | }
|
2110 | PyBuffer_Release(&pbuf);
|
2111 | return PyInt_FromSsize_t(size);
|
2112 | }
|
2113 |
|
2114 |
|
2115 | PyDoc_STRVAR_remove(posix_fstat__doc__,
|
2116 | "fstat(fd) -> stat result\n\n\
|
2117 | Like stat(), but for an open file descriptor.");
|
2118 |
|
2119 | static PyObject *
|
2120 | posix_fstat(PyObject *self, PyObject *args)
|
2121 | {
|
2122 | int fd;
|
2123 | STRUCT_STAT st;
|
2124 | int res;
|
2125 | if (!PyArg_ParseTuple(args, "i:fstat", &fd))
|
2126 | return NULL;
|
2127 | #ifdef __VMS
|
2128 | /* on OpenVMS we must ensure that all bytes are written to the file */
|
2129 | fsync(fd);
|
2130 | #endif
|
2131 | if (!_PyVerify_fd(fd))
|
2132 | return posix_error();
|
2133 | Py_BEGIN_ALLOW_THREADS
|
2134 | res = FSTAT(fd, &st);
|
2135 | Py_END_ALLOW_THREADS
|
2136 | if (res != 0) {
|
2137 | return posix_error();
|
2138 | }
|
2139 |
|
2140 | return _pystat_fromstructstat(&st);
|
2141 | }
|
2142 |
|
2143 |
|
2144 | PyDoc_STRVAR_remove(posix_fdopen__doc__,
|
2145 | "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
|
2146 | Return an open file object connected to a file descriptor.");
|
2147 |
|
2148 | static PyObject *
|
2149 | posix_fdopen(PyObject *self, PyObject *args)
|
2150 | {
|
2151 | int fd;
|
2152 | char *orgmode = "r";
|
2153 | int bufsize = -1;
|
2154 | FILE *fp;
|
2155 | PyObject *f;
|
2156 | char *mode;
|
2157 | if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
|
2158 | return NULL;
|
2159 |
|
2160 | /* Sanitize mode. See fileobject.c */
|
2161 | mode = PyMem_MALLOC(strlen(orgmode)+3);
|
2162 | if (!mode) {
|
2163 | PyErr_NoMemory();
|
2164 | return NULL;
|
2165 | }
|
2166 | strcpy(mode, orgmode);
|
2167 | if (_PyFile_SanitizeMode(mode)) {
|
2168 | PyMem_FREE(mode);
|
2169 | return NULL;
|
2170 | }
|
2171 | if (!_PyVerify_fd(fd)) {
|
2172 | PyMem_FREE(mode);
|
2173 | return posix_error();
|
2174 | }
|
2175 | #if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
|
2176 | {
|
2177 | struct stat buf;
|
2178 | const char *msg;
|
2179 | PyObject *exc;
|
2180 | if (fstat(fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
|
2181 | PyMem_FREE(mode);
|
2182 | msg = strerror(EISDIR);
|
2183 | exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
|
2184 | EISDIR, msg, "<fdopen>");
|
2185 | if (exc) {
|
2186 | PyErr_SetObject(PyExc_IOError, exc);
|
2187 | Py_DECREF(exc);
|
2188 | }
|
2189 | return NULL;
|
2190 | }
|
2191 | }
|
2192 | #endif
|
2193 | /* The dummy filename used here must be kept in sync with the value
|
2194 | tested against in gzip.GzipFile.__init__() - see issue #13781. */
|
2195 | f = PyFile_FromFile(NULL, "<fdopen>", orgmode, fclose);
|
2196 | if (f == NULL) {
|
2197 | PyMem_FREE(mode);
|
2198 | return NULL;
|
2199 | }
|
2200 | Py_BEGIN_ALLOW_THREADS
|
2201 | #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
|
2202 | if (mode[0] == 'a') {
|
2203 | /* try to make sure the O_APPEND flag is set */
|
2204 | int flags;
|
2205 | flags = fcntl(fd, F_GETFL);
|
2206 | if (flags != -1)
|
2207 | fcntl(fd, F_SETFL, flags | O_APPEND);
|
2208 | fp = fdopen(fd, mode);
|
2209 | if (fp == NULL && flags != -1)
|
2210 | /* restore old mode if fdopen failed */
|
2211 | fcntl(fd, F_SETFL, flags);
|
2212 | } else {
|
2213 | fp = fdopen(fd, mode);
|
2214 | }
|
2215 | #else
|
2216 | fp = fdopen(fd, mode);
|
2217 | #endif
|
2218 | Py_END_ALLOW_THREADS
|
2219 | PyMem_FREE(mode);
|
2220 | if (fp == NULL) {
|
2221 | Py_DECREF(f);
|
2222 | return posix_error();
|
2223 | }
|
2224 | /* We now know we will succeed, so initialize the file object. */
|
2225 | ((PyFileObject *)f)->f_fp = fp;
|
2226 | PyFile_SetBufSize(f, bufsize);
|
2227 | return f;
|
2228 | }
|
2229 |
|
2230 | PyDoc_STRVAR_remove(posix_isatty__doc__,
|
2231 | "isatty(fd) -> bool\n\n\
|
2232 | Return True if the file descriptor 'fd' is an open file descriptor\n\
|
2233 | connected to the slave end of a terminal.");
|
2234 |
|
2235 | static PyObject *
|
2236 | posix_isatty(PyObject *self, PyObject *args)
|
2237 | {
|
2238 | int fd;
|
2239 | if (!PyArg_ParseTuple(args, "i:isatty", &fd))
|
2240 | return NULL;
|
2241 | if (!_PyVerify_fd(fd))
|
2242 | return PyBool_FromLong(0);
|
2243 | return PyBool_FromLong(isatty(fd));
|
2244 | }
|
2245 |
|
2246 | #ifdef HAVE_PIPE
|
2247 | PyDoc_STRVAR_remove(posix_pipe__doc__,
|
2248 | "pipe() -> (read_end, write_end)\n\n\
|
2249 | Create a pipe.");
|
2250 |
|
2251 | static PyObject *
|
2252 | posix_pipe(PyObject *self, PyObject *noargs)
|
2253 | {
|
2254 | int fds[2];
|
2255 | int res;
|
2256 | Py_BEGIN_ALLOW_THREADS
|
2257 | res = pipe(fds);
|
2258 | Py_END_ALLOW_THREADS
|
2259 | if (res != 0)
|
2260 | return posix_error();
|
2261 | return Py_BuildValue("(ii)", fds[0], fds[1]);
|
2262 | }
|
2263 | #endif /* HAVE_PIPE */
|
2264 |
|
2265 |
|
2266 | #ifdef HAVE_MKFIFO
|
2267 | PyDoc_STRVAR_remove(posix_mkfifo__doc__,
|
2268 | "mkfifo(filename [, mode=0666])\n\n\
|
2269 | Create a FIFO (a POSIX named pipe).");
|
2270 |
|
2271 | static PyObject *
|
2272 | posix_mkfifo(PyObject *self, PyObject *args)
|
2273 | {
|
2274 | char *filename;
|
2275 | int mode = 0666;
|
2276 | int res;
|
2277 | if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
|
2278 | return NULL;
|
2279 | Py_BEGIN_ALLOW_THREADS
|
2280 | res = mkfifo(filename, mode);
|
2281 | Py_END_ALLOW_THREADS
|
2282 | if (res < 0)
|
2283 | return posix_error();
|
2284 | Py_INCREF(Py_None);
|
2285 | return Py_None;
|
2286 | }
|
2287 | #endif
|
2288 |
|
2289 | #ifdef HAVE_PUTENV
|
2290 | PyDoc_STRVAR_remove(posix_putenv__doc__,
|
2291 | "putenv(key, value)\n\n\
|
2292 | Change or add an environment variable.");
|
2293 |
|
2294 | /* Save putenv() parameters as values here, so we can collect them when they
|
2295 | * get re-set with another call for the same key. */
|
2296 | static PyObject *posix_putenv_garbage;
|
2297 |
|
2298 | static PyObject *
|
2299 | posix_putenv(PyObject *self, PyObject *args)
|
2300 | {
|
2301 | char *s1, *s2;
|
2302 | char *newenv;
|
2303 | PyObject *newstr;
|
2304 | size_t len;
|
2305 |
|
2306 | if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
|
2307 | return NULL;
|
2308 |
|
2309 | /* XXX This can leak memory -- not easy to fix :-( */
|
2310 | len = strlen(s1) + strlen(s2) + 2;
|
2311 | /* len includes space for a trailing \0; the size arg to
|
2312 | PyString_FromStringAndSize does not count that */
|
2313 | newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
|
2314 | if (newstr == NULL)
|
2315 | return PyErr_NoMemory();
|
2316 | newenv = PyString_AS_STRING(newstr);
|
2317 | PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
|
2318 | if (putenv(newenv)) {
|
2319 | Py_DECREF(newstr);
|
2320 | posix_error();
|
2321 | return NULL;
|
2322 | }
|
2323 | /* Install the first arg and newstr in posix_putenv_garbage;
|
2324 | * this will cause previous value to be collected. This has to
|
2325 | * happen after the real putenv() call because the old value
|
2326 | * was still accessible until then. */
|
2327 | if (PyDict_SetItem(posix_putenv_garbage,
|
2328 | PyTuple_GET_ITEM(args, 0), newstr)) {
|
2329 | /* really not much we can do; just leak */
|
2330 | PyErr_Clear();
|
2331 | }
|
2332 | else {
|
2333 | Py_DECREF(newstr);
|
2334 | }
|
2335 |
|
2336 | Py_INCREF(Py_None);
|
2337 | return Py_None;
|
2338 | }
|
2339 | #endif /* putenv */
|
2340 |
|
2341 | #ifdef HAVE_UNSETENV
|
2342 | PyDoc_STRVAR_remove(posix_unsetenv__doc__,
|
2343 | "unsetenv(key)\n\n\
|
2344 | Delete an environment variable.");
|
2345 |
|
2346 | static PyObject *
|
2347 | posix_unsetenv(PyObject *self, PyObject *args)
|
2348 | {
|
2349 | char *s1;
|
2350 | #ifndef HAVE_BROKEN_UNSETENV
|
2351 | int err;
|
2352 | #endif
|
2353 |
|
2354 | if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
|
2355 | return NULL;
|
2356 |
|
2357 | #ifdef HAVE_BROKEN_UNSETENV
|
2358 | unsetenv(s1);
|
2359 | #else
|
2360 | err = unsetenv(s1);
|
2361 | if (err)
|
2362 | return posix_error();
|
2363 | #endif
|
2364 |
|
2365 | /* Remove the key from posix_putenv_garbage;
|
2366 | * this will cause it to be collected. This has to
|
2367 | * happen after the real unsetenv() call because the
|
2368 | * old value was still accessible until then.
|
2369 | */
|
2370 | if (PyDict_DelItem(posix_putenv_garbage,
|
2371 | PyTuple_GET_ITEM(args, 0))) {
|
2372 | /* really not much we can do; just leak */
|
2373 | PyErr_Clear();
|
2374 | }
|
2375 |
|
2376 | Py_INCREF(Py_None);
|
2377 | return Py_None;
|
2378 | }
|
2379 | #endif /* unsetenv */
|
2380 |
|
2381 | PyDoc_STRVAR_remove(posix_strerror__doc__,
|
2382 | "strerror(code) -> string\n\n\
|
2383 | Translate an error code to a message string.");
|
2384 |
|
2385 | static PyObject *
|
2386 | posix_strerror(PyObject *self, PyObject *args)
|
2387 | {
|
2388 | int code;
|
2389 | char *message;
|
2390 | if (!PyArg_ParseTuple(args, "i:strerror", &code))
|
2391 | return NULL;
|
2392 | message = strerror(code);
|
2393 | if (message == NULL) {
|
2394 | PyErr_SetString(PyExc_ValueError,
|
2395 | "strerror() argument out of range");
|
2396 | return NULL;
|
2397 | }
|
2398 | return PyString_FromString(message);
|
2399 | }
|
2400 |
|
2401 |
|
2402 | #ifdef HAVE_SYS_WAIT_H
|
2403 |
|
2404 | #ifdef WCOREDUMP
|
2405 | PyDoc_STRVAR_remove(posix_WCOREDUMP__doc__,
|
2406 | "WCOREDUMP(status) -> bool\n\n\
|
2407 | Return True if the process returning 'status' was dumped to a core file.");
|
2408 |
|
2409 | static PyObject *
|
2410 | posix_WCOREDUMP(PyObject *self, PyObject *args)
|
2411 | {
|
2412 | WAIT_TYPE status;
|
2413 | WAIT_STATUS_INT(status) = 0;
|
2414 |
|
2415 | if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
|
2416 | return NULL;
|
2417 |
|
2418 | return PyBool_FromLong(WCOREDUMP(status));
|
2419 | }
|
2420 | #endif /* WCOREDUMP */
|
2421 |
|
2422 | #ifdef WIFCONTINUED
|
2423 | PyDoc_STRVAR_remove(posix_WIFCONTINUED__doc__,
|
2424 | "WIFCONTINUED(status) -> bool\n\n\
|
2425 | Return True if the process returning 'status' was continued from a\n\
|
2426 | job control stop.");
|
2427 |
|
2428 | static PyObject *
|
2429 | posix_WIFCONTINUED(PyObject *self, PyObject *args)
|
2430 | {
|
2431 | WAIT_TYPE status;
|
2432 | WAIT_STATUS_INT(status) = 0;
|
2433 |
|
2434 | if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
|
2435 | return NULL;
|
2436 |
|
2437 | return PyBool_FromLong(WIFCONTINUED(status));
|
2438 | }
|
2439 | #endif /* WIFCONTINUED */
|
2440 |
|
2441 | #ifdef WIFSTOPPED
|
2442 | PyDoc_STRVAR_remove(posix_WIFSTOPPED__doc__,
|
2443 | "WIFSTOPPED(status) -> bool\n\n\
|
2444 | Return True if the process returning 'status' was stopped.");
|
2445 |
|
2446 | static PyObject *
|
2447 | posix_WIFSTOPPED(PyObject *self, PyObject *args)
|
2448 | {
|
2449 | WAIT_TYPE status;
|
2450 | WAIT_STATUS_INT(status) = 0;
|
2451 |
|
2452 | if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
|
2453 | return NULL;
|
2454 |
|
2455 | return PyBool_FromLong(WIFSTOPPED(status));
|
2456 | }
|
2457 | #endif /* WIFSTOPPED */
|
2458 |
|
2459 | #ifdef WIFSIGNALED
|
2460 | PyDoc_STRVAR_remove(posix_WIFSIGNALED__doc__,
|
2461 | "WIFSIGNALED(status) -> bool\n\n\
|
2462 | Return True if the process returning 'status' was terminated by a signal.");
|
2463 |
|
2464 | static PyObject *
|
2465 | posix_WIFSIGNALED(PyObject *self, PyObject *args)
|
2466 | {
|
2467 | WAIT_TYPE status;
|
2468 | WAIT_STATUS_INT(status) = 0;
|
2469 |
|
2470 | if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
|
2471 | return NULL;
|
2472 |
|
2473 | return PyBool_FromLong(WIFSIGNALED(status));
|
2474 | }
|
2475 | #endif /* WIFSIGNALED */
|
2476 |
|
2477 | #ifdef WIFEXITED
|
2478 | PyDoc_STRVAR_remove(posix_WIFEXITED__doc__,
|
2479 | "WIFEXITED(status) -> bool\n\n\
|
2480 | Return true if the process returning 'status' exited using the exit()\n\
|
2481 | system call.");
|
2482 |
|
2483 | static PyObject *
|
2484 | posix_WIFEXITED(PyObject *self, PyObject *args)
|
2485 | {
|
2486 | WAIT_TYPE status;
|
2487 | WAIT_STATUS_INT(status) = 0;
|
2488 |
|
2489 | if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
|
2490 | return NULL;
|
2491 |
|
2492 | return PyBool_FromLong(WIFEXITED(status));
|
2493 | }
|
2494 | #endif /* WIFEXITED */
|
2495 |
|
2496 | #ifdef WEXITSTATUS
|
2497 | PyDoc_STRVAR_remove(posix_WEXITSTATUS__doc__,
|
2498 | "WEXITSTATUS(status) -> integer\n\n\
|
2499 | Return the process return code from 'status'.");
|
2500 |
|
2501 | static PyObject *
|
2502 | posix_WEXITSTATUS(PyObject *self, PyObject *args)
|
2503 | {
|
2504 | WAIT_TYPE status;
|
2505 | WAIT_STATUS_INT(status) = 0;
|
2506 |
|
2507 | if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
|
2508 | return NULL;
|
2509 |
|
2510 | return Py_BuildValue("i", WEXITSTATUS(status));
|
2511 | }
|
2512 | #endif /* WEXITSTATUS */
|
2513 |
|
2514 | #ifdef WTERMSIG
|
2515 | PyDoc_STRVAR_remove(posix_WTERMSIG__doc__,
|
2516 | "WTERMSIG(status) -> integer\n\n\
|
2517 | Return the signal that terminated the process that provided the 'status'\n\
|
2518 | value.");
|
2519 |
|
2520 | static PyObject *
|
2521 | posix_WTERMSIG(PyObject *self, PyObject *args)
|
2522 | {
|
2523 | WAIT_TYPE status;
|
2524 | WAIT_STATUS_INT(status) = 0;
|
2525 |
|
2526 | if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
|
2527 | return NULL;
|
2528 |
|
2529 | return Py_BuildValue("i", WTERMSIG(status));
|
2530 | }
|
2531 | #endif /* WTERMSIG */
|
2532 |
|
2533 | #ifdef WSTOPSIG
|
2534 | PyDoc_STRVAR_remove(posix_WSTOPSIG__doc__,
|
2535 | "WSTOPSIG(status) -> integer\n\n\
|
2536 | Return the signal that stopped the process that provided\n\
|
2537 | the 'status' value.");
|
2538 |
|
2539 | static PyObject *
|
2540 | posix_WSTOPSIG(PyObject *self, PyObject *args)
|
2541 | {
|
2542 | WAIT_TYPE status;
|
2543 | WAIT_STATUS_INT(status) = 0;
|
2544 |
|
2545 | if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
|
2546 | return NULL;
|
2547 |
|
2548 | return Py_BuildValue("i", WSTOPSIG(status));
|
2549 | }
|
2550 | #endif /* WSTOPSIG */
|
2551 |
|
2552 | #endif /* HAVE_SYS_WAIT_H */
|
2553 |
|
2554 | #include "Python-2.7.13/Modules/posixmodule.c/posix_methods.def"
|
2555 |
|
2556 | static int
|
2557 | ins(PyObject *module, char *symbol, long value)
|
2558 | {
|
2559 | return PyModule_AddIntConstant(module, symbol, value);
|
2560 | }
|
2561 |
|
2562 | static int
|
2563 | all_ins(PyObject *d)
|
2564 | {
|
2565 | #ifdef F_OK
|
2566 | if (ins(d, "F_OK", (long)F_OK)) return -1;
|
2567 | #endif
|
2568 | #ifdef R_OK
|
2569 | if (ins(d, "R_OK", (long)R_OK)) return -1;
|
2570 | #endif
|
2571 | #ifdef W_OK
|
2572 | if (ins(d, "W_OK", (long)W_OK)) return -1;
|
2573 | #endif
|
2574 | #ifdef X_OK
|
2575 | if (ins(d, "X_OK", (long)X_OK)) return -1;
|
2576 | #endif
|
2577 | #ifdef NGROUPS_MAX
|
2578 | if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
|
2579 | #endif
|
2580 | #ifdef TMP_MAX
|
2581 | if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
|
2582 | #endif
|
2583 | #ifdef WCONTINUED
|
2584 | if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
|
2585 | #endif
|
2586 | #ifdef WNOHANG
|
2587 | if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
|
2588 | #endif
|
2589 | #ifdef WUNTRACED
|
2590 | if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
|
2591 | #endif
|
2592 | #ifdef O_RDONLY
|
2593 | if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
|
2594 | #endif
|
2595 | #ifdef O_WRONLY
|
2596 | if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
|
2597 | #endif
|
2598 | #ifdef O_RDWR
|
2599 | if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
|
2600 | #endif
|
2601 | #ifdef O_NDELAY
|
2602 | if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
|
2603 | #endif
|
2604 | #ifdef O_NONBLOCK
|
2605 | if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
|
2606 | #endif
|
2607 | #ifdef O_APPEND
|
2608 | if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
|
2609 | #endif
|
2610 | #ifdef O_DSYNC
|
2611 | if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
|
2612 | #endif
|
2613 | #ifdef O_RSYNC
|
2614 | if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
|
2615 | #endif
|
2616 | #ifdef O_SYNC
|
2617 | if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
|
2618 | #endif
|
2619 | #ifdef O_NOCTTY
|
2620 | if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
|
2621 | #endif
|
2622 | #ifdef O_CREAT
|
2623 | if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
|
2624 | #endif
|
2625 | #ifdef O_EXCL
|
2626 | if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
|
2627 | #endif
|
2628 | #ifdef O_TRUNC
|
2629 | if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
|
2630 | #endif
|
2631 | #ifdef O_BINARY
|
2632 | if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
|
2633 | #endif
|
2634 | #ifdef O_TEXT
|
2635 | if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
|
2636 | #endif
|
2637 | #ifdef O_LARGEFILE
|
2638 | if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
|
2639 | #endif
|
2640 | #ifdef O_SHLOCK
|
2641 | if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
|
2642 | #endif
|
2643 | #ifdef O_EXLOCK
|
2644 | if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
|
2645 | #endif
|
2646 |
|
2647 | return 0;
|
2648 | }
|
2649 |
|
2650 | #define INITFUNC initposix_
|
2651 | #define MODNAME "posix_"
|
2652 |
|
2653 | PyMODINIT_FUNC
|
2654 | INITFUNC(void)
|
2655 | {
|
2656 | PyObject *m, *v;
|
2657 |
|
2658 | m = Py_InitModule3(MODNAME,
|
2659 | posix_methods,
|
2660 | posix__doc__);
|
2661 | if (m == NULL)
|
2662 | return;
|
2663 |
|
2664 | /* Initialize environ dictionary */
|
2665 | v = convertenviron();
|
2666 | Py_XINCREF(v);
|
2667 | if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
|
2668 | return;
|
2669 | Py_DECREF(v);
|
2670 |
|
2671 | if (all_ins(m))
|
2672 | return;
|
2673 |
|
2674 | /* OVM_MAIN: We might want to redefine OSError as IOError like Python 3 ?
|
2675 | * */
|
2676 | Py_INCREF(PyExc_OSError);
|
2677 | PyModule_AddObject(m, "error", PyExc_OSError);
|
2678 |
|
2679 | #ifdef HAVE_PUTENV
|
2680 | if (posix_putenv_garbage == NULL)
|
2681 | posix_putenv_garbage = PyDict_New();
|
2682 | #endif
|
2683 |
|
2684 | if (!initialized) {
|
2685 | stat_result_desc.name = MODNAME ".stat_result";
|
2686 | stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
|
2687 | stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
|
2688 | stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
|
2689 | PyStructSequence_InitType(&StatResultType, &stat_result_desc);
|
2690 | structseq_new = StatResultType.tp_new;
|
2691 | StatResultType.tp_new = statresult_new;
|
2692 |
|
2693 | #ifdef NEED_TICKS_PER_SECOND
|
2694 | # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
|
2695 | ticks_per_second = sysconf(_SC_CLK_TCK);
|
2696 | # elif defined(HZ)
|
2697 | ticks_per_second = HZ;
|
2698 | # else
|
2699 | ticks_per_second = 60; /* magic fallback value; may be bogus */
|
2700 | # endif
|
2701 | #endif
|
2702 | }
|
2703 | Py_INCREF((PyObject*) &StatResultType);
|
2704 | PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
|
2705 | initialized = 1;
|
2706 | }
|
2707 |
|
2708 | #ifdef __cplusplus
|
2709 | }
|
2710 | #endif
|