]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/edk2module.c
AppPkg/.../Python-2.7.10: Remove irrelevant conditional code from edk2module.c.
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / PyMod-2.7.10 / Modules / edk2module.c
CommitLineData
3ec97ca4
DM
1/** @file\r
2 OS-specific module implementation for EDK II and UEFI.\r
3 Derived from posixmodule.c in Python 2.7.2.\r
4\r
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
25extern "C" {\r
26#endif\r
27\r
28PyDoc_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
160extern char **environ;\r
161\r
162static PyObject *\r
163convertenviron(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
203static PyObject *\r
204posix_error(void)\r
205{\r
206 return PyErr_SetFromErrno(PyExc_OSError);\r
207}\r
208static PyObject *\r
209posix_error_with_filename(char* name)\r
210{\r
211 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);\r
212}\r
213\r
214\r
215static PyObject *\r
216posix_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
246static PyObject *\r
247posix_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
264static PyObject *\r
265posix_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
287PyDoc_STRVAR(stat_result__doc__,\r
288"stat_result: Result from stat or lstat.\n\n\\r
289This object may be accessed either as a tuple of\n\\r
290 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\\r
291or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\\r
292\n\\r
293Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\\r
294or st_flags, they are available as attributes only.\n\\r
295\n\\r
296See os.stat for more information.");\r
297\r
298static 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
370static 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
378PyDoc_STRVAR(statvfs_result__doc__,\r
379"statvfs_result: Result from statvfs or fstatvfs.\n\n\\r
380This object may be accessed either as a tuple of\n\\r
381 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\\r
382or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\\r
383\n\\r
384See os.statvfs for more information.");\r
385\r
386static 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
400static 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
407static PyTypeObject StatVFSResultType;\r
408#endif\r
409\r
410static int initialized;\r
411static PyTypeObject StatResultType;\r
412static newfunc structseq_new;\r
413\r
414static PyObject *\r
415statresult_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
444PyDoc_STRVAR(stat_float_times__doc__,\r
445"stat_float_times([newval]) -> oldval\n\n\\r
446Determine whether os.[lf]stat represents time stamps as float objects.\n\\r
447If newval is True, future calls to stat() return floats, if it is False,\n\\r
448future calls return ints. \n\\r
449If newval is omitted, return the current setting.\n");\r
450\r
451static PyObject*\r
452stat_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
467static void\r
468fill_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
490static 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
558static PyObject *\r
559posix_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
592PyDoc_STRVAR(posix_access__doc__,\r
593"access(path, mode) -> True if granted, False otherwise\n\n\\r
594Use the real uid/gid to test for access to a path. Note that most\n\\r
595operations will use the effective uid/gid, therefore this routine can\n\\r
596be used in a suid/sgid environment to test if the invoking user has the\n\\r
597specified access to the path. The mode argument can be F_OK to test\n\\r
598existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");\r
599\r
600static PyObject *\r
601posix_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
630PyDoc_STRVAR(posix_chdir__doc__,\r
631"chdir(path)\n\n\\r
632Change the current working directory to the specified path.");\r
633\r
634static PyObject *\r
635posix_chdir(PyObject *self, PyObject *args)\r
636{\r
637 return posix_1str(args, "et:chdir", chdir);\r
638}\r
639\r
640PyDoc_STRVAR(posix_chmod__doc__,\r
641"chmod(path, mode)\n\n\\r
642Change the access permissions of a file.");\r
643\r
644static PyObject *\r
645posix_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
664PyDoc_STRVAR(posix_fchmod__doc__,\r
665"fchmod(fd, mode)\n\n\\r
666Change the access permissions of the file given by file\n\\r
667descriptor fd.");\r
668\r
669static PyObject *\r
670posix_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
685PyDoc_STRVAR(posix_lchmod__doc__,\r
686"lchmod(path, mode)\n\n\\r
687Change the access permissions of a file. If path is a symlink, this\n\\r
688affects the link itself rather than the target.");\r
689\r
690static PyObject *\r
691posix_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
711PyDoc_STRVAR(posix_chflags__doc__,\r
712"chflags(path, flags)\n\n\\r
713Set file flags.");\r
714\r
715static PyObject *\r
716posix_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
736PyDoc_STRVAR(posix_lchflags__doc__,\r
737"lchflags(path, flags)\n\n\\r
738Set file flags.\n\\r
739This function will not follow symbolic links.");\r
740\r
741static PyObject *\r
742posix_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
762PyDoc_STRVAR(posix_chroot__doc__,\r
763"chroot(path)\n\n\\r
764Change root directory to path.");\r
765\r
766static PyObject *\r
767posix_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
774PyDoc_STRVAR(posix_fsync__doc__,\r
775"fsync(fildes)\n\n\\r
776force write of file with filedescriptor to disk.");\r
777\r
778static PyObject *\r
779posix_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
788extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */\r
789#endif\r
790\r
791PyDoc_STRVAR(posix_fdatasync__doc__,\r
792"fdatasync(fildes)\n\n\\r
793force write of file with filedescriptor to disk.\n\\r
794 does not force update of metadata.");\r
795\r
796static PyObject *\r
797posix_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
805PyDoc_STRVAR(posix_chown__doc__,\r
806"chown(path, uid, gid)\n\n\\r
807Change the owner and group id of path to the numeric uid and gid.");\r
808\r
809static PyObject *\r
810posix_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
831PyDoc_STRVAR(posix_fchown__doc__,\r
832"fchown(fd, uid, gid)\n\n\\r
833Change the owner and group id of the file given by file descriptor\n\\r
834fd to the numeric uid and gid.");\r
835\r
836static PyObject *\r
837posix_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
854PyDoc_STRVAR(posix_lchown__doc__,\r
855"lchown(path, uid, gid)\n\n\\r
856Change the owner and group id of path to the numeric uid and gid.\n\\r
857This function will not follow symbolic links.");\r
858\r
859static PyObject *\r
860posix_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
882PyDoc_STRVAR(posix_getcwd__doc__,\r
883"getcwd() -> path\n\n\\r
884Return a string representing the current working directory.");\r
885\r
886static PyObject *\r
887posix_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
919PyDoc_STRVAR(posix_getcwdu__doc__,\r
920"getcwdu() -> path\n\n\\r
921Return a unicode string representing the current working directory.");\r
922\r
923static PyObject *\r
924posix_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
940PyDoc_STRVAR(posix_listdir__doc__,\r
941"listdir(path) -> list_of_strings\n\n\\r
942Return 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
946The list is in arbitrary order. It does not include the special\n\\r
947entries '.' and '..' even if they are present in the directory.");\r
948\r
949static PyObject *\r
950posix_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
1063PyDoc_STRVAR(posix_mkdir__doc__,\r
1064"mkdir(path [, mode=0777])\n\n\\r
1065Create a directory.");\r
1066\r
1067static PyObject *\r
1068posix_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
1095PyDoc_STRVAR(posix_nice__doc__,\r
1096"nice(inc) -> new_priority\n\n\\r
1097Decrease the priority of process by inc and return the new priority.");\r
1098\r
1099static PyObject *\r
1100posix_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
1130PyDoc_STRVAR(posix_rename__doc__,\r
1131"rename(old, new)\n\n\\r
1132Rename a file or directory.");\r
1133\r
1134static PyObject *\r
1135posix_rename(PyObject *self, PyObject *args)\r
1136{\r
1137 return posix_2str(args, "etet:rename", rename);\r
1138}\r
1139\r
1140\r
1141PyDoc_STRVAR(posix_rmdir__doc__,\r
1142"rmdir(path)\n\n\\r
1143Remove a directory.");\r
1144\r
1145static PyObject *\r
1146posix_rmdir(PyObject *self, PyObject *args)\r
1147{\r
1148 return posix_1str(args, "et:rmdir", rmdir);\r
1149}\r
1150\r
1151\r
1152PyDoc_STRVAR(posix_stat__doc__,\r
1153"stat(path) -> stat result\n\n\\r
1154Perform a stat system call on the given path.");\r
1155\r
1156static PyObject *\r
1157posix_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
1164PyDoc_STRVAR(posix_system__doc__,\r
1165"system(command) -> exit_status\n\n\\r
1166Execute the command (a string) in a subshell.");\r
1167\r
1168static PyObject *\r
1169posix_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
1183PyDoc_STRVAR(posix_umask__doc__,\r
1184"umask(new_mask) -> old_mask\n\n\\r
1185Set the current numeric umask and return the previous umask.");\r
1186\r
1187static PyObject *\r
1188posix_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
1200PyDoc_STRVAR(posix_unlink__doc__,\r
1201"unlink(path)\n\n\\r
1202Remove a file (same as remove(path)).");\r
1203\r
1204PyDoc_STRVAR(posix_remove__doc__,\r
1205"remove(path)\n\n\\r
1206Remove a file (same as unlink(path)).");\r
1207\r
1208static PyObject *\r
1209posix_unlink(PyObject *self, PyObject *args)\r
1210{\r
1211 return posix_1str(args, "et:remove", unlink);\r
1212}\r
1213\r
1214\r
1215static int\r
1216extract_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
1252PyDoc_STRVAR(posix_utime__doc__,\r
1253"utime(path, (atime, mtime))\n\\r
1254utime(path, None)\n\n\\r
1255Set the access and modified time of the file to the given values. If the\n\\r
1256second form is used, set the access and modified times to the current time.");\r
1257\r
1258static PyObject *\r
1259posix_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
1339PyDoc_STRVAR(posix__exit__doc__,\r
1340"_exit(status)\n\n\\r
1341Exit to the system with specified status, without normal exit processing.");\r
1342\r
1343static PyObject *\r
1344posix__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
1354static void\r
1355free_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
1366PyDoc_STRVAR(posix_execv__doc__,\r
1367"execv(path, args)\n\n\\r
1368Execute 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
1373static PyObject *\r
1374posix_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
1437PyDoc_STRVAR(posix_execve__doc__,\r
1438"execve(path, args, env)\n\n\\r
1439Execute 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
1445static PyObject *\r
1446posix_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
1582PyDoc_STRVAR(posix_spawnv__doc__,\r
1583"spawnv(mode, path, args)\n\n\\r
1584Execute 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
1590static PyObject *\r
1591posix_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
1669PyDoc_STRVAR(posix_spawnve__doc__,\r
1670"spawnve(mode, path, args, env)\n\n\\r
1671Execute 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
1678static PyObject *\r
1679posix_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
1824PyDoc_STRVAR(posix_spawnvp__doc__,\r
1825"spawnvp(mode, file, args)\n\n\\r
1826Execute the program 'file' in a new process, using the environment\n\\r
1827search 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
1833static PyObject *\r
1834posix_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
1902PyDoc_STRVAR(posix_spawnvpe__doc__,\r
1903"spawnvpe(mode, file, args, env)\n\n\\r
1904Execute the program 'file' in a new process, using the environment\n\\r
1905search 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
1912static PyObject *\r
1913posix_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
2050PyDoc_STRVAR(posix_fork1__doc__,\r
2051"fork1() -> pid\n\n\\r
2052Fork a child process with a single multiplexed (i.e., not bound) thread.\n\\r
2053\n\\r
2054Return 0 to child process and PID of child to parent process.");\r
2055\r
2056static PyObject *\r
2057posix_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
2084PyDoc_STRVAR(posix_fork__doc__,\r
2085"fork() -> pid\n\n\\r
2086Fork a child process.\n\\r
2087Return 0 to child process and PID of child to parent process.");\r
2088\r
2089static PyObject *\r
2090posix_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
2142PyDoc_STRVAR(posix_openpty__doc__,\r
2143"openpty() -> (master_fd, slave_fd)\n\n\\r
2144Open a pseudo-terminal, returning open fd's for both master and slave end.\n");\r
2145\r
2146static PyObject *\r
2147posix_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
2208PyDoc_STRVAR(posix_forkpty__doc__,\r
2209"forkpty() -> (pid, master_fd)\n\n\\r
2210Fork a new process with a new pseudo-terminal as controlling tty.\n\n\\r
2211Like fork(), return 0 as pid to child process, and PID of child to parent.\n\\r
2212To both, return fd of newly opened pseudo-terminal.\n");\r
2213\r
2214static PyObject *\r
2215posix_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
2241PyDoc_STRVAR(posix_getpid__doc__,\r
2242"getpid() -> pid\n\n\\r
2243Return the current process id");\r
2244\r
2245static PyObject *\r
2246posix_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
2252PyDoc_STRVAR(posix_getlogin__doc__,\r
2253"getlogin() -> string\n\n\\r
2254Return the actual login name.");\r
2255\r
2256static PyObject *\r
2257posix_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
2281PyDoc_STRVAR(posix_kill__doc__,\r
2282"kill(pid, sig)\n\n\\r
2283Kill a process with a signal.");\r
2284\r
2285static PyObject *\r
2286posix_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
2320PyDoc_STRVAR(posix_plock__doc__,\r
2321"plock(op)\n\n\\r
2322Lock program segments into memory.");\r
2323\r
2324static PyObject *\r
2325posix_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
2339PyDoc_STRVAR(posix_popen__doc__,\r
2340"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\\r
2341Open a pipe to/from a command returning a file object.");\r
2342\r
3ec97ca4
DM
2343/* standard posix version of popen() support */\r
2344static PyObject *\r
2345posix_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 2373static PyObject *\r
173523c2 2374wait_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
2433PyDoc_STRVAR(posix_wait3__doc__,\r
2434"wait3(options) -> (pid, status, rusage)\n\n\\r
2435Wait for completion of a child process.");\r
3ec97ca4
DM
2436\r
2437static PyObject *\r
173523c2 2438posix_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
2458PyDoc_STRVAR(posix_wait4__doc__,\r
2459"wait4(pid, options) -> (pid, status, rusage)\n\n\\r
2460Wait for completion of a given child process.");\r
3ec97ca4
DM
2461\r
2462static PyObject *\r
173523c2 2463posix_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
2483PyDoc_STRVAR(posix_waitpid__doc__,\r
2484"waitpid(pid, options) -> (pid, status)\n\n\\r
2485Wait for completion of a given child process.");\r
3ec97ca4
DM
2486\r
2487static PyObject *\r
173523c2 2488posix_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
2509PyDoc_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
2513static PyObject *\r
2514posix_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
2533PyDoc_STRVAR(posix_wait__doc__,\r
2534"wait() -> (pid, status)\n\n\\r
2535Wait for completion of a child process.");\r
3ec97ca4 2536\r
173523c2
DM
2537static PyObject *\r
2538posix_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
2555PyDoc_STRVAR(posix_lstat__doc__,\r
2556"lstat(path) -> stat result\n\n\\r
2557Like stat(path), but do not follow symbolic links.");\r
3ec97ca4 2558\r
173523c2
DM
2559static PyObject *\r
2560posix_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
2571PyDoc_STRVAR(posix_readlink__doc__,\r
2572"readlink(path) -> path\n\n\\r
2573Return a string representing the path to which the symbolic link points.");\r
3ec97ca4 2574\r
173523c2
DM
2575static PyObject *\r
2576posix_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
2634PyDoc_STRVAR(posix_symlink__doc__,\r
2635"symlink(src, dst)\n\n\\r
2636Create a symbolic link pointing to src named dst.");\r
3ec97ca4
DM
2637\r
2638static PyObject *\r
173523c2 2639posix_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
2648static long ticks_per_second = -1;\r
3ec97ca4 2649static PyObject *\r
173523c2 2650posix_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
2669PyDoc_STRVAR(posix_times__doc__,\r
2670"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\\r
2671Return 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
2676PyDoc_STRVAR(posix_getsid__doc__,\r
2677"getsid(pid) -> sid\n\n\\r
2678Call the system call getsid().");\r
3ec97ca4
DM
2679\r
2680static PyObject *\r
173523c2 2681posix_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
2696PyDoc_STRVAR(posix_setsid__doc__,\r
2697"setsid()\n\n\\r
2698Call the system call setsid().");\r
3ec97ca4 2699\r
173523c2
DM
2700static PyObject *\r
2701posix_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
2711PyDoc_STRVAR(posix_setpgid__doc__,\r
2712"setpgid(pid, pgrp)\n\n\\r
2713Call the system call setpgid().");\r
3ec97ca4
DM
2714\r
2715static PyObject *\r
173523c2 2716posix_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
2731PyDoc_STRVAR(posix_tcgetpgrp__doc__,\r
2732"tcgetpgrp(fd) -> pgid\n\n\\r
2733Return the process group associated with the terminal given by a fd.");\r
3ec97ca4
DM
2734\r
2735static PyObject *\r
173523c2 2736posix_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
2751PyDoc_STRVAR(posix_tcsetpgrp__doc__,\r
2752"tcsetpgrp(fd, pgid)\n\n\\r
2753Set the process group associated with the terminal given by a fd.");\r
3ec97ca4 2754\r
173523c2
DM
2755static PyObject *\r
2756posix_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
2771PyDoc_STRVAR(posix_open__doc__,\r
2772"open(filename, flag [, mode=0777]) -> fd\n\n\\r
2773Open a file (for low level IO).");\r
3ec97ca4 2774\r
3ec97ca4 2775static PyObject *\r
173523c2 2776posix_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
2798PyDoc_STRVAR(posix_close__doc__,\r
2799"close(fd)\n\n\\r
2800Close a file descriptor (for low level IO).");\r
3ec97ca4
DM
2801\r
2802static PyObject *\r
173523c2 2803posix_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
2820PyDoc_STRVAR(posix_closerange__doc__,\r
2821"closerange(fd_low, fd_high)\n\n\\r
2822Closes all file descriptors in [fd_low, fd_high), ignoring errors.");\r
3ec97ca4
DM
2823\r
2824static PyObject *\r
173523c2 2825posix_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
2839PyDoc_STRVAR(posix_dup__doc__,\r
2840"dup(fd) -> fd2\n\n\\r
2841Return a duplicate of a file descriptor.");\r
3ec97ca4
DM
2842\r
2843static PyObject *\r
173523c2 2844posix_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
2860PyDoc_STRVAR(posix_dup2__doc__,\r
2861"dup2(old_fd, new_fd)\n\n\\r
2862Duplicate file descriptor.");\r
3ec97ca4
DM
2863\r
2864static PyObject *\r
173523c2 2865posix_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
2882PyDoc_STRVAR(posix_lseek__doc__,\r
2883"lseek(fd, pos, how) -> newpos\n\n\\r
2884Set the current position of a file descriptor.");\r
3ec97ca4
DM
2885\r
2886static PyObject *\r
173523c2 2887posix_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
2928PyDoc_STRVAR(posix_read__doc__,\r
2929"read(fd, buffersize) -> string\n\n\\r
2930Read a file descriptor.");\r
3ec97ca4
DM
2931\r
2932static PyObject *\r
173523c2 2933posix_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
2963PyDoc_STRVAR(posix_write__doc__,\r
2964"write(fd, string) -> byteswritten\n\n\\r
2965Write a string to a file descriptor.");\r
3ec97ca4
DM
2966\r
2967static PyObject *\r
173523c2 2968posix_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
2990PyDoc_STRVAR(posix_fstat__doc__,\r
2991"fstat(fd) -> stat result\n\n\\r
2992Like stat(), but for an open file descriptor.");\r
3ec97ca4
DM
2993\r
2994static PyObject *\r
173523c2 2995posix_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
3015PyDoc_STRVAR(posix_fdopen__doc__,\r
3016"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\\r
3017Return an open file object connected to a file descriptor.");\r
3ec97ca4
DM
3018\r
3019static PyObject *\r
173523c2 3020posix_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
3072PyDoc_STRVAR(posix_isatty__doc__,\r
3073"isatty(fd) -> bool\n\n\\r
3074Return True if the file descriptor 'fd' is an open file descriptor\n\\r
3075connected to the slave end of a terminal.");\r
3ec97ca4
DM
3076\r
3077static PyObject *\r
173523c2 3078posix_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
3089PyDoc_STRVAR(posix_pipe__doc__,\r
3090"pipe() -> (read_end, write_end)\n\n\\r
3091Create a pipe.");\r
3ec97ca4 3092\r
173523c2
DM
3093static PyObject *\r
3094posix_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
3109PyDoc_STRVAR(posix_mkfifo__doc__,\r
3110"mkfifo(filename [, mode=0666])\n\n\\r
3111Create a FIFO (a POSIX named pipe).");\r
3ec97ca4
DM
3112\r
3113static PyObject *\r
173523c2 3114posix_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
3133PyDoc_STRVAR(posix_mknod__doc__,\r
3134"mknod(filename [, mode=0600, device])\n\n\\r
3135Create a filesystem node (file, device special file or named pipe)\n\\r
3136named filename. mode specifies both the permissions to use and the\n\\r
3137type of node to be created, being combined (bitwise OR) with one of\n\\r
3138S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\\r
3139device defines the newly created device special file (probably using\n\\r
3140os.makedev()), otherwise it is ignored.");\r
3141\r
3ec97ca4
DM
3142\r
3143static PyObject *\r
173523c2 3144posix_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
3163PyDoc_STRVAR(posix_major__doc__,\r
3164"major(device) -> major number\n\\r
3165Extracts a device major number from a raw device number.");\r
3ec97ca4
DM
3166\r
3167static PyObject *\r
173523c2 3168posix_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
3176PyDoc_STRVAR(posix_minor__doc__,\r
3177"minor(device) -> minor number\n\\r
3178Extracts a device minor number from a raw device number.");\r
3ec97ca4
DM
3179\r
3180static PyObject *\r
173523c2 3181posix_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
3189PyDoc_STRVAR(posix_makedev__doc__,\r
3190"makedev(major, minor) -> device number\n\\r
3191Composes a raw device number from the major and minor device numbers.");\r
3192\r
3ec97ca4 3193static PyObject *\r
173523c2 3194posix_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
3205PyDoc_STRVAR(posix_ftruncate__doc__,\r
3206"ftruncate(fd, length)\n\n\\r
3207Truncate a file to a specified length.");\r
3ec97ca4
DM
3208\r
3209static PyObject *\r
173523c2 3210posix_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
3240PyDoc_STRVAR(posix_putenv__doc__,\r
3241"putenv(key, value)\n\n\\r
3242Change 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
3246static PyObject *posix_putenv_garbage;\r
3ec97ca4
DM
3247\r
3248static PyObject *\r
173523c2 3249posix_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
3292PyDoc_STRVAR(posix_unsetenv__doc__,\r
3293"unsetenv(key)\n\n\\r
3294Delete an environment variable.");\r
3ec97ca4
DM
3295\r
3296static PyObject *\r
173523c2 3297posix_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
3322PyDoc_STRVAR(posix_strerror__doc__,\r
3323"strerror(code) -> string\n\n\\r
3324Translate an error code to a message string.");\r
3ec97ca4
DM
3325\r
3326static PyObject *\r
173523c2 3327posix_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
3346PyDoc_STRVAR(posix_WCOREDUMP__doc__,\r
3347"WCOREDUMP(status) -> bool\n\n\\r
3348Return True if the process returning 'status' was dumped to a core file.");\r
3ec97ca4
DM
3349\r
3350static PyObject *\r
173523c2 3351posix_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
3364PyDoc_STRVAR(posix_WIFCONTINUED__doc__,\r
3365"WIFCONTINUED(status) -> bool\n\n\\r
3366Return True if the process returning 'status' was continued from a\n\\r
3367job control stop.");\r
3ec97ca4
DM
3368\r
3369static PyObject *\r
173523c2 3370posix_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
3383PyDoc_STRVAR(posix_WIFSTOPPED__doc__,\r
3384"WIFSTOPPED(status) -> bool\n\n\\r
3385Return True if the process returning 'status' was stopped.");\r
3ec97ca4
DM
3386\r
3387static PyObject *\r
173523c2 3388posix_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
3401PyDoc_STRVAR(posix_WIFSIGNALED__doc__,\r
3402"WIFSIGNALED(status) -> bool\n\n\\r
3403Return True if the process returning 'status' was terminated by a signal.");\r
3ec97ca4
DM
3404\r
3405static PyObject *\r
173523c2 3406posix_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
3419PyDoc_STRVAR(posix_WIFEXITED__doc__,\r
3420"WIFEXITED(status) -> bool\n\n\\r
3421Return true if the process returning 'status' exited using the exit()\n\\r
3422system call.");\r
3ec97ca4
DM
3423\r
3424static PyObject *\r
173523c2 3425posix_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
3438PyDoc_STRVAR(posix_WEXITSTATUS__doc__,\r
3439"WEXITSTATUS(status) -> integer\n\n\\r
3440Return the process return code from 'status'.");\r
3ec97ca4
DM
3441\r
3442static PyObject *\r
173523c2 3443posix_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
3456PyDoc_STRVAR(posix_WTERMSIG__doc__,\r
3457"WTERMSIG(status) -> integer\n\n\\r
3458Return the signal that terminated the process that provided the 'status'\n\\r
3459value.");\r
3460\r
3461static PyObject *\r
3462posix_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
3475PyDoc_STRVAR(posix_WSTOPSIG__doc__,\r
3476"WSTOPSIG(status) -> integer\n\n\\r
3477Return the signal that stopped the process that provided\n\\r
3478the 'status' value.");\r
3ec97ca4
DM
3479\r
3480static PyObject *\r
173523c2 3481posix_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
3499static 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
3538PyDoc_STRVAR(posix_fstatvfs__doc__,\r
3539"fstatvfs(fd) -> statvfs result\n\n\\r
3540Perform an fstatvfs system call on the given fd.");\r
3541\r
3542static PyObject *\r
3543posix_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
3564PyDoc_STRVAR(posix_statvfs__doc__,\r
3565"statvfs(path) -> statvfs result\n\n\\r
3566Perform a statvfs system call on the given path.");\r
3567\r
3568static PyObject *\r
3569posix_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
3588PyDoc_STRVAR(posix_tempnam__doc__,\r
3589"tempnam([dir[, prefix]]) -> string\n\n\\r
3590Return a unique name for a temporary file.\n\\r
3591The directory and a prefix may be specified as strings; they may be omitted\n\\r
3592or None if not needed.");\r
3ec97ca4
DM
3593\r
3594static PyObject *\r
173523c2 3595posix_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
3624PyDoc_STRVAR(posix_tmpfile__doc__,\r
3625"tmpfile() -> file object\n\n\\r
3626Create a temporary file with no directory entries.");\r
3627\r
3628static PyObject *\r
3629posix_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
3646PyDoc_STRVAR(posix_tmpnam__doc__,\r
3647"tmpnam() -> string\n\n\\r
3648Return a unique name for a temporary file.");\r
3649\r
3650static PyObject *\r
3651posix_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
3685PyDoc_STRVAR(posix_abort__doc__,\r
3686"abort() -> does not return!\n\n\\r
3687Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\\r
3688in the hardest way possible on the hosting operating system.");\r
3ec97ca4 3689\r
173523c2
DM
3690static PyObject *\r
3691posix_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
3699static 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
3960static int\r
3961ins(PyObject *module, char *symbol, long value)\r
3962{\r
3963 return PyModule_AddIntConstant(module, symbol, value);\r
3964}\r
3965\r
3966static int\r
3967all_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
4163PyMODINIT_FUNC\r
4164INITFUNC(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