]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/edk2module.c
AppPkg/Applications/Python/Python-2.7.10: Initial Checkin part 5/5.
[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
1063#ifdef MS_WINDOWS\r
1064/* A helper function for abspath on win32 */\r
1065static PyObject *\r
1066posix__getfullpathname(PyObject *self, PyObject *args)\r
1067{\r
1068 /* assume encoded strings won't more than double no of chars */\r
1069 char inbuf[MAX_PATH*2];\r
1070 char *inbufp = inbuf;\r
1071 Py_ssize_t insize = sizeof(inbuf);\r
1072 char outbuf[MAX_PATH*2];\r
1073 char *temp;\r
1074\r
1075 PyUnicodeObject *po;\r
1076 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {\r
1077 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);\r
1078 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;\r
1079 Py_UNICODE *wtemp;\r
1080 DWORD result;\r
1081 PyObject *v;\r
1082 result = GetFullPathNameW(wpath,\r
1083 sizeof(woutbuf)/sizeof(woutbuf[0]),\r
1084 woutbuf, &wtemp);\r
1085 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {\r
1086 woutbufp = malloc(result * sizeof(Py_UNICODE));\r
1087 if (!woutbufp)\r
1088 return PyErr_NoMemory();\r
1089 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);\r
1090 }\r
1091 if (result)\r
1092 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));\r
1093 else\r
1094 v = win32_error_unicode("GetFullPathNameW", wpath);\r
1095 if (woutbufp != woutbuf)\r
1096 free(woutbufp);\r
1097 return v;\r
1098 }\r
1099 /* Drop the argument parsing error as narrow strings\r
1100 are also valid. */\r
1101 PyErr_Clear();\r
1102\r
1103 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",\r
1104 Py_FileSystemDefaultEncoding, &inbufp,\r
1105 &insize))\r
1106 return NULL;\r
1107 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),\r
1108 outbuf, &temp))\r
1109 return win32_error("GetFullPathName", inbuf);\r
1110 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {\r
1111 return PyUnicode_Decode(outbuf, strlen(outbuf),\r
1112 Py_FileSystemDefaultEncoding, NULL);\r
1113 }\r
1114 return PyString_FromString(outbuf);\r
1115} /* end of posix__getfullpathname */\r
1116#endif /* MS_WINDOWS */\r
1117\r
1118PyDoc_STRVAR(posix_mkdir__doc__,\r
1119"mkdir(path [, mode=0777])\n\n\\r
1120Create a directory.");\r
1121\r
1122static PyObject *\r
1123posix_mkdir(PyObject *self, PyObject *args)\r
1124{\r
1125 int res;\r
1126 char *path = NULL;\r
1127 int mode = 0777;\r
1128\r
1129 if (!PyArg_ParseTuple(args, "et|i:mkdir",\r
1130 Py_FileSystemDefaultEncoding, &path, &mode))\r
1131 return NULL;\r
1132 Py_BEGIN_ALLOW_THREADS\r
1133 res = mkdir(path, mode);\r
1134 Py_END_ALLOW_THREADS\r
1135 if (res < 0)\r
1136 return posix_error_with_allocated_filename(path);\r
1137 PyMem_Free(path);\r
1138 Py_INCREF(Py_None);\r
1139 return Py_None;\r
1140}\r
1141\r
1142\r
1143/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */\r
1144#if defined(HAVE_SYS_RESOURCE_H)\r
1145#include <sys/resource.h>\r
1146#endif\r
1147\r
1148\r
1149#ifdef HAVE_NICE\r
1150PyDoc_STRVAR(posix_nice__doc__,\r
1151"nice(inc) -> new_priority\n\n\\r
1152Decrease the priority of process by inc and return the new priority.");\r
1153\r
1154static PyObject *\r
1155posix_nice(PyObject *self, PyObject *args)\r
1156{\r
1157 int increment, value;\r
1158\r
1159 if (!PyArg_ParseTuple(args, "i:nice", &increment))\r
1160 return NULL;\r
1161\r
1162 /* There are two flavours of 'nice': one that returns the new\r
1163 priority (as required by almost all standards out there) and the\r
1164 Linux/FreeBSD/BSDI one, which returns '0' on success and advices\r
1165 the use of getpriority() to get the new priority.\r
1166\r
1167 If we are of the nice family that returns the new priority, we\r
1168 need to clear errno before the call, and check if errno is filled\r
1169 before calling posix_error() on a returnvalue of -1, because the\r
1170 -1 may be the actual new priority! */\r
1171\r
1172 errno = 0;\r
1173 value = nice(increment);\r
1174#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)\r
1175 if (value == 0)\r
1176 value = getpriority(PRIO_PROCESS, 0);\r
1177#endif\r
1178 if (value == -1 && errno != 0)\r
1179 /* either nice() or getpriority() returned an error */\r
1180 return posix_error();\r
1181 return PyInt_FromLong((long) value);\r
1182}\r
1183#endif /* HAVE_NICE */\r
1184\r
1185PyDoc_STRVAR(posix_rename__doc__,\r
1186"rename(old, new)\n\n\\r
1187Rename a file or directory.");\r
1188\r
1189static PyObject *\r
1190posix_rename(PyObject *self, PyObject *args)\r
1191{\r
1192 return posix_2str(args, "etet:rename", rename);\r
1193}\r
1194\r
1195\r
1196PyDoc_STRVAR(posix_rmdir__doc__,\r
1197"rmdir(path)\n\n\\r
1198Remove a directory.");\r
1199\r
1200static PyObject *\r
1201posix_rmdir(PyObject *self, PyObject *args)\r
1202{\r
1203 return posix_1str(args, "et:rmdir", rmdir);\r
1204}\r
1205\r
1206\r
1207PyDoc_STRVAR(posix_stat__doc__,\r
1208"stat(path) -> stat result\n\n\\r
1209Perform a stat system call on the given path.");\r
1210\r
1211static PyObject *\r
1212posix_stat(PyObject *self, PyObject *args)\r
1213{\r
1214 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);\r
1215}\r
1216\r
1217\r
1218#ifdef HAVE_SYSTEM\r
1219PyDoc_STRVAR(posix_system__doc__,\r
1220"system(command) -> exit_status\n\n\\r
1221Execute the command (a string) in a subshell.");\r
1222\r
1223static PyObject *\r
1224posix_system(PyObject *self, PyObject *args)\r
1225{\r
1226 char *command;\r
1227 long sts;\r
1228 if (!PyArg_ParseTuple(args, "s:system", &command))\r
1229 return NULL;\r
1230 Py_BEGIN_ALLOW_THREADS\r
1231 sts = system(command);\r
1232 Py_END_ALLOW_THREADS\r
1233 return PyInt_FromLong(sts);\r
1234}\r
1235#endif\r
1236\r
1237\r
1238PyDoc_STRVAR(posix_umask__doc__,\r
1239"umask(new_mask) -> old_mask\n\n\\r
1240Set the current numeric umask and return the previous umask.");\r
1241\r
1242static PyObject *\r
1243posix_umask(PyObject *self, PyObject *args)\r
1244{\r
1245 int i;\r
1246 if (!PyArg_ParseTuple(args, "i:umask", &i))\r
1247 return NULL;\r
1248 i = (int)umask(i);\r
1249 if (i < 0)\r
1250 return posix_error();\r
1251 return PyInt_FromLong((long)i);\r
1252}\r
1253\r
1254\r
1255PyDoc_STRVAR(posix_unlink__doc__,\r
1256"unlink(path)\n\n\\r
1257Remove a file (same as remove(path)).");\r
1258\r
1259PyDoc_STRVAR(posix_remove__doc__,\r
1260"remove(path)\n\n\\r
1261Remove a file (same as unlink(path)).");\r
1262\r
1263static PyObject *\r
1264posix_unlink(PyObject *self, PyObject *args)\r
1265{\r
1266 return posix_1str(args, "et:remove", unlink);\r
1267}\r
1268\r
1269\r
1270static int\r
1271extract_time(PyObject *t, time_t* sec, long* usec)\r
1272{\r
1273 time_t intval;\r
1274 if (PyFloat_Check(t)) {\r
1275 double tval = PyFloat_AsDouble(t);\r
1276 PyObject *intobj = PyNumber_Long(t);\r
1277 if (!intobj)\r
1278 return -1;\r
1279#if SIZEOF_TIME_T > SIZEOF_LONG\r
1280 intval = PyInt_AsUnsignedLongLongMask(intobj);\r
1281#else\r
1282 intval = PyInt_AsLong(intobj);\r
1283#endif\r
1284 Py_DECREF(intobj);\r
1285 if (intval == -1 && PyErr_Occurred())\r
1286 return -1;\r
1287 *sec = intval;\r
1288 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */\r
1289 if (*usec < 0)\r
1290 /* If rounding gave us a negative number,\r
1291 truncate. */\r
1292 *usec = 0;\r
1293 return 0;\r
1294 }\r
1295#if SIZEOF_TIME_T > SIZEOF_LONG\r
1296 intval = PyInt_AsUnsignedLongLongMask(t);\r
1297#else\r
1298 intval = PyInt_AsLong(t);\r
1299#endif\r
1300 if (intval == -1 && PyErr_Occurred())\r
1301 return -1;\r
1302 *sec = intval;\r
1303 *usec = 0;\r
1304 return 0;\r
1305}\r
1306\r
1307PyDoc_STRVAR(posix_utime__doc__,\r
1308"utime(path, (atime, mtime))\n\\r
1309utime(path, None)\n\n\\r
1310Set the access and modified time of the file to the given values. If the\n\\r
1311second form is used, set the access and modified times to the current time.");\r
1312\r
1313static PyObject *\r
1314posix_utime(PyObject *self, PyObject *args)\r
1315{\r
1316 char *path = NULL;\r
1317 time_t atime, mtime;\r
1318 long ausec, musec;\r
1319 int res;\r
1320 PyObject* arg;\r
1321\r
1322#if defined(HAVE_UTIMES)\r
1323 struct timeval buf[2];\r
1324#define ATIME buf[0].tv_sec\r
1325#define MTIME buf[1].tv_sec\r
1326#elif defined(HAVE_UTIME_H)\r
1327/* XXX should define struct utimbuf instead, above */\r
1328 struct utimbuf buf;\r
1329#define ATIME buf.actime\r
1330#define MTIME buf.modtime\r
1331#define UTIME_ARG &buf\r
1332#else /* HAVE_UTIMES */\r
1333 time_t buf[2];\r
1334#define ATIME buf[0]\r
1335#define MTIME buf[1]\r
1336#define UTIME_ARG buf\r
1337#endif /* HAVE_UTIMES */\r
1338\r
1339\r
1340 if (!PyArg_ParseTuple(args, "etO:utime",\r
1341 Py_FileSystemDefaultEncoding, &path, &arg))\r
1342 return NULL;\r
1343 if (arg == Py_None) {\r
1344 /* optional time values not given */\r
1345 Py_BEGIN_ALLOW_THREADS\r
1346 res = utime(path, NULL);\r
1347 Py_END_ALLOW_THREADS\r
1348 }\r
1349 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {\r
1350 PyErr_SetString(PyExc_TypeError,\r
1351 "utime() arg 2 must be a tuple (atime, mtime)");\r
1352 PyMem_Free(path);\r
1353 return NULL;\r
1354 }\r
1355 else {\r
1356 if (extract_time(PyTuple_GET_ITEM(arg, 0),\r
1357 &atime, &ausec) == -1) {\r
1358 PyMem_Free(path);\r
1359 return NULL;\r
1360 }\r
1361 if (extract_time(PyTuple_GET_ITEM(arg, 1),\r
1362 &mtime, &musec) == -1) {\r
1363 PyMem_Free(path);\r
1364 return NULL;\r
1365 }\r
1366 ATIME = atime;\r
1367 MTIME = mtime;\r
1368#ifdef HAVE_UTIMES\r
1369 buf[0].tv_usec = ausec;\r
1370 buf[1].tv_usec = musec;\r
1371 Py_BEGIN_ALLOW_THREADS\r
1372 res = utimes(path, buf);\r
1373 Py_END_ALLOW_THREADS\r
1374#else\r
1375 Py_BEGIN_ALLOW_THREADS\r
1376 res = utime(path, UTIME_ARG);\r
1377 Py_END_ALLOW_THREADS\r
1378#endif /* HAVE_UTIMES */\r
1379 }\r
1380 if (res < 0) {\r
1381 return posix_error_with_allocated_filename(path);\r
1382 }\r
1383 PyMem_Free(path);\r
1384 Py_INCREF(Py_None);\r
1385 return Py_None;\r
1386#undef UTIME_ARG\r
1387#undef ATIME\r
1388#undef MTIME\r
1389}\r
1390\r
1391\r
1392/* Process operations */\r
1393\r
1394PyDoc_STRVAR(posix__exit__doc__,\r
1395"_exit(status)\n\n\\r
1396Exit to the system with specified status, without normal exit processing.");\r
1397\r
1398static PyObject *\r
1399posix__exit(PyObject *self, PyObject *args)\r
1400{\r
1401 int sts;\r
1402 if (!PyArg_ParseTuple(args, "i:_exit", &sts))\r
1403 return NULL;\r
1404 _Exit(sts);\r
1405 return NULL; /* Make gcc -Wall happy */\r
1406}\r
1407\r
1408#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)\r
1409static void\r
1410free_string_array(char **array, Py_ssize_t count)\r
1411{\r
1412 Py_ssize_t i;\r
1413 for (i = 0; i < count; i++)\r
1414 PyMem_Free(array[i]);\r
1415 PyMem_DEL(array);\r
1416}\r
1417#endif\r
1418\r
1419\r
1420#ifdef HAVE_EXECV\r
1421PyDoc_STRVAR(posix_execv__doc__,\r
1422"execv(path, args)\n\n\\r
1423Execute an executable path with arguments, replacing current process.\n\\r
1424\n\\r
1425 path: path of executable file\n\\r
1426 args: tuple or list of strings");\r
1427\r
1428static PyObject *\r
1429posix_execv(PyObject *self, PyObject *args)\r
1430{\r
1431 char *path;\r
1432 PyObject *argv;\r
1433 char **argvlist;\r
1434 Py_ssize_t i, argc;\r
1435 PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
1436\r
1437 /* execv has two arguments: (path, argv), where\r
1438 argv is a list or tuple of strings. */\r
1439\r
1440 if (!PyArg_ParseTuple(args, "etO:execv",\r
1441 Py_FileSystemDefaultEncoding,\r
1442 &path, &argv))\r
1443 return NULL;\r
1444 if (PyList_Check(argv)) {\r
1445 argc = PyList_Size(argv);\r
1446 getitem = PyList_GetItem;\r
1447 }\r
1448 else if (PyTuple_Check(argv)) {\r
1449 argc = PyTuple_Size(argv);\r
1450 getitem = PyTuple_GetItem;\r
1451 }\r
1452 else {\r
1453 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");\r
1454 PyMem_Free(path);\r
1455 return NULL;\r
1456 }\r
1457 if (argc < 1) {\r
1458 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");\r
1459 PyMem_Free(path);\r
1460 return NULL;\r
1461 }\r
1462\r
1463 argvlist = PyMem_NEW(char *, argc+1);\r
1464 if (argvlist == NULL) {\r
1465 PyMem_Free(path);\r
1466 return PyErr_NoMemory();\r
1467 }\r
1468 for (i = 0; i < argc; i++) {\r
1469 if (!PyArg_Parse((*getitem)(argv, i), "et",\r
1470 Py_FileSystemDefaultEncoding,\r
1471 &argvlist[i])) {\r
1472 free_string_array(argvlist, i);\r
1473 PyErr_SetString(PyExc_TypeError,\r
1474 "execv() arg 2 must contain only strings");\r
1475 PyMem_Free(path);\r
1476 return NULL;\r
1477\r
1478 }\r
1479 }\r
1480 argvlist[argc] = NULL;\r
1481\r
1482 execv(path, argvlist);\r
1483\r
1484 /* If we get here it's definitely an error */\r
1485\r
1486 free_string_array(argvlist, argc);\r
1487 PyMem_Free(path);\r
1488 return posix_error();\r
1489}\r
1490\r
1491\r
1492PyDoc_STRVAR(posix_execve__doc__,\r
1493"execve(path, args, env)\n\n\\r
1494Execute a path with arguments and environment, replacing current process.\n\\r
1495\n\\r
1496 path: path of executable file\n\\r
1497 args: tuple or list of arguments\n\\r
1498 env: dictionary of strings mapping to strings");\r
1499\r
1500static PyObject *\r
1501posix_execve(PyObject *self, PyObject *args)\r
1502{\r
1503 char *path;\r
1504 PyObject *argv, *env;\r
1505 char **argvlist;\r
1506 char **envlist;\r
1507 PyObject *key, *val, *keys=NULL, *vals=NULL;\r
1508 Py_ssize_t i, pos, argc, envc;\r
1509 PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
1510 Py_ssize_t lastarg = 0;\r
1511\r
1512 /* execve has three arguments: (path, argv, env), where\r
1513 argv is a list or tuple of strings and env is a dictionary\r
1514 like posix.environ. */\r
1515\r
1516 if (!PyArg_ParseTuple(args, "etOO:execve",\r
1517 Py_FileSystemDefaultEncoding,\r
1518 &path, &argv, &env))\r
1519 return NULL;\r
1520 if (PyList_Check(argv)) {\r
1521 argc = PyList_Size(argv);\r
1522 getitem = PyList_GetItem;\r
1523 }\r
1524 else if (PyTuple_Check(argv)) {\r
1525 argc = PyTuple_Size(argv);\r
1526 getitem = PyTuple_GetItem;\r
1527 }\r
1528 else {\r
1529 PyErr_SetString(PyExc_TypeError,\r
1530 "execve() arg 2 must be a tuple or list");\r
1531 goto fail_0;\r
1532 }\r
1533 if (!PyMapping_Check(env)) {\r
1534 PyErr_SetString(PyExc_TypeError,\r
1535 "execve() arg 3 must be a mapping object");\r
1536 goto fail_0;\r
1537 }\r
1538\r
1539 argvlist = PyMem_NEW(char *, argc+1);\r
1540 if (argvlist == NULL) {\r
1541 PyErr_NoMemory();\r
1542 goto fail_0;\r
1543 }\r
1544 for (i = 0; i < argc; i++) {\r
1545 if (!PyArg_Parse((*getitem)(argv, i),\r
1546 "et;execve() arg 2 must contain only strings",\r
1547 Py_FileSystemDefaultEncoding,\r
1548 &argvlist[i]))\r
1549 {\r
1550 lastarg = i;\r
1551 goto fail_1;\r
1552 }\r
1553 }\r
1554 lastarg = argc;\r
1555 argvlist[argc] = NULL;\r
1556\r
1557 i = PyMapping_Size(env);\r
1558 if (i < 0)\r
1559 goto fail_1;\r
1560 envlist = PyMem_NEW(char *, i + 1);\r
1561 if (envlist == NULL) {\r
1562 PyErr_NoMemory();\r
1563 goto fail_1;\r
1564 }\r
1565 envc = 0;\r
1566 keys = PyMapping_Keys(env);\r
1567 vals = PyMapping_Values(env);\r
1568 if (!keys || !vals)\r
1569 goto fail_2;\r
1570 if (!PyList_Check(keys) || !PyList_Check(vals)) {\r
1571 PyErr_SetString(PyExc_TypeError,\r
1572 "execve(): env.keys() or env.values() is not a list");\r
1573 goto fail_2;\r
1574 }\r
1575\r
1576 for (pos = 0; pos < i; pos++) {\r
1577 char *p, *k, *v;\r
1578 size_t len;\r
1579\r
1580 key = PyList_GetItem(keys, pos);\r
1581 val = PyList_GetItem(vals, pos);\r
1582 if (!key || !val)\r
1583 goto fail_2;\r
1584\r
1585 if (!PyArg_Parse(\r
1586 key,\r
1587 "s;execve() arg 3 contains a non-string key",\r
1588 &k) ||\r
1589 !PyArg_Parse(\r
1590 val,\r
1591 "s;execve() arg 3 contains a non-string value",\r
1592 &v))\r
1593 {\r
1594 goto fail_2;\r
1595 }\r
1596\r
1597#if defined(PYOS_OS2)\r
1598 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */\r
1599 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {\r
1600#endif\r
1601 len = PyString_Size(key) + PyString_Size(val) + 2;\r
1602 p = PyMem_NEW(char, len);\r
1603 if (p == NULL) {\r
1604 PyErr_NoMemory();\r
1605 goto fail_2;\r
1606 }\r
1607 PyOS_snprintf(p, len, "%s=%s", k, v);\r
1608 envlist[envc++] = p;\r
1609#if defined(PYOS_OS2)\r
1610 }\r
1611#endif\r
1612 }\r
1613 envlist[envc] = 0;\r
1614\r
1615 execve(path, argvlist, envlist);\r
1616\r
1617 /* If we get here it's definitely an error */\r
1618\r
1619 (void) posix_error();\r
1620\r
1621 fail_2:\r
1622 while (--envc >= 0)\r
1623 PyMem_DEL(envlist[envc]);\r
1624 PyMem_DEL(envlist);\r
1625 fail_1:\r
1626 free_string_array(argvlist, lastarg);\r
1627 Py_XDECREF(vals);\r
1628 Py_XDECREF(keys);\r
1629 fail_0:\r
1630 PyMem_Free(path);\r
1631 return NULL;\r
1632}\r
1633#endif /* HAVE_EXECV */\r
1634\r
1635\r
1636#ifdef HAVE_SPAWNV\r
1637PyDoc_STRVAR(posix_spawnv__doc__,\r
1638"spawnv(mode, path, args)\n\n\\r
1639Execute the program 'path' in a new process.\n\\r
1640\n\\r
1641 mode: mode of process creation\n\\r
1642 path: path of executable file\n\\r
1643 args: tuple or list of strings");\r
1644\r
1645static PyObject *\r
1646posix_spawnv(PyObject *self, PyObject *args)\r
1647{\r
1648 char *path;\r
1649 PyObject *argv;\r
1650 char **argvlist;\r
1651 int mode, i;\r
1652 Py_ssize_t argc;\r
1653 Py_intptr_t spawnval;\r
1654 PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
1655\r
1656 /* spawnv has three arguments: (mode, path, argv), where\r
1657 argv is a list or tuple of strings. */\r
1658\r
1659 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,\r
1660 Py_FileSystemDefaultEncoding,\r
1661 &path, &argv))\r
1662 return NULL;\r
1663 if (PyList_Check(argv)) {\r
1664 argc = PyList_Size(argv);\r
1665 getitem = PyList_GetItem;\r
1666 }\r
1667 else if (PyTuple_Check(argv)) {\r
1668 argc = PyTuple_Size(argv);\r
1669 getitem = PyTuple_GetItem;\r
1670 }\r
1671 else {\r
1672 PyErr_SetString(PyExc_TypeError,\r
1673 "spawnv() arg 2 must be a tuple or list");\r
1674 PyMem_Free(path);\r
1675 return NULL;\r
1676 }\r
1677\r
1678 argvlist = PyMem_NEW(char *, argc+1);\r
1679 if (argvlist == NULL) {\r
1680 PyMem_Free(path);\r
1681 return PyErr_NoMemory();\r
1682 }\r
1683 for (i = 0; i < argc; i++) {\r
1684 if (!PyArg_Parse((*getitem)(argv, i), "et",\r
1685 Py_FileSystemDefaultEncoding,\r
1686 &argvlist[i])) {\r
1687 free_string_array(argvlist, i);\r
1688 PyErr_SetString(\r
1689 PyExc_TypeError,\r
1690 "spawnv() arg 2 must contain only strings");\r
1691 PyMem_Free(path);\r
1692 return NULL;\r
1693 }\r
1694 }\r
1695 argvlist[argc] = NULL;\r
1696\r
1697#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
1698 Py_BEGIN_ALLOW_THREADS\r
1699 spawnval = spawnv(mode, path, argvlist);\r
1700 Py_END_ALLOW_THREADS\r
1701#else\r
1702 if (mode == _OLD_P_OVERLAY)\r
1703 mode = _P_OVERLAY;\r
1704\r
1705 Py_BEGIN_ALLOW_THREADS\r
1706 spawnval = _spawnv(mode, path, argvlist);\r
1707 Py_END_ALLOW_THREADS\r
1708#endif\r
1709\r
1710 free_string_array(argvlist, argc);\r
1711 PyMem_Free(path);\r
1712\r
1713 if (spawnval == -1)\r
1714 return posix_error();\r
1715 else\r
1716#if SIZEOF_LONG == SIZEOF_VOID_P\r
1717 return Py_BuildValue("l", (long) spawnval);\r
1718#else\r
1719 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);\r
1720#endif\r
1721}\r
1722\r
1723\r
1724PyDoc_STRVAR(posix_spawnve__doc__,\r
1725"spawnve(mode, path, args, env)\n\n\\r
1726Execute the program 'path' in a new process.\n\\r
1727\n\\r
1728 mode: mode of process creation\n\\r
1729 path: path of executable file\n\\r
1730 args: tuple or list of arguments\n\\r
1731 env: dictionary of strings mapping to strings");\r
1732\r
1733static PyObject *\r
1734posix_spawnve(PyObject *self, PyObject *args)\r
1735{\r
1736 char *path;\r
1737 PyObject *argv, *env;\r
1738 char **argvlist;\r
1739 char **envlist;\r
1740 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;\r
1741 int mode, pos, envc;\r
1742 Py_ssize_t argc, i;\r
1743 Py_intptr_t spawnval;\r
1744 PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
1745 Py_ssize_t lastarg = 0;\r
1746\r
1747 /* spawnve has four arguments: (mode, path, argv, env), where\r
1748 argv is a list or tuple of strings and env is a dictionary\r
1749 like posix.environ. */\r
1750\r
1751 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,\r
1752 Py_FileSystemDefaultEncoding,\r
1753 &path, &argv, &env))\r
1754 return NULL;\r
1755 if (PyList_Check(argv)) {\r
1756 argc = PyList_Size(argv);\r
1757 getitem = PyList_GetItem;\r
1758 }\r
1759 else if (PyTuple_Check(argv)) {\r
1760 argc = PyTuple_Size(argv);\r
1761 getitem = PyTuple_GetItem;\r
1762 }\r
1763 else {\r
1764 PyErr_SetString(PyExc_TypeError,\r
1765 "spawnve() arg 2 must be a tuple or list");\r
1766 goto fail_0;\r
1767 }\r
1768 if (!PyMapping_Check(env)) {\r
1769 PyErr_SetString(PyExc_TypeError,\r
1770 "spawnve() arg 3 must be a mapping object");\r
1771 goto fail_0;\r
1772 }\r
1773\r
1774 argvlist = PyMem_NEW(char *, argc+1);\r
1775 if (argvlist == NULL) {\r
1776 PyErr_NoMemory();\r
1777 goto fail_0;\r
1778 }\r
1779 for (i = 0; i < argc; i++) {\r
1780 if (!PyArg_Parse((*getitem)(argv, i),\r
1781 "et;spawnve() arg 2 must contain only strings",\r
1782 Py_FileSystemDefaultEncoding,\r
1783 &argvlist[i]))\r
1784 {\r
1785 lastarg = i;\r
1786 goto fail_1;\r
1787 }\r
1788 }\r
1789 lastarg = argc;\r
1790 argvlist[argc] = NULL;\r
1791\r
1792 i = PyMapping_Size(env);\r
1793 if (i < 0)\r
1794 goto fail_1;\r
1795 envlist = PyMem_NEW(char *, i + 1);\r
1796 if (envlist == NULL) {\r
1797 PyErr_NoMemory();\r
1798 goto fail_1;\r
1799 }\r
1800 envc = 0;\r
1801 keys = PyMapping_Keys(env);\r
1802 vals = PyMapping_Values(env);\r
1803 if (!keys || !vals)\r
1804 goto fail_2;\r
1805 if (!PyList_Check(keys) || !PyList_Check(vals)) {\r
1806 PyErr_SetString(PyExc_TypeError,\r
1807 "spawnve(): env.keys() or env.values() is not a list");\r
1808 goto fail_2;\r
1809 }\r
1810\r
1811 for (pos = 0; pos < i; pos++) {\r
1812 char *p, *k, *v;\r
1813 size_t len;\r
1814\r
1815 key = PyList_GetItem(keys, pos);\r
1816 val = PyList_GetItem(vals, pos);\r
1817 if (!key || !val)\r
1818 goto fail_2;\r
1819\r
1820 if (!PyArg_Parse(\r
1821 key,\r
1822 "s;spawnve() arg 3 contains a non-string key",\r
1823 &k) ||\r
1824 !PyArg_Parse(\r
1825 val,\r
1826 "s;spawnve() arg 3 contains a non-string value",\r
1827 &v))\r
1828 {\r
1829 goto fail_2;\r
1830 }\r
1831 len = PyString_Size(key) + PyString_Size(val) + 2;\r
1832 p = PyMem_NEW(char, len);\r
1833 if (p == NULL) {\r
1834 PyErr_NoMemory();\r
1835 goto fail_2;\r
1836 }\r
1837 PyOS_snprintf(p, len, "%s=%s", k, v);\r
1838 envlist[envc++] = p;\r
1839 }\r
1840 envlist[envc] = 0;\r
1841\r
1842#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
1843 Py_BEGIN_ALLOW_THREADS\r
1844 spawnval = spawnve(mode, path, argvlist, envlist);\r
1845 Py_END_ALLOW_THREADS\r
1846#else\r
1847 if (mode == _OLD_P_OVERLAY)\r
1848 mode = _P_OVERLAY;\r
1849\r
1850 Py_BEGIN_ALLOW_THREADS\r
1851 spawnval = _spawnve(mode, path, argvlist, envlist);\r
1852 Py_END_ALLOW_THREADS\r
1853#endif\r
1854\r
1855 if (spawnval == -1)\r
1856 (void) posix_error();\r
1857 else\r
1858#if SIZEOF_LONG == SIZEOF_VOID_P\r
1859 res = Py_BuildValue("l", (long) spawnval);\r
1860#else\r
1861 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);\r
1862#endif\r
1863\r
1864 fail_2:\r
1865 while (--envc >= 0)\r
1866 PyMem_DEL(envlist[envc]);\r
1867 PyMem_DEL(envlist);\r
1868 fail_1:\r
1869 free_string_array(argvlist, lastarg);\r
1870 Py_XDECREF(vals);\r
1871 Py_XDECREF(keys);\r
1872 fail_0:\r
1873 PyMem_Free(path);\r
1874 return res;\r
1875}\r
1876\r
1877/* OS/2 supports spawnvp & spawnvpe natively */\r
1878#if defined(PYOS_OS2)\r
1879PyDoc_STRVAR(posix_spawnvp__doc__,\r
1880"spawnvp(mode, file, args)\n\n\\r
1881Execute the program 'file' in a new process, using the environment\n\\r
1882search path to find the file.\n\\r
1883\n\\r
1884 mode: mode of process creation\n\\r
1885 file: executable file name\n\\r
1886 args: tuple or list of strings");\r
1887\r
1888static PyObject *\r
1889posix_spawnvp(PyObject *self, PyObject *args)\r
1890{\r
1891 char *path;\r
1892 PyObject *argv;\r
1893 char **argvlist;\r
1894 int mode, i, argc;\r
1895 Py_intptr_t spawnval;\r
1896 PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
1897\r
1898 /* spawnvp has three arguments: (mode, path, argv), where\r
1899 argv is a list or tuple of strings. */\r
1900\r
1901 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,\r
1902 Py_FileSystemDefaultEncoding,\r
1903 &path, &argv))\r
1904 return NULL;\r
1905 if (PyList_Check(argv)) {\r
1906 argc = PyList_Size(argv);\r
1907 getitem = PyList_GetItem;\r
1908 }\r
1909 else if (PyTuple_Check(argv)) {\r
1910 argc = PyTuple_Size(argv);\r
1911 getitem = PyTuple_GetItem;\r
1912 }\r
1913 else {\r
1914 PyErr_SetString(PyExc_TypeError,\r
1915 "spawnvp() arg 2 must be a tuple or list");\r
1916 PyMem_Free(path);\r
1917 return NULL;\r
1918 }\r
1919\r
1920 argvlist = PyMem_NEW(char *, argc+1);\r
1921 if (argvlist == NULL) {\r
1922 PyMem_Free(path);\r
1923 return PyErr_NoMemory();\r
1924 }\r
1925 for (i = 0; i < argc; i++) {\r
1926 if (!PyArg_Parse((*getitem)(argv, i), "et",\r
1927 Py_FileSystemDefaultEncoding,\r
1928 &argvlist[i])) {\r
1929 free_string_array(argvlist, i);\r
1930 PyErr_SetString(\r
1931 PyExc_TypeError,\r
1932 "spawnvp() arg 2 must contain only strings");\r
1933 PyMem_Free(path);\r
1934 return NULL;\r
1935 }\r
1936 }\r
1937 argvlist[argc] = NULL;\r
1938\r
1939 Py_BEGIN_ALLOW_THREADS\r
1940#if defined(PYCC_GCC)\r
1941 spawnval = spawnvp(mode, path, argvlist);\r
1942#else\r
1943 spawnval = _spawnvp(mode, path, argvlist);\r
1944#endif\r
1945 Py_END_ALLOW_THREADS\r
1946\r
1947 free_string_array(argvlist, argc);\r
1948 PyMem_Free(path);\r
1949\r
1950 if (spawnval == -1)\r
1951 return posix_error();\r
1952 else\r
1953 return Py_BuildValue("l", (long) spawnval);\r
1954}\r
1955\r
1956\r
1957PyDoc_STRVAR(posix_spawnvpe__doc__,\r
1958"spawnvpe(mode, file, args, env)\n\n\\r
1959Execute the program 'file' in a new process, using the environment\n\\r
1960search path to find the file.\n\\r
1961\n\\r
1962 mode: mode of process creation\n\\r
1963 file: executable file name\n\\r
1964 args: tuple or list of arguments\n\\r
1965 env: dictionary of strings mapping to strings");\r
1966\r
1967static PyObject *\r
1968posix_spawnvpe(PyObject *self, PyObject *args)\r
1969{\r
1970 char *path;\r
1971 PyObject *argv, *env;\r
1972 char **argvlist;\r
1973 char **envlist;\r
1974 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;\r
1975 int mode, i, pos, argc, envc;\r
1976 Py_intptr_t spawnval;\r
1977 PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
1978 int lastarg = 0;\r
1979\r
1980 /* spawnvpe has four arguments: (mode, path, argv, env), where\r
1981 argv is a list or tuple of strings and env is a dictionary\r
1982 like posix.environ. */\r
1983\r
1984 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,\r
1985 Py_FileSystemDefaultEncoding,\r
1986 &path, &argv, &env))\r
1987 return NULL;\r
1988 if (PyList_Check(argv)) {\r
1989 argc = PyList_Size(argv);\r
1990 getitem = PyList_GetItem;\r
1991 }\r
1992 else if (PyTuple_Check(argv)) {\r
1993 argc = PyTuple_Size(argv);\r
1994 getitem = PyTuple_GetItem;\r
1995 }\r
1996 else {\r
1997 PyErr_SetString(PyExc_TypeError,\r
1998 "spawnvpe() arg 2 must be a tuple or list");\r
1999 goto fail_0;\r
2000 }\r
2001 if (!PyMapping_Check(env)) {\r
2002 PyErr_SetString(PyExc_TypeError,\r
2003 "spawnvpe() arg 3 must be a mapping object");\r
2004 goto fail_0;\r
2005 }\r
2006\r
2007 argvlist = PyMem_NEW(char *, argc+1);\r
2008 if (argvlist == NULL) {\r
2009 PyErr_NoMemory();\r
2010 goto fail_0;\r
2011 }\r
2012 for (i = 0; i < argc; i++) {\r
2013 if (!PyArg_Parse((*getitem)(argv, i),\r
2014 "et;spawnvpe() arg 2 must contain only strings",\r
2015 Py_FileSystemDefaultEncoding,\r
2016 &argvlist[i]))\r
2017 {\r
2018 lastarg = i;\r
2019 goto fail_1;\r
2020 }\r
2021 }\r
2022 lastarg = argc;\r
2023 argvlist[argc] = NULL;\r
2024\r
2025 i = PyMapping_Size(env);\r
2026 if (i < 0)\r
2027 goto fail_1;\r
2028 envlist = PyMem_NEW(char *, i + 1);\r
2029 if (envlist == NULL) {\r
2030 PyErr_NoMemory();\r
2031 goto fail_1;\r
2032 }\r
2033 envc = 0;\r
2034 keys = PyMapping_Keys(env);\r
2035 vals = PyMapping_Values(env);\r
2036 if (!keys || !vals)\r
2037 goto fail_2;\r
2038 if (!PyList_Check(keys) || !PyList_Check(vals)) {\r
2039 PyErr_SetString(PyExc_TypeError,\r
2040 "spawnvpe(): env.keys() or env.values() is not a list");\r
2041 goto fail_2;\r
2042 }\r
2043\r
2044 for (pos = 0; pos < i; pos++) {\r
2045 char *p, *k, *v;\r
2046 size_t len;\r
2047\r
2048 key = PyList_GetItem(keys, pos);\r
2049 val = PyList_GetItem(vals, pos);\r
2050 if (!key || !val)\r
2051 goto fail_2;\r
2052\r
2053 if (!PyArg_Parse(\r
2054 key,\r
2055 "s;spawnvpe() arg 3 contains a non-string key",\r
2056 &k) ||\r
2057 !PyArg_Parse(\r
2058 val,\r
2059 "s;spawnvpe() arg 3 contains a non-string value",\r
2060 &v))\r
2061 {\r
2062 goto fail_2;\r
2063 }\r
2064 len = PyString_Size(key) + PyString_Size(val) + 2;\r
2065 p = PyMem_NEW(char, len);\r
2066 if (p == NULL) {\r
2067 PyErr_NoMemory();\r
2068 goto fail_2;\r
2069 }\r
2070 PyOS_snprintf(p, len, "%s=%s", k, v);\r
2071 envlist[envc++] = p;\r
2072 }\r
2073 envlist[envc] = 0;\r
2074\r
2075 Py_BEGIN_ALLOW_THREADS\r
2076#if defined(PYCC_GCC)\r
2077 spawnval = spawnvpe(mode, path, argvlist, envlist);\r
2078#else\r
2079 spawnval = _spawnvpe(mode, path, argvlist, envlist);\r
2080#endif\r
2081 Py_END_ALLOW_THREADS\r
2082\r
2083 if (spawnval == -1)\r
2084 (void) posix_error();\r
2085 else\r
2086 res = Py_BuildValue("l", (long) spawnval);\r
2087\r
2088 fail_2:\r
2089 while (--envc >= 0)\r
2090 PyMem_DEL(envlist[envc]);\r
2091 PyMem_DEL(envlist);\r
2092 fail_1:\r
2093 free_string_array(argvlist, lastarg);\r
2094 Py_XDECREF(vals);\r
2095 Py_XDECREF(keys);\r
2096 fail_0:\r
2097 PyMem_Free(path);\r
2098 return res;\r
2099}\r
2100#endif /* PYOS_OS2 */\r
2101#endif /* HAVE_SPAWNV */\r
2102\r
2103\r
2104#ifdef HAVE_FORK1\r
2105PyDoc_STRVAR(posix_fork1__doc__,\r
2106"fork1() -> pid\n\n\\r
2107Fork a child process with a single multiplexed (i.e., not bound) thread.\n\\r
2108\n\\r
2109Return 0 to child process and PID of child to parent process.");\r
2110\r
2111static PyObject *\r
2112posix_fork1(PyObject *self, PyObject *noargs)\r
2113{\r
2114 pid_t pid;\r
2115 int result = 0;\r
2116 _PyImport_AcquireLock();\r
2117 pid = fork1();\r
2118 if (pid == 0) {\r
2119 /* child: this clobbers and resets the import lock. */\r
2120 PyOS_AfterFork();\r
2121 } else {\r
2122 /* parent: release the import lock. */\r
2123 result = _PyImport_ReleaseLock();\r
2124 }\r
2125 if (pid == -1)\r
2126 return posix_error();\r
2127 if (result < 0) {\r
2128 /* Don't clobber the OSError if the fork failed. */\r
2129 PyErr_SetString(PyExc_RuntimeError,\r
2130 "not holding the import lock");\r
2131 return NULL;\r
2132 }\r
2133 return PyLong_FromPid(pid);\r
2134}\r
2135#endif\r
2136\r
2137\r
2138#ifdef HAVE_FORK\r
2139PyDoc_STRVAR(posix_fork__doc__,\r
2140"fork() -> pid\n\n\\r
2141Fork a child process.\n\\r
2142Return 0 to child process and PID of child to parent process.");\r
2143\r
2144static PyObject *\r
2145posix_fork(PyObject *self, PyObject *noargs)\r
2146{\r
2147 pid_t pid;\r
2148 int result = 0;\r
2149 _PyImport_AcquireLock();\r
2150 pid = fork();\r
2151 if (pid == 0) {\r
2152 /* child: this clobbers and resets the import lock. */\r
2153 PyOS_AfterFork();\r
2154 } else {\r
2155 /* parent: release the import lock. */\r
2156 result = _PyImport_ReleaseLock();\r
2157 }\r
2158 if (pid == -1)\r
2159 return posix_error();\r
2160 if (result < 0) {\r
2161 /* Don't clobber the OSError if the fork failed. */\r
2162 PyErr_SetString(PyExc_RuntimeError,\r
2163 "not holding the import lock");\r
2164 return NULL;\r
2165 }\r
2166 return PyLong_FromPid(pid);\r
2167}\r
2168#endif\r
2169\r
2170/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */\r
2171/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */\r
2172#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)\r
2173#define DEV_PTY_FILE "/dev/ptc"\r
2174#define HAVE_DEV_PTMX\r
2175#else\r
2176#define DEV_PTY_FILE "/dev/ptmx"\r
2177#endif\r
2178\r
2179#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)\r
2180#ifdef HAVE_PTY_H\r
2181#include <pty.h>\r
2182#else\r
2183#ifdef HAVE_LIBUTIL_H\r
2184#include <libutil.h>\r
2185#else\r
2186#ifdef HAVE_UTIL_H\r
2187#include <util.h>\r
2188#endif /* HAVE_UTIL_H */\r
2189#endif /* HAVE_LIBUTIL_H */\r
2190#endif /* HAVE_PTY_H */\r
2191#ifdef HAVE_STROPTS_H\r
2192#include <stropts.h>\r
2193#endif\r
2194#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */\r
2195\r
2196#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)\r
2197PyDoc_STRVAR(posix_openpty__doc__,\r
2198"openpty() -> (master_fd, slave_fd)\n\n\\r
2199Open a pseudo-terminal, returning open fd's for both master and slave end.\n");\r
2200\r
2201static PyObject *\r
2202posix_openpty(PyObject *self, PyObject *noargs)\r
2203{\r
2204 int master_fd, slave_fd;\r
2205#ifndef HAVE_OPENPTY\r
2206 char * slave_name;\r
2207#endif\r
2208#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)\r
2209 PyOS_sighandler_t sig_saved;\r
2210#ifdef sun\r
2211 extern char *ptsname(int fildes);\r
2212#endif\r
2213#endif\r
2214\r
2215#ifdef HAVE_OPENPTY\r
2216 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)\r
2217 return posix_error();\r
2218#elif defined(HAVE__GETPTY)\r
2219 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);\r
2220 if (slave_name == NULL)\r
2221 return posix_error();\r
2222\r
2223 slave_fd = open(slave_name, O_RDWR);\r
2224 if (slave_fd < 0)\r
2225 return posix_error();\r
2226#else\r
2227 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */\r
2228 if (master_fd < 0)\r
2229 return posix_error();\r
2230 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);\r
2231 /* change permission of slave */\r
2232 if (grantpt(master_fd) < 0) {\r
2233 PyOS_setsig(SIGCHLD, sig_saved);\r
2234 return posix_error();\r
2235 }\r
2236 /* unlock slave */\r
2237 if (unlockpt(master_fd) < 0) {\r
2238 PyOS_setsig(SIGCHLD, sig_saved);\r
2239 return posix_error();\r
2240 }\r
2241 PyOS_setsig(SIGCHLD, sig_saved);\r
2242 slave_name = ptsname(master_fd); /* get name of slave */\r
2243 if (slave_name == NULL)\r
2244 return posix_error();\r
2245 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */\r
2246 if (slave_fd < 0)\r
2247 return posix_error();\r
2248#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)\r
2249 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */\r
2250 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */\r
2251#ifndef __hpux\r
2252 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */\r
2253#endif /* __hpux */\r
2254#endif /* HAVE_CYGWIN */\r
2255#endif /* HAVE_OPENPTY */\r
2256\r
2257 return Py_BuildValue("(ii)", master_fd, slave_fd);\r
2258\r
2259}\r
2260#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */\r
2261\r
2262#ifdef HAVE_FORKPTY\r
2263PyDoc_STRVAR(posix_forkpty__doc__,\r
2264"forkpty() -> (pid, master_fd)\n\n\\r
2265Fork a new process with a new pseudo-terminal as controlling tty.\n\n\\r
2266Like fork(), return 0 as pid to child process, and PID of child to parent.\n\\r
2267To both, return fd of newly opened pseudo-terminal.\n");\r
2268\r
2269static PyObject *\r
2270posix_forkpty(PyObject *self, PyObject *noargs)\r
2271{\r
2272 int master_fd = -1, result = 0;\r
2273 pid_t pid;\r
2274\r
2275 _PyImport_AcquireLock();\r
2276 pid = forkpty(&master_fd, NULL, NULL, NULL);\r
2277 if (pid == 0) {\r
2278 /* child: this clobbers and resets the import lock. */\r
2279 PyOS_AfterFork();\r
2280 } else {\r
2281 /* parent: release the import lock. */\r
2282 result = _PyImport_ReleaseLock();\r
2283 }\r
2284 if (pid == -1)\r
2285 return posix_error();\r
2286 if (result < 0) {\r
2287 /* Don't clobber the OSError if the fork failed. */\r
2288 PyErr_SetString(PyExc_RuntimeError,\r
2289 "not holding the import lock");\r
2290 return NULL;\r
2291 }\r
2292 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);\r
2293}\r
2294#endif\r
2295\r
2296#ifdef HAVE_GETEGID\r
2297PyDoc_STRVAR(posix_getegid__doc__,\r
2298"getegid() -> egid\n\n\\r
2299Return the current process's effective group id.");\r
2300\r
2301static PyObject *\r
2302posix_getegid(PyObject *self, PyObject *noargs)\r
2303{\r
2304 return PyInt_FromLong((long)getegid());\r
2305}\r
2306#endif\r
2307\r
2308\r
2309#ifdef HAVE_GETEUID\r
2310PyDoc_STRVAR(posix_geteuid__doc__,\r
2311"geteuid() -> euid\n\n\\r
2312Return the current process's effective user id.");\r
2313\r
2314static PyObject *\r
2315posix_geteuid(PyObject *self, PyObject *noargs)\r
2316{\r
2317 return PyInt_FromLong((long)geteuid());\r
2318}\r
2319#endif\r
2320\r
2321\r
2322#ifdef HAVE_GETGID\r
2323PyDoc_STRVAR(posix_getgid__doc__,\r
2324"getgid() -> gid\n\n\\r
2325Return the current process's group id.");\r
2326\r
2327static PyObject *\r
2328posix_getgid(PyObject *self, PyObject *noargs)\r
2329{\r
2330 return PyInt_FromLong((long)getgid());\r
2331}\r
2332#endif\r
2333\r
2334\r
2335PyDoc_STRVAR(posix_getpid__doc__,\r
2336"getpid() -> pid\n\n\\r
2337Return the current process id");\r
2338\r
2339static PyObject *\r
2340posix_getpid(PyObject *self, PyObject *noargs)\r
2341{\r
2342 return PyLong_FromPid(getpid());\r
2343}\r
2344\r
2345\r
2346#ifdef HAVE_GETGROUPS\r
2347PyDoc_STRVAR(posix_getgroups__doc__,\r
2348"getgroups() -> list of group IDs\n\n\\r
2349Return list of supplemental group IDs for the process.");\r
2350\r
2351static PyObject *\r
2352posix_getgroups(PyObject *self, PyObject *noargs)\r
2353{\r
2354 PyObject *result = NULL;\r
2355\r
2356#ifdef NGROUPS_MAX\r
2357#define MAX_GROUPS NGROUPS_MAX\r
2358#else\r
2359 /* defined to be 16 on Solaris7, so this should be a small number */\r
2360#define MAX_GROUPS 64\r
2361#endif\r
2362 gid_t grouplist[MAX_GROUPS];\r
2363\r
2364 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results\r
2365 * This is a helper variable to store the intermediate result when\r
2366 * that happens.\r
2367 *\r
2368 * To keep the code readable the OSX behaviour is unconditional,\r
2369 * according to the POSIX spec this should be safe on all unix-y\r
2370 * systems.\r
2371 */\r
2372 gid_t* alt_grouplist = grouplist;\r
2373 int n;\r
2374\r
2375 n = getgroups(MAX_GROUPS, grouplist);\r
2376 if (n < 0) {\r
2377 if (errno == EINVAL) {\r
2378 n = getgroups(0, NULL);\r
2379 if (n == -1) {\r
2380 return posix_error();\r
2381 }\r
2382 if (n == 0) {\r
2383 /* Avoid malloc(0) */\r
2384 alt_grouplist = grouplist;\r
2385 } else {\r
2386 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));\r
2387 if (alt_grouplist == NULL) {\r
2388 errno = EINVAL;\r
2389 return posix_error();\r
2390 }\r
2391 n = getgroups(n, alt_grouplist);\r
2392 if (n == -1) {\r
2393 PyMem_Free(alt_grouplist);\r
2394 return posix_error();\r
2395 }\r
2396 }\r
2397 } else {\r
2398 return posix_error();\r
2399 }\r
2400 }\r
2401 result = PyList_New(n);\r
2402 if (result != NULL) {\r
2403 int i;\r
2404 for (i = 0; i < n; ++i) {\r
2405 PyObject *o = PyInt_FromLong((long)alt_grouplist[i]);\r
2406 if (o == NULL) {\r
2407 Py_DECREF(result);\r
2408 result = NULL;\r
2409 break;\r
2410 }\r
2411 PyList_SET_ITEM(result, i, o);\r
2412 }\r
2413 }\r
2414\r
2415 if (alt_grouplist != grouplist) {\r
2416 PyMem_Free(alt_grouplist);\r
2417 }\r
2418\r
2419 return result;\r
2420}\r
2421#endif\r
2422\r
2423#ifdef HAVE_INITGROUPS\r
2424PyDoc_STRVAR(posix_initgroups__doc__,\r
2425"initgroups(username, gid) -> None\n\n\\r
2426Call the system initgroups() to initialize the group access list with all of\n\\r
2427the groups of which the specified username is a member, plus the specified\n\\r
2428group id.");\r
2429\r
2430static PyObject *\r
2431posix_initgroups(PyObject *self, PyObject *args)\r
2432{\r
2433 char *username;\r
2434 long gid;\r
2435\r
2436 if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))\r
2437 return NULL;\r
2438\r
2439 if (initgroups(username, (gid_t) gid) == -1)\r
2440 return PyErr_SetFromErrno(PyExc_OSError);\r
2441\r
2442 Py_INCREF(Py_None);\r
2443 return Py_None;\r
2444}\r
2445#endif\r
2446\r
2447#ifdef HAVE_GETPGID\r
2448PyDoc_STRVAR(posix_getpgid__doc__,\r
2449"getpgid(pid) -> pgid\n\n\\r
2450Call the system call getpgid().");\r
2451\r
2452static PyObject *\r
2453posix_getpgid(PyObject *self, PyObject *args)\r
2454{\r
2455 pid_t pid, pgid;\r
2456 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))\r
2457 return NULL;\r
2458 pgid = getpgid(pid);\r
2459 if (pgid < 0)\r
2460 return posix_error();\r
2461 return PyLong_FromPid(pgid);\r
2462}\r
2463#endif /* HAVE_GETPGID */\r
2464\r
2465\r
2466#ifdef HAVE_GETPGRP\r
2467PyDoc_STRVAR(posix_getpgrp__doc__,\r
2468"getpgrp() -> pgrp\n\n\\r
2469Return the current process group id.");\r
2470\r
2471static PyObject *\r
2472posix_getpgrp(PyObject *self, PyObject *noargs)\r
2473{\r
2474#ifdef GETPGRP_HAVE_ARG\r
2475 return PyLong_FromPid(getpgrp(0));\r
2476#else /* GETPGRP_HAVE_ARG */\r
2477 return PyLong_FromPid(getpgrp());\r
2478#endif /* GETPGRP_HAVE_ARG */\r
2479}\r
2480#endif /* HAVE_GETPGRP */\r
2481\r
2482\r
2483#ifdef HAVE_SETPGRP\r
2484PyDoc_STRVAR(posix_setpgrp__doc__,\r
2485"setpgrp()\n\n\\r
2486Make this process the process group leader.");\r
2487\r
2488static PyObject *\r
2489posix_setpgrp(PyObject *self, PyObject *noargs)\r
2490{\r
2491#ifdef SETPGRP_HAVE_ARG\r
2492 if (setpgrp(0, 0) < 0)\r
2493#else /* SETPGRP_HAVE_ARG */\r
2494 if (setpgrp() < 0)\r
2495#endif /* SETPGRP_HAVE_ARG */\r
2496 return posix_error();\r
2497 Py_INCREF(Py_None);\r
2498 return Py_None;\r
2499}\r
2500\r
2501#endif /* HAVE_SETPGRP */\r
2502\r
2503#ifdef HAVE_GETPPID\r
2504PyDoc_STRVAR(posix_getppid__doc__,\r
2505"getppid() -> ppid\n\n\\r
2506Return the parent's process id.");\r
2507\r
2508static PyObject *\r
2509posix_getppid(PyObject *self, PyObject *noargs)\r
2510{\r
2511 return PyLong_FromPid(getppid());\r
2512}\r
2513#endif\r
2514\r
2515\r
2516#ifdef HAVE_GETLOGIN\r
2517PyDoc_STRVAR(posix_getlogin__doc__,\r
2518"getlogin() -> string\n\n\\r
2519Return the actual login name.");\r
2520\r
2521static PyObject *\r
2522posix_getlogin(PyObject *self, PyObject *noargs)\r
2523{\r
2524 PyObject *result = NULL;\r
2525 char *name;\r
2526 int old_errno = errno;\r
2527\r
2528 errno = 0;\r
2529 name = getlogin();\r
2530 if (name == NULL) {\r
2531 if (errno)\r
2532 posix_error();\r
2533 else\r
2534 PyErr_SetString(PyExc_OSError,\r
2535 "unable to determine login name");\r
2536 }\r
2537 else\r
2538 result = PyString_FromString(name);\r
2539 errno = old_errno;\r
2540\r
2541 return result;\r
2542}\r
2543#endif\r
2544\r
2545#ifndef UEFI_C_SOURCE\r
2546PyDoc_STRVAR(posix_getuid__doc__,\r
2547"getuid() -> uid\n\n\\r
2548Return the current process's user id.");\r
2549\r
2550static PyObject *\r
2551posix_getuid(PyObject *self, PyObject *noargs)\r
2552{\r
2553 return PyInt_FromLong((long)getuid());\r
2554}\r
2555#endif /* UEFI_C_SOURCE */\r
2556\r
2557#ifdef HAVE_KILL\r
2558PyDoc_STRVAR(posix_kill__doc__,\r
2559"kill(pid, sig)\n\n\\r
2560Kill a process with a signal.");\r
2561\r
2562static PyObject *\r
2563posix_kill(PyObject *self, PyObject *args)\r
2564{\r
2565 pid_t pid;\r
2566 int sig;\r
2567 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))\r
2568 return NULL;\r
2569#if defined(PYOS_OS2) && !defined(PYCC_GCC)\r
2570 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {\r
2571 APIRET rc;\r
2572 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)\r
2573 return os2_error(rc);\r
2574\r
2575 } else if (sig == XCPT_SIGNAL_KILLPROC) {\r
2576 APIRET rc;\r
2577 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)\r
2578 return os2_error(rc);\r
2579\r
2580 } else\r
2581 return NULL; /* Unrecognized Signal Requested */\r
2582#else\r
2583 if (kill(pid, sig) == -1)\r
2584 return posix_error();\r
2585#endif\r
2586 Py_INCREF(Py_None);\r
2587 return Py_None;\r
2588}\r
2589#endif\r
2590\r
2591#ifdef HAVE_KILLPG\r
2592PyDoc_STRVAR(posix_killpg__doc__,\r
2593"killpg(pgid, sig)\n\n\\r
2594Kill a process group with a signal.");\r
2595\r
2596static PyObject *\r
2597posix_killpg(PyObject *self, PyObject *args)\r
2598{\r
2599 int sig;\r
2600 pid_t pgid;\r
2601 /* XXX some man pages make the `pgid` parameter an int, others\r
2602 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should\r
2603 take the same type. Moreover, pid_t is always at least as wide as\r
2604 int (else compilation of this module fails), which is safe. */\r
2605 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))\r
2606 return NULL;\r
2607 if (killpg(pgid, sig) == -1)\r
2608 return posix_error();\r
2609 Py_INCREF(Py_None);\r
2610 return Py_None;\r
2611}\r
2612#endif\r
2613\r
2614#ifdef HAVE_PLOCK\r
2615\r
2616#ifdef HAVE_SYS_LOCK_H\r
2617#include <sys/lock.h>\r
2618#endif\r
2619\r
2620PyDoc_STRVAR(posix_plock__doc__,\r
2621"plock(op)\n\n\\r
2622Lock program segments into memory.");\r
2623\r
2624static PyObject *\r
2625posix_plock(PyObject *self, PyObject *args)\r
2626{\r
2627 int op;\r
2628 if (!PyArg_ParseTuple(args, "i:plock", &op))\r
2629 return NULL;\r
2630 if (plock(op) == -1)\r
2631 return posix_error();\r
2632 Py_INCREF(Py_None);\r
2633 return Py_None;\r
2634}\r
2635#endif\r
2636\r
2637\r
2638#ifdef HAVE_POPEN\r
2639PyDoc_STRVAR(posix_popen__doc__,\r
2640"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\\r
2641Open a pipe to/from a command returning a file object.");\r
2642\r
2643#if defined(PYOS_OS2)\r
2644#if defined(PYCC_VACPP)\r
2645static int\r
2646async_system(const char *command)\r
2647{\r
2648 char errormsg[256], args[1024];\r
2649 RESULTCODES rcodes;\r
2650 APIRET rc;\r
2651\r
2652 char *shell = getenv("COMSPEC");\r
2653 if (!shell)\r
2654 shell = "cmd";\r
2655\r
2656 /* avoid overflowing the argument buffer */\r
2657 if (strlen(shell) + 3 + strlen(command) >= 1024)\r
2658 return ERROR_NOT_ENOUGH_MEMORY\r
2659\r
2660 args[0] = '\0';\r
2661 strcat(args, shell);\r
2662 strcat(args, "/c ");\r
2663 strcat(args, command);\r
2664\r
2665 /* execute asynchronously, inheriting the environment */\r
2666 rc = DosExecPgm(errormsg,\r
2667 sizeof(errormsg),\r
2668 EXEC_ASYNC,\r
2669 args,\r
2670 NULL,\r
2671 &rcodes,\r
2672 shell);\r
2673 return rc;\r
2674}\r
2675\r
2676static FILE *\r
2677popen(const char *command, const char *mode, int pipesize, int *err)\r
2678{\r
2679 int oldfd, tgtfd;\r
2680 HFILE pipeh[2];\r
2681 APIRET rc;\r
2682\r
2683 /* mode determines which of stdin or stdout is reconnected to\r
2684 * the pipe to the child\r
2685 */\r
2686 if (strchr(mode, 'r') != NULL) {\r
2687 tgt_fd = 1; /* stdout */\r
2688 } else if (strchr(mode, 'w')) {\r
2689 tgt_fd = 0; /* stdin */\r
2690 } else {\r
2691 *err = ERROR_INVALID_ACCESS;\r
2692 return NULL;\r
2693 }\r
2694\r
2695 /* setup the pipe */\r
2696 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {\r
2697 *err = rc;\r
2698 return NULL;\r
2699 }\r
2700\r
2701 /* prevent other threads accessing stdio */\r
2702 DosEnterCritSec();\r
2703\r
2704 /* reconnect stdio and execute child */\r
2705 oldfd = dup(tgtfd);\r
2706 close(tgtfd);\r
2707 if (dup2(pipeh[tgtfd], tgtfd) == 0) {\r
2708 DosClose(pipeh[tgtfd]);\r
2709 rc = async_system(command);\r
2710 }\r
2711\r
2712 /* restore stdio */\r
2713 dup2(oldfd, tgtfd);\r
2714 close(oldfd);\r
2715\r
2716 /* allow other threads access to stdio */\r
2717 DosExitCritSec();\r
2718\r
2719 /* if execution of child was successful return file stream */\r
2720 if (rc == NO_ERROR)\r
2721 return fdopen(pipeh[1 - tgtfd], mode);\r
2722 else {\r
2723 DosClose(pipeh[1 - tgtfd]);\r
2724 *err = rc;\r
2725 return NULL;\r
2726 }\r
2727}\r
2728\r
2729static PyObject *\r
2730posix_popen(PyObject *self, PyObject *args)\r
2731{\r
2732 char *name;\r
2733 char *mode = "r";\r
2734 int err, bufsize = -1;\r
2735 FILE *fp;\r
2736 PyObject *f;\r
2737 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))\r
2738 return NULL;\r
2739 Py_BEGIN_ALLOW_THREADS\r
2740 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);\r
2741 Py_END_ALLOW_THREADS\r
2742 if (fp == NULL)\r
2743 return os2_error(err);\r
2744\r
2745 f = PyFile_FromFile(fp, name, mode, fclose);\r
2746 if (f != NULL)\r
2747 PyFile_SetBufSize(f, bufsize);\r
2748 return f;\r
2749}\r
2750\r
2751#elif defined(PYCC_GCC)\r
2752\r
2753/* standard posix version of popen() support */\r
2754static PyObject *\r
2755posix_popen(PyObject *self, PyObject *args)\r
2756{\r
2757 char *name;\r
2758 char *mode = "r";\r
2759 int bufsize = -1;\r
2760 FILE *fp;\r
2761 PyObject *f;\r
2762 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))\r
2763 return NULL;\r
2764 Py_BEGIN_ALLOW_THREADS\r
2765 fp = popen(name, mode);\r
2766 Py_END_ALLOW_THREADS\r
2767 if (fp == NULL)\r
2768 return posix_error();\r
2769 f = PyFile_FromFile(fp, name, mode, pclose);\r
2770 if (f != NULL)\r
2771 PyFile_SetBufSize(f, bufsize);\r
2772 return f;\r
2773}\r
2774\r
2775/* fork() under OS/2 has lots'o'warts\r
2776 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()\r
2777 * most of this code is a ripoff of the win32 code, but using the\r
2778 * capabilities of EMX's C library routines\r
2779 */\r
2780\r
2781/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */\r
2782#define POPEN_1 1\r
2783#define POPEN_2 2\r
2784#define POPEN_3 3\r
2785#define POPEN_4 4\r
2786\r
2787static PyObject *_PyPopen(char *, int, int, int);\r
2788static int _PyPclose(FILE *file);\r
2789\r
2790/*\r
2791 * Internal dictionary mapping popen* file pointers to process handles,\r
2792 * for use when retrieving the process exit code. See _PyPclose() below\r
2793 * for more information on this dictionary's use.\r
2794 */\r
2795static PyObject *_PyPopenProcs = NULL;\r
2796\r
2797/* os2emx version of popen2()\r
2798 *\r
2799 * The result of this function is a pipe (file) connected to the\r
2800 * process's stdin, and a pipe connected to the process's stdout.\r
2801 */\r
2802\r
2803static PyObject *\r
2804os2emx_popen2(PyObject *self, PyObject *args)\r
2805{\r
2806 PyObject *f;\r
2807 int tm=0;\r
2808\r
2809 char *cmdstring;\r
2810 char *mode = "t";\r
2811 int bufsize = -1;\r
2812 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))\r
2813 return NULL;\r
2814\r
2815 if (*mode == 't')\r
2816 tm = O_TEXT;\r
2817 else if (*mode != 'b') {\r
2818 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");\r
2819 return NULL;\r
2820 } else\r
2821 tm = O_BINARY;\r
2822\r
2823 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);\r
2824\r
2825 return f;\r
2826}\r
2827\r
2828/*\r
2829 * Variation on os2emx.popen2\r
2830 *\r
2831 * The result of this function is 3 pipes - the process's stdin,\r
2832 * stdout and stderr\r
2833 */\r
2834\r
2835static PyObject *\r
2836os2emx_popen3(PyObject *self, PyObject *args)\r
2837{\r
2838 PyObject *f;\r
2839 int tm = 0;\r
2840\r
2841 char *cmdstring;\r
2842 char *mode = "t";\r
2843 int bufsize = -1;\r
2844 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))\r
2845 return NULL;\r
2846\r
2847 if (*mode == 't')\r
2848 tm = O_TEXT;\r
2849 else if (*mode != 'b') {\r
2850 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");\r
2851 return NULL;\r
2852 } else\r
2853 tm = O_BINARY;\r
2854\r
2855 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);\r
2856\r
2857 return f;\r
2858}\r
2859\r
2860/*\r
2861 * Variation on os2emx.popen2\r
2862 *\r
2863 * The result of this function is 2 pipes - the processes stdin,\r
2864 * and stdout+stderr combined as a single pipe.\r
2865 */\r
2866\r
2867static PyObject *\r
2868os2emx_popen4(PyObject *self, PyObject *args)\r
2869{\r
2870 PyObject *f;\r
2871 int tm = 0;\r
2872\r
2873 char *cmdstring;\r
2874 char *mode = "t";\r
2875 int bufsize = -1;\r
2876 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))\r
2877 return NULL;\r
2878\r
2879 if (*mode == 't')\r
2880 tm = O_TEXT;\r
2881 else if (*mode != 'b') {\r
2882 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");\r
2883 return NULL;\r
2884 } else\r
2885 tm = O_BINARY;\r
2886\r
2887 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);\r
2888\r
2889 return f;\r
2890}\r
2891\r
2892/* a couple of structures for convenient handling of multiple\r
2893 * file handles and pipes\r
2894 */\r
2895struct file_ref\r
2896{\r
2897 int handle;\r
2898 int flags;\r
2899};\r
2900\r
2901struct pipe_ref\r
2902{\r
2903 int rd;\r
2904 int wr;\r
2905};\r
2906\r
2907/* The following code is derived from the win32 code */\r
2908\r
2909static PyObject *\r
2910_PyPopen(char *cmdstring, int mode, int n, int bufsize)\r
2911{\r
2912 struct file_ref stdio[3];\r
2913 struct pipe_ref p_fd[3];\r
2914 FILE *p_s[3];\r
2915 int file_count, i, pipe_err;\r
2916 pid_t pipe_pid;\r
2917 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;\r
2918 PyObject *f, *p_f[3];\r
2919\r
2920 /* file modes for subsequent fdopen's on pipe handles */\r
2921 if (mode == O_TEXT)\r
2922 {\r
2923 rd_mode = "rt";\r
2924 wr_mode = "wt";\r
2925 }\r
2926 else\r
2927 {\r
2928 rd_mode = "rb";\r
2929 wr_mode = "wb";\r
2930 }\r
2931\r
2932 /* prepare shell references */\r
2933 if ((shell = getenv("EMXSHELL")) == NULL)\r
2934 if ((shell = getenv("COMSPEC")) == NULL)\r
2935 {\r
2936 errno = ENOENT;\r
2937 return posix_error();\r
2938 }\r
2939\r
2940 sh_name = _getname(shell);\r
2941 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)\r
2942 opt = "/c";\r
2943 else\r
2944 opt = "-c";\r
2945\r
2946 /* save current stdio fds + their flags, and set not inheritable */\r
2947 i = pipe_err = 0;\r
2948 while (pipe_err >= 0 && i < 3)\r
2949 {\r
2950 pipe_err = stdio[i].handle = dup(i);\r
2951 stdio[i].flags = fcntl(i, F_GETFD, 0);\r
2952 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);\r
2953 i++;\r
2954 }\r
2955 if (pipe_err < 0)\r
2956 {\r
2957 /* didn't get them all saved - clean up and bail out */\r
2958 int saved_err = errno;\r
2959 while (i-- > 0)\r
2960 {\r
2961 close(stdio[i].handle);\r
2962 }\r
2963 errno = saved_err;\r
2964 return posix_error();\r
2965 }\r
2966\r
2967 /* create pipe ends */\r
2968 file_count = 2;\r
2969 if (n == POPEN_3)\r
2970 file_count = 3;\r
2971 i = pipe_err = 0;\r
2972 while ((pipe_err == 0) && (i < file_count))\r
2973 pipe_err = pipe((int *)&p_fd[i++]);\r
2974 if (pipe_err < 0)\r
2975 {\r
2976 /* didn't get them all made - clean up and bail out */\r
2977 while (i-- > 0)\r
2978 {\r
2979 close(p_fd[i].wr);\r
2980 close(p_fd[i].rd);\r
2981 }\r
2982 errno = EPIPE;\r
2983 return posix_error();\r
2984 }\r
2985\r
2986 /* change the actual standard IO streams over temporarily,\r
2987 * making the retained pipe ends non-inheritable\r
2988 */\r
2989 pipe_err = 0;\r
2990\r
2991 /* - stdin */\r
2992 if (dup2(p_fd[0].rd, 0) == 0)\r
2993 {\r
2994 close(p_fd[0].rd);\r
2995 i = fcntl(p_fd[0].wr, F_GETFD, 0);\r
2996 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);\r
2997 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)\r
2998 {\r
2999 close(p_fd[0].wr);\r
3000 pipe_err = -1;\r
3001 }\r
3002 }\r
3003 else\r
3004 {\r
3005 pipe_err = -1;\r
3006 }\r
3007\r
3008 /* - stdout */\r
3009 if (pipe_err == 0)\r
3010 {\r
3011 if (dup2(p_fd[1].wr, 1) == 1)\r
3012 {\r
3013 close(p_fd[1].wr);\r
3014 i = fcntl(p_fd[1].rd, F_GETFD, 0);\r
3015 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);\r
3016 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)\r
3017 {\r
3018 close(p_fd[1].rd);\r
3019 pipe_err = -1;\r
3020 }\r
3021 }\r
3022 else\r
3023 {\r
3024 pipe_err = -1;\r
3025 }\r
3026 }\r
3027\r
3028 /* - stderr, as required */\r
3029 if (pipe_err == 0)\r
3030 switch (n)\r
3031 {\r
3032 case POPEN_3:\r
3033 {\r
3034 if (dup2(p_fd[2].wr, 2) == 2)\r
3035 {\r
3036 close(p_fd[2].wr);\r
3037 i = fcntl(p_fd[2].rd, F_GETFD, 0);\r
3038 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);\r
3039 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)\r
3040 {\r
3041 close(p_fd[2].rd);\r
3042 pipe_err = -1;\r
3043 }\r
3044 }\r
3045 else\r
3046 {\r
3047 pipe_err = -1;\r
3048 }\r
3049 break;\r
3050 }\r
3051\r
3052 case POPEN_4:\r
3053 {\r
3054 if (dup2(1, 2) != 2)\r
3055 {\r
3056 pipe_err = -1;\r
3057 }\r
3058 break;\r
3059 }\r
3060 }\r
3061\r
3062 /* spawn the child process */\r
3063 if (pipe_err == 0)\r
3064 {\r
3065 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);\r
3066 if (pipe_pid == -1)\r
3067 {\r
3068 pipe_err = -1;\r
3069 }\r
3070 else\r
3071 {\r
3072 /* save the PID into the FILE structure\r
3073 * NOTE: this implementation doesn't actually\r
3074 * take advantage of this, but do it for\r
3075 * completeness - AIM Apr01\r
3076 */\r
3077 for (i = 0; i < file_count; i++)\r
3078 p_s[i]->_pid = pipe_pid;\r
3079 }\r
3080 }\r
3081\r
3082 /* reset standard IO to normal */\r
3083 for (i = 0; i < 3; i++)\r
3084 {\r
3085 dup2(stdio[i].handle, i);\r
3086 fcntl(i, F_SETFD, stdio[i].flags);\r
3087 close(stdio[i].handle);\r
3088 }\r
3089\r
3090 /* if any remnant problems, clean up and bail out */\r
3091 if (pipe_err < 0)\r
3092 {\r
3093 for (i = 0; i < 3; i++)\r
3094 {\r
3095 close(p_fd[i].rd);\r
3096 close(p_fd[i].wr);\r
3097 }\r
3098 errno = EPIPE;\r
3099 return posix_error_with_filename(cmdstring);\r
3100 }\r
3101\r
3102 /* build tuple of file objects to return */\r
3103 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)\r
3104 PyFile_SetBufSize(p_f[0], bufsize);\r
3105 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)\r
3106 PyFile_SetBufSize(p_f[1], bufsize);\r
3107 if (n == POPEN_3)\r
3108 {\r
3109 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)\r
3110 PyFile_SetBufSize(p_f[0], bufsize);\r
3111 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);\r
3112 }\r
3113 else\r
3114 f = PyTuple_Pack(2, p_f[0], p_f[1]);\r
3115\r
3116 /*\r
3117 * Insert the files we've created into the process dictionary\r
3118 * all referencing the list with the process handle and the\r
3119 * initial number of files (see description below in _PyPclose).\r
3120 * Since if _PyPclose later tried to wait on a process when all\r
3121 * handles weren't closed, it could create a deadlock with the\r
3122 * child, we spend some energy here to try to ensure that we\r
3123 * either insert all file handles into the dictionary or none\r
3124 * at all. It's a little clumsy with the various popen modes\r
3125 * and variable number of files involved.\r
3126 */\r
3127 if (!_PyPopenProcs)\r
3128 {\r
3129 _PyPopenProcs = PyDict_New();\r
3130 }\r
3131\r
3132 if (_PyPopenProcs)\r
3133 {\r
3134 PyObject *procObj, *pidObj, *intObj, *fileObj[3];\r
3135 int ins_rc[3];\r
3136\r
3137 fileObj[0] = fileObj[1] = fileObj[2] = NULL;\r
3138 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;\r
3139\r
3140 procObj = PyList_New(2);\r
3141 pidObj = PyLong_FromPid(pipe_pid);\r
3142 intObj = PyInt_FromLong((long) file_count);\r
3143\r
3144 if (procObj && pidObj && intObj)\r
3145 {\r
3146 PyList_SetItem(procObj, 0, pidObj);\r
3147 PyList_SetItem(procObj, 1, intObj);\r
3148\r
3149 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);\r
3150 if (fileObj[0])\r
3151 {\r
3152 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,\r
3153 fileObj[0],\r
3154 procObj);\r
3155 }\r
3156 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);\r
3157 if (fileObj[1])\r
3158 {\r
3159 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,\r
3160 fileObj[1],\r
3161 procObj);\r
3162 }\r
3163 if (file_count >= 3)\r
3164 {\r
3165 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);\r
3166 if (fileObj[2])\r
3167 {\r
3168 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,\r
3169 fileObj[2],\r
3170 procObj);\r
3171 }\r
3172 }\r
3173\r
3174 if (ins_rc[0] < 0 || !fileObj[0] ||\r
3175 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||\r
3176 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))\r
3177 {\r
3178 /* Something failed - remove any dictionary\r
3179 * entries that did make it.\r
3180 */\r
3181 if (!ins_rc[0] && fileObj[0])\r
3182 {\r
3183 PyDict_DelItem(_PyPopenProcs,\r
3184 fileObj[0]);\r
3185 }\r
3186 if (!ins_rc[1] && fileObj[1])\r
3187 {\r
3188 PyDict_DelItem(_PyPopenProcs,\r
3189 fileObj[1]);\r
3190 }\r
3191 if (!ins_rc[2] && fileObj[2])\r
3192 {\r
3193 PyDict_DelItem(_PyPopenProcs,\r
3194 fileObj[2]);\r
3195 }\r
3196 }\r
3197 }\r
3198\r
3199 /*\r
3200 * Clean up our localized references for the dictionary keys\r
3201 * and value since PyDict_SetItem will Py_INCREF any copies\r
3202 * that got placed in the dictionary.\r
3203 */\r
3204 Py_XDECREF(procObj);\r
3205 Py_XDECREF(fileObj[0]);\r
3206 Py_XDECREF(fileObj[1]);\r
3207 Py_XDECREF(fileObj[2]);\r
3208 }\r
3209\r
3210 /* Child is launched. */\r
3211 return f;\r
3212}\r
3213\r
3214/*\r
3215 * Wrapper for fclose() to use for popen* files, so we can retrieve the\r
3216 * exit code for the child process and return as a result of the close.\r
3217 *\r
3218 * This function uses the _PyPopenProcs dictionary in order to map the\r
3219 * input file pointer to information about the process that was\r
3220 * originally created by the popen* call that created the file pointer.\r
3221 * The dictionary uses the file pointer as a key (with one entry\r
3222 * inserted for each file returned by the original popen* call) and a\r
3223 * single list object as the value for all files from a single call.\r
3224 * The list object contains the Win32 process handle at [0], and a file\r
3225 * count at [1], which is initialized to the total number of file\r
3226 * handles using that list.\r
3227 *\r
3228 * This function closes whichever handle it is passed, and decrements\r
3229 * the file count in the dictionary for the process handle pointed to\r
3230 * by this file. On the last close (when the file count reaches zero),\r
3231 * this function will wait for the child process and then return its\r
3232 * exit code as the result of the close() operation. This permits the\r
3233 * files to be closed in any order - it is always the close() of the\r
3234 * final handle that will return the exit code.\r
3235 *\r
3236 * NOTE: This function is currently called with the GIL released.\r
3237 * hence we use the GILState API to manage our state.\r
3238 */\r
3239\r
3240static int _PyPclose(FILE *file)\r
3241{\r
3242 int result;\r
3243 int exit_code;\r
3244 pid_t pipe_pid;\r
3245 PyObject *procObj, *pidObj, *intObj, *fileObj;\r
3246 int file_count;\r
3247#ifdef WITH_THREAD\r
3248 PyGILState_STATE state;\r
3249#endif\r
3250\r
3251 /* Close the file handle first, to ensure it can't block the\r
3252 * child from exiting if it's the last handle.\r
3253 */\r
3254 result = fclose(file);\r
3255\r
3256#ifdef WITH_THREAD\r
3257 state = PyGILState_Ensure();\r
3258#endif\r
3259 if (_PyPopenProcs)\r
3260 {\r
3261 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&\r
3262 (procObj = PyDict_GetItem(_PyPopenProcs,\r
3263 fileObj)) != NULL &&\r
3264 (pidObj = PyList_GetItem(procObj,0)) != NULL &&\r
3265 (intObj = PyList_GetItem(procObj,1)) != NULL)\r
3266 {\r
3267 pipe_pid = (pid_t) PyLong_AsPid(pidObj);\r
3268 file_count = (int) PyInt_AsLong(intObj);\r
3269\r
3270 if (file_count > 1)\r
3271 {\r
3272 /* Still other files referencing process */\r
3273 file_count--;\r
3274 PyList_SetItem(procObj,1,\r
3275 PyInt_FromLong((long) file_count));\r
3276 }\r
3277 else\r
3278 {\r
3279 /* Last file for this process */\r
3280 if (result != EOF &&\r
3281 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)\r
3282 {\r
3283 /* extract exit status */\r
3284 if (WIFEXITED(exit_code))\r
3285 {\r
3286 result = WEXITSTATUS(exit_code);\r
3287 }\r
3288 else\r
3289 {\r
3290 errno = EPIPE;\r
3291 result = -1;\r
3292 }\r
3293 }\r
3294 else\r
3295 {\r
3296 /* Indicate failure - this will cause the file object\r
3297 * to raise an I/O error and translate the last\r
3298 * error code from errno. We do have a problem with\r
3299 * last errors that overlap the normal errno table,\r
3300 * but that's a consistent problem with the file object.\r
3301 */\r
3302 result = -1;\r
3303 }\r
3304 }\r
3305\r
3306 /* Remove this file pointer from dictionary */\r
3307 PyDict_DelItem(_PyPopenProcs, fileObj);\r
3308\r
3309 if (PyDict_Size(_PyPopenProcs) == 0)\r
3310 {\r
3311 Py_DECREF(_PyPopenProcs);\r
3312 _PyPopenProcs = NULL;\r
3313 }\r
3314\r
3315 } /* if object retrieval ok */\r
3316\r
3317 Py_XDECREF(fileObj);\r
3318 } /* if _PyPopenProcs */\r
3319\r
3320#ifdef WITH_THREAD\r
3321 PyGILState_Release(state);\r
3322#endif\r
3323 return result;\r
3324}\r
3325\r
3326#endif /* PYCC_??? */\r
3327\r
3328#elif defined(MS_WINDOWS)\r
3329\r
3330/*\r
3331 * Portable 'popen' replacement for Win32.\r
3332 *\r
3333 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks\r
3334 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>\r
3335 * Return code handling by David Bolen <db3l@fitlinxx.com>.\r
3336 */\r
3337\r
3338#include <malloc.h>\r
3339#include <io.h>\r
3340#include <fcntl.h>\r
3341\r
3342/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */\r
3343#define POPEN_1 1\r
3344#define POPEN_2 2\r
3345#define POPEN_3 3\r
3346#define POPEN_4 4\r
3347\r
3348static PyObject *_PyPopen(char *, int, int);\r
3349static int _PyPclose(FILE *file);\r
3350\r
3351/*\r
3352 * Internal dictionary mapping popen* file pointers to process handles,\r
3353 * for use when retrieving the process exit code. See _PyPclose() below\r
3354 * for more information on this dictionary's use.\r
3355 */\r
3356static PyObject *_PyPopenProcs = NULL;\r
3357\r
3358\r
3359/* popen that works from a GUI.\r
3360 *\r
3361 * The result of this function is a pipe (file) connected to the\r
3362 * processes stdin or stdout, depending on the requested mode.\r
3363 */\r
3364\r
3365static PyObject *\r
3366posix_popen(PyObject *self, PyObject *args)\r
3367{\r
3368 PyObject *f;\r
3369 int tm = 0;\r
3370\r
3371 char *cmdstring;\r
3372 char *mode = "r";\r
3373 int bufsize = -1;\r
3374 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))\r
3375 return NULL;\r
3376\r
3377 if (*mode == 'r')\r
3378 tm = _O_RDONLY;\r
3379 else if (*mode != 'w') {\r
3380 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");\r
3381 return NULL;\r
3382 } else\r
3383 tm = _O_WRONLY;\r
3384\r
3385 if (bufsize != -1) {\r
3386 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");\r
3387 return NULL;\r
3388 }\r
3389\r
3390 if (*(mode+1) == 't')\r
3391 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);\r
3392 else if (*(mode+1) == 'b')\r
3393 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);\r
3394 else\r
3395 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);\r
3396\r
3397 return f;\r
3398}\r
3399\r
3400/* Variation on win32pipe.popen\r
3401 *\r
3402 * The result of this function is a pipe (file) connected to the\r
3403 * process's stdin, and a pipe connected to the process's stdout.\r
3404 */\r
3405\r
3406static PyObject *\r
3407win32_popen2(PyObject *self, PyObject *args)\r
3408{\r
3409 PyObject *f;\r
3410 int tm=0;\r
3411\r
3412 char *cmdstring;\r
3413 char *mode = "t";\r
3414 int bufsize = -1;\r
3415 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))\r
3416 return NULL;\r
3417\r
3418 if (*mode == 't')\r
3419 tm = _O_TEXT;\r
3420 else if (*mode != 'b') {\r
3421 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");\r
3422 return NULL;\r
3423 } else\r
3424 tm = _O_BINARY;\r
3425\r
3426 if (bufsize != -1) {\r
3427 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");\r
3428 return NULL;\r
3429 }\r
3430\r
3431 f = _PyPopen(cmdstring, tm, POPEN_2);\r
3432\r
3433 return f;\r
3434}\r
3435\r
3436/*\r
3437 * Variation on <om win32pipe.popen>\r
3438 *\r
3439 * The result of this function is 3 pipes - the process's stdin,\r
3440 * stdout and stderr\r
3441 */\r
3442\r
3443static PyObject *\r
3444win32_popen3(PyObject *self, PyObject *args)\r
3445{\r
3446 PyObject *f;\r
3447 int tm = 0;\r
3448\r
3449 char *cmdstring;\r
3450 char *mode = "t";\r
3451 int bufsize = -1;\r
3452 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))\r
3453 return NULL;\r
3454\r
3455 if (*mode == 't')\r
3456 tm = _O_TEXT;\r
3457 else if (*mode != 'b') {\r
3458 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");\r
3459 return NULL;\r
3460 } else\r
3461 tm = _O_BINARY;\r
3462\r
3463 if (bufsize != -1) {\r
3464 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");\r
3465 return NULL;\r
3466 }\r
3467\r
3468 f = _PyPopen(cmdstring, tm, POPEN_3);\r
3469\r
3470 return f;\r
3471}\r
3472\r
3473/*\r
3474 * Variation on win32pipe.popen\r
3475 *\r
3476 * The result of this function is 2 pipes - the processes stdin,\r
3477 * and stdout+stderr combined as a single pipe.\r
3478 */\r
3479\r
3480static PyObject *\r
3481win32_popen4(PyObject *self, PyObject *args)\r
3482{\r
3483 PyObject *f;\r
3484 int tm = 0;\r
3485\r
3486 char *cmdstring;\r
3487 char *mode = "t";\r
3488 int bufsize = -1;\r
3489 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))\r
3490 return NULL;\r
3491\r
3492 if (*mode == 't')\r
3493 tm = _O_TEXT;\r
3494 else if (*mode != 'b') {\r
3495 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");\r
3496 return NULL;\r
3497 } else\r
3498 tm = _O_BINARY;\r
3499\r
3500 if (bufsize != -1) {\r
3501 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");\r
3502 return NULL;\r
3503 }\r
3504\r
3505 f = _PyPopen(cmdstring, tm, POPEN_4);\r
3506\r
3507 return f;\r
3508}\r
3509\r
3510static BOOL\r
3511_PyPopenCreateProcess(char *cmdstring,\r
3512 HANDLE hStdin,\r
3513 HANDLE hStdout,\r
3514 HANDLE hStderr,\r
3515 HANDLE *hProcess)\r
3516{\r
3517 PROCESS_INFORMATION piProcInfo;\r
3518 STARTUPINFO siStartInfo;\r
3519 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */\r
3520 char *s1,*s2, *s3 = " /c ";\r
3521 const char *szConsoleSpawn = "w9xpopen.exe";\r
3522 int i;\r
3523 Py_ssize_t x;\r
3524\r
3525 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {\r
3526 char *comshell;\r
3527\r
3528 s1 = (char *)alloca(i);\r
3529 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))\r
3530 /* x < i, so x fits into an integer */\r
3531 return (int)x;\r
3532\r
3533 /* Explicitly check if we are using COMMAND.COM. If we are\r
3534 * then use the w9xpopen hack.\r
3535 */\r
3536 comshell = s1 + x;\r
3537 while (comshell >= s1 && *comshell != '\\')\r
3538 --comshell;\r
3539 ++comshell;\r
3540\r
3541 if (GetVersion() < 0x80000000 &&\r
3542 _stricmp(comshell, "command.com") != 0) {\r
3543 /* NT/2000 and not using command.com. */\r
3544 x = i + strlen(s3) + strlen(cmdstring) + 1;\r
3545 s2 = (char *)alloca(x);\r
3546 ZeroMemory(s2, x);\r
3547 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);\r
3548 }\r
3549 else {\r
3550 /*\r
3551 * Oh gag, we're on Win9x or using COMMAND.COM. Use\r
3552 * the workaround listed in KB: Q150956\r
3553 */\r
3554 char modulepath[_MAX_PATH];\r
3555 struct stat statinfo;\r
3556 GetModuleFileName(NULL, modulepath, sizeof(modulepath));\r
3557 for (x = i = 0; modulepath[i]; i++)\r
3558 if (modulepath[i] == SEP)\r
3559 x = i+1;\r
3560 modulepath[x] = '\0';\r
3561 /* Create the full-name to w9xpopen, so we can test it exists */\r
3562 strncat(modulepath,\r
3563 szConsoleSpawn,\r
3564 (sizeof(modulepath)/sizeof(modulepath[0]))\r
3565 -strlen(modulepath));\r
3566 if (stat(modulepath, &statinfo) != 0) {\r
3567 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);\r
3568 /* Eeek - file-not-found - possibly an embedding\r
3569 situation - see if we can locate it in sys.prefix\r
3570 */\r
3571 strncpy(modulepath,\r
3572 Py_GetExecPrefix(),\r
3573 mplen);\r
3574 modulepath[mplen-1] = '\0';\r
3575 if (modulepath[strlen(modulepath)-1] != '\\')\r
3576 strcat(modulepath, "\\");\r
3577 strncat(modulepath,\r
3578 szConsoleSpawn,\r
3579 mplen-strlen(modulepath));\r
3580 /* No where else to look - raise an easily identifiable\r
3581 error, rather than leaving Windows to report\r
3582 "file not found" - as the user is probably blissfully\r
3583 unaware this shim EXE is used, and it will confuse them.\r
3584 (well, it confused me for a while ;-)\r
3585 */\r
3586 if (stat(modulepath, &statinfo) != 0) {\r
3587 PyErr_Format(PyExc_RuntimeError,\r
3588 "Can not locate '%s' which is needed "\r
3589 "for popen to work with your shell "\r
3590 "or platform.",\r
3591 szConsoleSpawn);\r
3592 return FALSE;\r
3593 }\r
3594 }\r
3595 x = i + strlen(s3) + strlen(cmdstring) + 1 +\r
3596 strlen(modulepath) +\r
3597 strlen(szConsoleSpawn) + 1;\r
3598\r
3599 s2 = (char *)alloca(x);\r
3600 ZeroMemory(s2, x);\r
3601 /* To maintain correct argument passing semantics,\r
3602 we pass the command-line as it stands, and allow\r
3603 quoting to be applied. w9xpopen.exe will then\r
3604 use its argv vector, and re-quote the necessary\r
3605 args for the ultimate child process.\r
3606 */\r
3607 PyOS_snprintf(\r
3608 s2, x,\r
3609 "\"%s\" %s%s%s",\r
3610 modulepath,\r
3611 s1,\r
3612 s3,\r
3613 cmdstring);\r
3614 /* Not passing CREATE_NEW_CONSOLE has been known to\r
3615 cause random failures on win9x. Specifically a\r
3616 dialog:\r
3617 "Your program accessed mem currently in use at xxx"\r
3618 and a hopeful warning about the stability of your\r
3619 system.\r
3620 Cost is Ctrl+C won't kill children, but anyone\r
3621 who cares can have a go!\r
3622 */\r
3623 dwProcessFlags |= CREATE_NEW_CONSOLE;\r
3624 }\r
3625 }\r
3626\r
3627 /* Could be an else here to try cmd.exe / command.com in the path\r
3628 Now we'll just error out.. */\r
3629 else {\r
3630 PyErr_SetString(PyExc_RuntimeError,\r
3631 "Cannot locate a COMSPEC environment variable to "\r
3632 "use as the shell");\r
3633 return FALSE;\r
3634 }\r
3635\r
3636 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));\r
3637 siStartInfo.cb = sizeof(STARTUPINFO);\r
3638 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;\r
3639 siStartInfo.hStdInput = hStdin;\r
3640 siStartInfo.hStdOutput = hStdout;\r
3641 siStartInfo.hStdError = hStderr;\r
3642 siStartInfo.wShowWindow = SW_HIDE;\r
3643\r
3644 if (CreateProcess(NULL,\r
3645 s2,\r
3646 NULL,\r
3647 NULL,\r
3648 TRUE,\r
3649 dwProcessFlags,\r
3650 NULL,\r
3651 NULL,\r
3652 &siStartInfo,\r
3653 &piProcInfo) ) {\r
3654 /* Close the handles now so anyone waiting is woken. */\r
3655 CloseHandle(piProcInfo.hThread);\r
3656\r
3657 /* Return process handle */\r
3658 *hProcess = piProcInfo.hProcess;\r
3659 return TRUE;\r
3660 }\r
3661 win32_error("CreateProcess", s2);\r
3662 return FALSE;\r
3663}\r
3664\r
3665/* The following code is based off of KB: Q190351 */\r
3666\r
3667static PyObject *\r
3668_PyPopen(char *cmdstring, int mode, int n)\r
3669{\r
3670 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,\r
3671 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,\r
3672 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */\r
3673\r
3674 SECURITY_ATTRIBUTES saAttr;\r
3675 BOOL fSuccess;\r
3676 int fd1, fd2, fd3;\r
3677 FILE *f1, *f2, *f3;\r
3678 long file_count;\r
3679 PyObject *f;\r
3680\r
3681 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);\r
3682 saAttr.bInheritHandle = TRUE;\r
3683 saAttr.lpSecurityDescriptor = NULL;\r
3684\r
3685 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))\r
3686 return win32_error("CreatePipe", NULL);\r
3687\r
3688 /* Create new output read handle and the input write handle. Set\r
3689 * the inheritance properties to FALSE. Otherwise, the child inherits\r
3690 * these handles; resulting in non-closeable handles to the pipes\r
3691 * being created. */\r
3692 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,\r
3693 GetCurrentProcess(), &hChildStdinWrDup, 0,\r
3694 FALSE,\r
3695 DUPLICATE_SAME_ACCESS);\r
3696 if (!fSuccess)\r
3697 return win32_error("DuplicateHandle", NULL);\r
3698\r
3699 /* Close the inheritable version of ChildStdin\r
3700 that we're using. */\r
3701 CloseHandle(hChildStdinWr);\r
3702\r
3703 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))\r
3704 return win32_error("CreatePipe", NULL);\r
3705\r
3706 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,\r
3707 GetCurrentProcess(), &hChildStdoutRdDup, 0,\r
3708 FALSE, DUPLICATE_SAME_ACCESS);\r
3709 if (!fSuccess)\r
3710 return win32_error("DuplicateHandle", NULL);\r
3711\r
3712 /* Close the inheritable version of ChildStdout\r
3713 that we're using. */\r
3714 CloseHandle(hChildStdoutRd);\r
3715\r
3716 if (n != POPEN_4) {\r
3717 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))\r
3718 return win32_error("CreatePipe", NULL);\r
3719 fSuccess = DuplicateHandle(GetCurrentProcess(),\r
3720 hChildStderrRd,\r
3721 GetCurrentProcess(),\r
3722 &hChildStderrRdDup, 0,\r
3723 FALSE, DUPLICATE_SAME_ACCESS);\r
3724 if (!fSuccess)\r
3725 return win32_error("DuplicateHandle", NULL);\r
3726 /* Close the inheritable version of ChildStdErr that we're using. */\r
3727 CloseHandle(hChildStderrRd);\r
3728 }\r
3729\r
3730 switch (n) {\r
3731 case POPEN_1:\r
3732 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {\r
3733 case _O_WRONLY | _O_TEXT:\r
3734 /* Case for writing to child Stdin in text mode. */\r
3735 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);\r
3736 f1 = _fdopen(fd1, "w");\r
3737 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);\r
3738 PyFile_SetBufSize(f, 0);\r
3739 /* We don't care about these pipes anymore, so close them. */\r
3740 CloseHandle(hChildStdoutRdDup);\r
3741 CloseHandle(hChildStderrRdDup);\r
3742 break;\r
3743\r
3744 case _O_RDONLY | _O_TEXT:\r
3745 /* Case for reading from child Stdout in text mode. */\r
3746 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);\r
3747 f1 = _fdopen(fd1, "r");\r
3748 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);\r
3749 PyFile_SetBufSize(f, 0);\r
3750 /* We don't care about these pipes anymore, so close them. */\r
3751 CloseHandle(hChildStdinWrDup);\r
3752 CloseHandle(hChildStderrRdDup);\r
3753 break;\r
3754\r
3755 case _O_RDONLY | _O_BINARY:\r
3756 /* Case for readinig from child Stdout in binary mode. */\r
3757 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);\r
3758 f1 = _fdopen(fd1, "rb");\r
3759 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);\r
3760 PyFile_SetBufSize(f, 0);\r
3761 /* We don't care about these pipes anymore, so close them. */\r
3762 CloseHandle(hChildStdinWrDup);\r
3763 CloseHandle(hChildStderrRdDup);\r
3764 break;\r
3765\r
3766 case _O_WRONLY | _O_BINARY:\r
3767 /* Case for writing to child Stdin in binary mode. */\r
3768 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);\r
3769 f1 = _fdopen(fd1, "wb");\r
3770 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);\r
3771 PyFile_SetBufSize(f, 0);\r
3772 /* We don't care about these pipes anymore, so close them. */\r
3773 CloseHandle(hChildStdoutRdDup);\r
3774 CloseHandle(hChildStderrRdDup);\r
3775 break;\r
3776 }\r
3777 file_count = 1;\r
3778 break;\r
3779\r
3780 case POPEN_2:\r
3781 case POPEN_4:\r
3782 {\r
3783 char *m1, *m2;\r
3784 PyObject *p1, *p2;\r
3785\r
3786 if (mode & _O_TEXT) {\r
3787 m1 = "r";\r
3788 m2 = "w";\r
3789 } else {\r
3790 m1 = "rb";\r
3791 m2 = "wb";\r
3792 }\r
3793\r
3794 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);\r
3795 f1 = _fdopen(fd1, m2);\r
3796 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);\r
3797 f2 = _fdopen(fd2, m1);\r
3798 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);\r
3799 PyFile_SetBufSize(p1, 0);\r
3800 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);\r
3801 PyFile_SetBufSize(p2, 0);\r
3802\r
3803 if (n != 4)\r
3804 CloseHandle(hChildStderrRdDup);\r
3805\r
3806 f = PyTuple_Pack(2,p1,p2);\r
3807 Py_XDECREF(p1);\r
3808 Py_XDECREF(p2);\r
3809 file_count = 2;\r
3810 break;\r
3811 }\r
3812\r
3813 case POPEN_3:\r
3814 {\r
3815 char *m1, *m2;\r
3816 PyObject *p1, *p2, *p3;\r
3817\r
3818 if (mode & _O_TEXT) {\r
3819 m1 = "r";\r
3820 m2 = "w";\r
3821 } else {\r
3822 m1 = "rb";\r
3823 m2 = "wb";\r
3824 }\r
3825\r
3826 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);\r
3827 f1 = _fdopen(fd1, m2);\r
3828 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);\r
3829 f2 = _fdopen(fd2, m1);\r
3830 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);\r
3831 f3 = _fdopen(fd3, m1);\r
3832 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);\r
3833 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);\r
3834 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);\r
3835 PyFile_SetBufSize(p1, 0);\r
3836 PyFile_SetBufSize(p2, 0);\r
3837 PyFile_SetBufSize(p3, 0);\r
3838 f = PyTuple_Pack(3,p1,p2,p3);\r
3839 Py_XDECREF(p1);\r
3840 Py_XDECREF(p2);\r
3841 Py_XDECREF(p3);\r
3842 file_count = 3;\r
3843 break;\r
3844 }\r
3845 }\r
3846\r
3847 if (n == POPEN_4) {\r
3848 if (!_PyPopenCreateProcess(cmdstring,\r
3849 hChildStdinRd,\r
3850 hChildStdoutWr,\r
3851 hChildStdoutWr,\r
3852 &hProcess))\r
3853 return NULL;\r
3854 }\r
3855 else {\r
3856 if (!_PyPopenCreateProcess(cmdstring,\r
3857 hChildStdinRd,\r
3858 hChildStdoutWr,\r
3859 hChildStderrWr,\r
3860 &hProcess))\r
3861 return NULL;\r
3862 }\r
3863\r
3864 /*\r
3865 * Insert the files we've created into the process dictionary\r
3866 * all referencing the list with the process handle and the\r
3867 * initial number of files (see description below in _PyPclose).\r
3868 * Since if _PyPclose later tried to wait on a process when all\r
3869 * handles weren't closed, it could create a deadlock with the\r
3870 * child, we spend some energy here to try to ensure that we\r
3871 * either insert all file handles into the dictionary or none\r
3872 * at all. It's a little clumsy with the various popen modes\r
3873 * and variable number of files involved.\r
3874 */\r
3875 if (!_PyPopenProcs) {\r
3876 _PyPopenProcs = PyDict_New();\r
3877 }\r
3878\r
3879 if (_PyPopenProcs) {\r
3880 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];\r
3881 int ins_rc[3];\r
3882\r
3883 fileObj[0] = fileObj[1] = fileObj[2] = NULL;\r
3884 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;\r
3885\r
3886 procObj = PyList_New(2);\r
3887 hProcessObj = PyLong_FromVoidPtr(hProcess);\r
3888 intObj = PyInt_FromLong(file_count);\r
3889\r
3890 if (procObj && hProcessObj && intObj) {\r
3891 PyList_SetItem(procObj,0,hProcessObj);\r
3892 PyList_SetItem(procObj,1,intObj);\r
3893\r
3894 fileObj[0] = PyLong_FromVoidPtr(f1);\r
3895 if (fileObj[0]) {\r
3896 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,\r
3897 fileObj[0],\r
3898 procObj);\r
3899 }\r
3900 if (file_count >= 2) {\r
3901 fileObj[1] = PyLong_FromVoidPtr(f2);\r
3902 if (fileObj[1]) {\r
3903 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,\r
3904 fileObj[1],\r
3905 procObj);\r
3906 }\r
3907 }\r
3908 if (file_count >= 3) {\r
3909 fileObj[2] = PyLong_FromVoidPtr(f3);\r
3910 if (fileObj[2]) {\r
3911 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,\r
3912 fileObj[2],\r
3913 procObj);\r
3914 }\r
3915 }\r
3916\r
3917 if (ins_rc[0] < 0 || !fileObj[0] ||\r
3918 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||\r
3919 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {\r
3920 /* Something failed - remove any dictionary\r
3921 * entries that did make it.\r
3922 */\r
3923 if (!ins_rc[0] && fileObj[0]) {\r
3924 PyDict_DelItem(_PyPopenProcs,\r
3925 fileObj[0]);\r
3926 }\r
3927 if (!ins_rc[1] && fileObj[1]) {\r
3928 PyDict_DelItem(_PyPopenProcs,\r
3929 fileObj[1]);\r
3930 }\r
3931 if (!ins_rc[2] && fileObj[2]) {\r
3932 PyDict_DelItem(_PyPopenProcs,\r
3933 fileObj[2]);\r
3934 }\r
3935 }\r
3936 }\r
3937\r
3938 /*\r
3939 * Clean up our localized references for the dictionary keys\r
3940 * and value since PyDict_SetItem will Py_INCREF any copies\r
3941 * that got placed in the dictionary.\r
3942 */\r
3943 Py_XDECREF(procObj);\r
3944 Py_XDECREF(fileObj[0]);\r
3945 Py_XDECREF(fileObj[1]);\r
3946 Py_XDECREF(fileObj[2]);\r
3947 }\r
3948\r
3949 /* Child is launched. Close the parents copy of those pipe\r
3950 * handles that only the child should have open. You need to\r
3951 * make sure that no handles to the write end of the output pipe\r
3952 * are maintained in this process or else the pipe will not close\r
3953 * when the child process exits and the ReadFile will hang. */\r
3954\r
3955 if (!CloseHandle(hChildStdinRd))\r
3956 return win32_error("CloseHandle", NULL);\r
3957\r
3958 if (!CloseHandle(hChildStdoutWr))\r
3959 return win32_error("CloseHandle", NULL);\r
3960\r
3961 if ((n != 4) && (!CloseHandle(hChildStderrWr)))\r
3962 return win32_error("CloseHandle", NULL);\r
3963\r
3964 return f;\r
3965}\r
3966\r
3967/*\r
3968 * Wrapper for fclose() to use for popen* files, so we can retrieve the\r
3969 * exit code for the child process and return as a result of the close.\r
3970 *\r
3971 * This function uses the _PyPopenProcs dictionary in order to map the\r
3972 * input file pointer to information about the process that was\r
3973 * originally created by the popen* call that created the file pointer.\r
3974 * The dictionary uses the file pointer as a key (with one entry\r
3975 * inserted for each file returned by the original popen* call) and a\r
3976 * single list object as the value for all files from a single call.\r
3977 * The list object contains the Win32 process handle at [0], and a file\r
3978 * count at [1], which is initialized to the total number of file\r
3979 * handles using that list.\r
3980 *\r
3981 * This function closes whichever handle it is passed, and decrements\r
3982 * the file count in the dictionary for the process handle pointed to\r
3983 * by this file. On the last close (when the file count reaches zero),\r
3984 * this function will wait for the child process and then return its\r
3985 * exit code as the result of the close() operation. This permits the\r
3986 * files to be closed in any order - it is always the close() of the\r
3987 * final handle that will return the exit code.\r
3988 *\r
3989 * NOTE: This function is currently called with the GIL released.\r
3990 * hence we use the GILState API to manage our state.\r
3991 */\r
3992\r
3993static int _PyPclose(FILE *file)\r
3994{\r
3995 int result;\r
3996 DWORD exit_code;\r
3997 HANDLE hProcess;\r
3998 PyObject *procObj, *hProcessObj, *intObj, *fileObj;\r
3999 long file_count;\r
4000#ifdef WITH_THREAD\r
4001 PyGILState_STATE state;\r
4002#endif\r
4003\r
4004 /* Close the file handle first, to ensure it can't block the\r
4005 * child from exiting if it's the last handle.\r
4006 */\r
4007 result = fclose(file);\r
4008#ifdef WITH_THREAD\r
4009 state = PyGILState_Ensure();\r
4010#endif\r
4011 if (_PyPopenProcs) {\r
4012 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&\r
4013 (procObj = PyDict_GetItem(_PyPopenProcs,\r
4014 fileObj)) != NULL &&\r
4015 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&\r
4016 (intObj = PyList_GetItem(procObj,1)) != NULL) {\r
4017\r
4018 hProcess = PyLong_AsVoidPtr(hProcessObj);\r
4019 file_count = PyInt_AsLong(intObj);\r
4020\r
4021 if (file_count > 1) {\r
4022 /* Still other files referencing process */\r
4023 file_count--;\r
4024 PyList_SetItem(procObj,1,\r
4025 PyInt_FromLong(file_count));\r
4026 } else {\r
4027 /* Last file for this process */\r
4028 if (result != EOF &&\r
4029 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&\r
4030 GetExitCodeProcess(hProcess, &exit_code)) {\r
4031 /* Possible truncation here in 16-bit environments, but\r
4032 * real exit codes are just the lower byte in any event.\r
4033 */\r
4034 result = exit_code;\r
4035 } else {\r
4036 /* Indicate failure - this will cause the file object\r
4037 * to raise an I/O error and translate the last Win32\r
4038 * error code from errno. We do have a problem with\r
4039 * last errors that overlap the normal errno table,\r
4040 * but that's a consistent problem with the file object.\r
4041 */\r
4042 if (result != EOF) {\r
4043 /* If the error wasn't from the fclose(), then\r
4044 * set errno for the file object error handling.\r
4045 */\r
4046 errno = GetLastError();\r
4047 }\r
4048 result = -1;\r
4049 }\r
4050\r
4051 /* Free up the native handle at this point */\r
4052 CloseHandle(hProcess);\r
4053 }\r
4054\r
4055 /* Remove this file pointer from dictionary */\r
4056 PyDict_DelItem(_PyPopenProcs, fileObj);\r
4057\r
4058 if (PyDict_Size(_PyPopenProcs) == 0) {\r
4059 Py_DECREF(_PyPopenProcs);\r
4060 _PyPopenProcs = NULL;\r
4061 }\r
4062\r
4063 } /* if object retrieval ok */\r
4064\r
4065 Py_XDECREF(fileObj);\r
4066 } /* if _PyPopenProcs */\r
4067\r
4068#ifdef WITH_THREAD\r
4069 PyGILState_Release(state);\r
4070#endif\r
4071 return result;\r
4072}\r
4073\r
4074#else /* which OS? */\r
4075static PyObject *\r
4076posix_popen(PyObject *self, PyObject *args)\r
4077{\r
4078 char *name;\r
4079 char *mode = "r";\r
4080 int bufsize = -1;\r
4081 FILE *fp;\r
4082 PyObject *f;\r
4083 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))\r
4084 return NULL;\r
4085 /* Strip mode of binary or text modifiers */\r
4086 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)\r
4087 mode = "r";\r
4088 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)\r
4089 mode = "w";\r
4090 Py_BEGIN_ALLOW_THREADS\r
4091 fp = popen(name, mode);\r
4092 Py_END_ALLOW_THREADS\r
4093 if (fp == NULL)\r
4094 return posix_error();\r
4095 f = PyFile_FromFile(fp, name, mode, pclose);\r
4096 if (f != NULL)\r
4097 PyFile_SetBufSize(f, bufsize);\r
4098 return f;\r
4099}\r
4100\r
4101#endif /* PYOS_??? */\r
4102#endif /* HAVE_POPEN */\r
4103\r
4104\r
4105#ifdef HAVE_SETUID\r
4106PyDoc_STRVAR(posix_setuid__doc__,\r
4107"setuid(uid)\n\n\\r
4108Set the current process's user id.");\r
4109\r
4110static PyObject *\r
4111posix_setuid(PyObject *self, PyObject *args)\r
4112{\r
4113 long uid_arg;\r
4114 uid_t uid;\r
4115 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))\r
4116 return NULL;\r
4117 uid = uid_arg;\r
4118 if (uid != uid_arg) {\r
4119 PyErr_SetString(PyExc_OverflowError, "user id too big");\r
4120 return NULL;\r
4121 }\r
4122 if (setuid(uid) < 0)\r
4123 return posix_error();\r
4124 Py_INCREF(Py_None);\r
4125 return Py_None;\r
4126}\r
4127#endif /* HAVE_SETUID */\r
4128\r
4129\r
4130#ifdef HAVE_SETEUID\r
4131PyDoc_STRVAR(posix_seteuid__doc__,\r
4132"seteuid(uid)\n\n\\r
4133Set the current process's effective user id.");\r
4134\r
4135static PyObject *\r
4136posix_seteuid (PyObject *self, PyObject *args)\r
4137{\r
4138 long euid_arg;\r
4139 uid_t euid;\r
4140 if (!PyArg_ParseTuple(args, "l", &euid_arg))\r
4141 return NULL;\r
4142 euid = euid_arg;\r
4143 if (euid != euid_arg) {\r
4144 PyErr_SetString(PyExc_OverflowError, "user id too big");\r
4145 return NULL;\r
4146 }\r
4147 if (seteuid(euid) < 0) {\r
4148 return posix_error();\r
4149 } else {\r
4150 Py_INCREF(Py_None);\r
4151 return Py_None;\r
4152 }\r
4153}\r
4154#endif /* HAVE_SETEUID */\r
4155\r
4156#ifdef HAVE_SETEGID\r
4157PyDoc_STRVAR(posix_setegid__doc__,\r
4158"setegid(gid)\n\n\\r
4159Set the current process's effective group id.");\r
4160\r
4161static PyObject *\r
4162posix_setegid (PyObject *self, PyObject *args)\r
4163{\r
4164 long egid_arg;\r
4165 gid_t egid;\r
4166 if (!PyArg_ParseTuple(args, "l", &egid_arg))\r
4167 return NULL;\r
4168 egid = egid_arg;\r
4169 if (egid != egid_arg) {\r
4170 PyErr_SetString(PyExc_OverflowError, "group id too big");\r
4171 return NULL;\r
4172 }\r
4173 if (setegid(egid) < 0) {\r
4174 return posix_error();\r
4175 } else {\r
4176 Py_INCREF(Py_None);\r
4177 return Py_None;\r
4178 }\r
4179}\r
4180#endif /* HAVE_SETEGID */\r
4181\r
4182#ifdef HAVE_SETREUID\r
4183PyDoc_STRVAR(posix_setreuid__doc__,\r
4184"setreuid(ruid, euid)\n\n\\r
4185Set the current process's real and effective user ids.");\r
4186\r
4187static PyObject *\r
4188posix_setreuid (PyObject *self, PyObject *args)\r
4189{\r
4190 long ruid_arg, euid_arg;\r
4191 uid_t ruid, euid;\r
4192 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))\r
4193 return NULL;\r
4194 if (ruid_arg == -1)\r
4195 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */\r
4196 else\r
4197 ruid = ruid_arg; /* otherwise, assign from our long */\r
4198 if (euid_arg == -1)\r
4199 euid = (uid_t)-1;\r
4200 else\r
4201 euid = euid_arg;\r
4202 if ((euid_arg != -1 && euid != euid_arg) ||\r
4203 (ruid_arg != -1 && ruid != ruid_arg)) {\r
4204 PyErr_SetString(PyExc_OverflowError, "user id too big");\r
4205 return NULL;\r
4206 }\r
4207 if (setreuid(ruid, euid) < 0) {\r
4208 return posix_error();\r
4209 } else {\r
4210 Py_INCREF(Py_None);\r
4211 return Py_None;\r
4212 }\r
4213}\r
4214#endif /* HAVE_SETREUID */\r
4215\r
4216#ifdef HAVE_SETREGID\r
4217PyDoc_STRVAR(posix_setregid__doc__,\r
4218"setregid(rgid, egid)\n\n\\r
4219Set the current process's real and effective group ids.");\r
4220\r
4221static PyObject *\r
4222posix_setregid (PyObject *self, PyObject *args)\r
4223{\r
4224 long rgid_arg, egid_arg;\r
4225 gid_t rgid, egid;\r
4226 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))\r
4227 return NULL;\r
4228 if (rgid_arg == -1)\r
4229 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */\r
4230 else\r
4231 rgid = rgid_arg; /* otherwise, assign from our long */\r
4232 if (egid_arg == -1)\r
4233 egid = (gid_t)-1;\r
4234 else\r
4235 egid = egid_arg;\r
4236 if ((egid_arg != -1 && egid != egid_arg) ||\r
4237 (rgid_arg != -1 && rgid != rgid_arg)) {\r
4238 PyErr_SetString(PyExc_OverflowError, "group id too big");\r
4239 return NULL;\r
4240 }\r
4241 if (setregid(rgid, egid) < 0) {\r
4242 return posix_error();\r
4243 } else {\r
4244 Py_INCREF(Py_None);\r
4245 return Py_None;\r
4246 }\r
4247}\r
4248#endif /* HAVE_SETREGID */\r
4249\r
4250#ifdef HAVE_SETGID\r
4251PyDoc_STRVAR(posix_setgid__doc__,\r
4252"setgid(gid)\n\n\\r
4253Set the current process's group id.");\r
4254\r
4255static PyObject *\r
4256posix_setgid(PyObject *self, PyObject *args)\r
4257{\r
4258 long gid_arg;\r
4259 gid_t gid;\r
4260 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))\r
4261 return NULL;\r
4262 gid = gid_arg;\r
4263 if (gid != gid_arg) {\r
4264 PyErr_SetString(PyExc_OverflowError, "group id too big");\r
4265 return NULL;\r
4266 }\r
4267 if (setgid(gid) < 0)\r
4268 return posix_error();\r
4269 Py_INCREF(Py_None);\r
4270 return Py_None;\r
4271}\r
4272#endif /* HAVE_SETGID */\r
4273\r
4274#ifdef HAVE_SETGROUPS\r
4275PyDoc_STRVAR(posix_setgroups__doc__,\r
4276"setgroups(list)\n\n\\r
4277Set the groups of the current process to list.");\r
4278\r
4279static PyObject *\r
4280posix_setgroups(PyObject *self, PyObject *groups)\r
4281{\r
4282 int i, len;\r
4283 gid_t grouplist[MAX_GROUPS];\r
4284\r
4285 if (!PySequence_Check(groups)) {\r
4286 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");\r
4287 return NULL;\r
4288 }\r
4289 len = PySequence_Size(groups);\r
4290 if (len > MAX_GROUPS) {\r
4291 PyErr_SetString(PyExc_ValueError, "too many groups");\r
4292 return NULL;\r
4293 }\r
4294 for(i = 0; i < len; i++) {\r
4295 PyObject *elem;\r
4296 elem = PySequence_GetItem(groups, i);\r
4297 if (!elem)\r
4298 return NULL;\r
4299 if (!PyInt_Check(elem)) {\r
4300 if (!PyLong_Check(elem)) {\r
4301 PyErr_SetString(PyExc_TypeError,\r
4302 "groups must be integers");\r
4303 Py_DECREF(elem);\r
4304 return NULL;\r
4305 } else {\r
4306 unsigned long x = PyLong_AsUnsignedLong(elem);\r
4307 if (PyErr_Occurred()) {\r
4308 PyErr_SetString(PyExc_TypeError,\r
4309 "group id too big");\r
4310 Py_DECREF(elem);\r
4311 return NULL;\r
4312 }\r
4313 grouplist[i] = x;\r
4314 /* read back to see if it fits in gid_t */\r
4315 if (grouplist[i] != x) {\r
4316 PyErr_SetString(PyExc_TypeError,\r
4317 "group id too big");\r
4318 Py_DECREF(elem);\r
4319 return NULL;\r
4320 }\r
4321 }\r
4322 } else {\r
4323 long x = PyInt_AsLong(elem);\r
4324 grouplist[i] = x;\r
4325 if (grouplist[i] != x) {\r
4326 PyErr_SetString(PyExc_TypeError,\r
4327 "group id too big");\r
4328 Py_DECREF(elem);\r
4329 return NULL;\r
4330 }\r
4331 }\r
4332 Py_DECREF(elem);\r
4333 }\r
4334\r
4335 if (setgroups(len, grouplist) < 0)\r
4336 return posix_error();\r
4337 Py_INCREF(Py_None);\r
4338 return Py_None;\r
4339}\r
4340#endif /* HAVE_SETGROUPS */\r
4341\r
4342#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)\r
4343static PyObject *\r
4344wait_helper(pid_t pid, int status, struct rusage *ru)\r
4345{\r
4346 PyObject *result;\r
4347 static PyObject *struct_rusage;\r
4348\r
4349 if (pid == -1)\r
4350 return posix_error();\r
4351\r
4352 if (struct_rusage == NULL) {\r
4353 PyObject *m = PyImport_ImportModuleNoBlock("resource");\r
4354 if (m == NULL)\r
4355 return NULL;\r
4356 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");\r
4357 Py_DECREF(m);\r
4358 if (struct_rusage == NULL)\r
4359 return NULL;\r
4360 }\r
4361\r
4362 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */\r
4363 result = PyStructSequence_New((PyTypeObject*) struct_rusage);\r
4364 if (!result)\r
4365 return NULL;\r
4366\r
4367#ifndef doubletime\r
4368#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)\r
4369#endif\r
4370\r
4371 PyStructSequence_SET_ITEM(result, 0,\r
4372 PyFloat_FromDouble(doubletime(ru->ru_utime)));\r
4373 PyStructSequence_SET_ITEM(result, 1,\r
4374 PyFloat_FromDouble(doubletime(ru->ru_stime)));\r
4375#define SET_INT(result, index, value)\\r
4376 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))\r
4377 SET_INT(result, 2, ru->ru_maxrss);\r
4378 SET_INT(result, 3, ru->ru_ixrss);\r
4379 SET_INT(result, 4, ru->ru_idrss);\r
4380 SET_INT(result, 5, ru->ru_isrss);\r
4381 SET_INT(result, 6, ru->ru_minflt);\r
4382 SET_INT(result, 7, ru->ru_majflt);\r
4383 SET_INT(result, 8, ru->ru_nswap);\r
4384 SET_INT(result, 9, ru->ru_inblock);\r
4385 SET_INT(result, 10, ru->ru_oublock);\r
4386 SET_INT(result, 11, ru->ru_msgsnd);\r
4387 SET_INT(result, 12, ru->ru_msgrcv);\r
4388 SET_INT(result, 13, ru->ru_nsignals);\r
4389 SET_INT(result, 14, ru->ru_nvcsw);\r
4390 SET_INT(result, 15, ru->ru_nivcsw);\r
4391#undef SET_INT\r
4392\r
4393 if (PyErr_Occurred()) {\r
4394 Py_DECREF(result);\r
4395 return NULL;\r
4396 }\r
4397\r
4398 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);\r
4399}\r
4400#endif /* HAVE_WAIT3 || HAVE_WAIT4 */\r
4401\r
4402#ifdef HAVE_WAIT3\r
4403PyDoc_STRVAR(posix_wait3__doc__,\r
4404"wait3(options) -> (pid, status, rusage)\n\n\\r
4405Wait for completion of a child process.");\r
4406\r
4407static PyObject *\r
4408posix_wait3(PyObject *self, PyObject *args)\r
4409{\r
4410 pid_t pid;\r
4411 int options;\r
4412 struct rusage ru;\r
4413 WAIT_TYPE status;\r
4414 WAIT_STATUS_INT(status) = 0;\r
4415\r
4416 if (!PyArg_ParseTuple(args, "i:wait3", &options))\r
4417 return NULL;\r
4418\r
4419 Py_BEGIN_ALLOW_THREADS\r
4420 pid = wait3(&status, options, &ru);\r
4421 Py_END_ALLOW_THREADS\r
4422\r
4423 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);\r
4424}\r
4425#endif /* HAVE_WAIT3 */\r
4426\r
4427#ifdef HAVE_WAIT4\r
4428PyDoc_STRVAR(posix_wait4__doc__,\r
4429"wait4(pid, options) -> (pid, status, rusage)\n\n\\r
4430Wait for completion of a given child process.");\r
4431\r
4432static PyObject *\r
4433posix_wait4(PyObject *self, PyObject *args)\r
4434{\r
4435 pid_t pid;\r
4436 int options;\r
4437 struct rusage ru;\r
4438 WAIT_TYPE status;\r
4439 WAIT_STATUS_INT(status) = 0;\r
4440\r
4441 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))\r
4442 return NULL;\r
4443\r
4444 Py_BEGIN_ALLOW_THREADS\r
4445 pid = wait4(pid, &status, options, &ru);\r
4446 Py_END_ALLOW_THREADS\r
4447\r
4448 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);\r
4449}\r
4450#endif /* HAVE_WAIT4 */\r
4451\r
4452#ifdef HAVE_WAITPID\r
4453PyDoc_STRVAR(posix_waitpid__doc__,\r
4454"waitpid(pid, options) -> (pid, status)\n\n\\r
4455Wait for completion of a given child process.");\r
4456\r
4457static PyObject *\r
4458posix_waitpid(PyObject *self, PyObject *args)\r
4459{\r
4460 pid_t pid;\r
4461 int options;\r
4462 WAIT_TYPE status;\r
4463 WAIT_STATUS_INT(status) = 0;\r
4464\r
4465 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))\r
4466 return NULL;\r
4467 Py_BEGIN_ALLOW_THREADS\r
4468 pid = waitpid(pid, &status, options);\r
4469 Py_END_ALLOW_THREADS\r
4470 if (pid == -1)\r
4471 return posix_error();\r
4472\r
4473 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));\r
4474}\r
4475\r
4476#elif defined(HAVE_CWAIT)\r
4477\r
4478/* MS C has a variant of waitpid() that's usable for most purposes. */\r
4479PyDoc_STRVAR(posix_waitpid__doc__,\r
4480"waitpid(pid, options) -> (pid, status << 8)\n\n"\r
4481"Wait for completion of a given process. options is ignored on Windows.");\r
4482\r
4483static PyObject *\r
4484posix_waitpid(PyObject *self, PyObject *args)\r
4485{\r
4486 Py_intptr_t pid;\r
4487 int status, options;\r
4488\r
4489 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))\r
4490 return NULL;\r
4491 Py_BEGIN_ALLOW_THREADS\r
4492 pid = _cwait(&status, pid, options);\r
4493 Py_END_ALLOW_THREADS\r
4494 if (pid == -1)\r
4495 return posix_error();\r
4496\r
4497 /* shift the status left a byte so this is more like the POSIX waitpid */\r
4498 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);\r
4499}\r
4500#endif /* HAVE_WAITPID || HAVE_CWAIT */\r
4501\r
4502#ifdef HAVE_WAIT\r
4503PyDoc_STRVAR(posix_wait__doc__,\r
4504"wait() -> (pid, status)\n\n\\r
4505Wait for completion of a child process.");\r
4506\r
4507static PyObject *\r
4508posix_wait(PyObject *self, PyObject *noargs)\r
4509{\r
4510 pid_t pid;\r
4511 WAIT_TYPE status;\r
4512 WAIT_STATUS_INT(status) = 0;\r
4513\r
4514 Py_BEGIN_ALLOW_THREADS\r
4515 pid = wait(&status);\r
4516 Py_END_ALLOW_THREADS\r
4517 if (pid == -1)\r
4518 return posix_error();\r
4519\r
4520 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));\r
4521}\r
4522#endif\r
4523\r
4524\r
4525PyDoc_STRVAR(posix_lstat__doc__,\r
4526"lstat(path) -> stat result\n\n\\r
4527Like stat(path), but do not follow symbolic links.");\r
4528\r
4529static PyObject *\r
4530posix_lstat(PyObject *self, PyObject *args)\r
4531{\r
4532#ifdef HAVE_LSTAT\r
4533 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);\r
4534#else /* !HAVE_LSTAT */\r
4535 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);\r
4536#endif /* !HAVE_LSTAT */\r
4537}\r
4538\r
4539\r
4540#ifdef HAVE_READLINK\r
4541PyDoc_STRVAR(posix_readlink__doc__,\r
4542"readlink(path) -> path\n\n\\r
4543Return a string representing the path to which the symbolic link points.");\r
4544\r
4545static PyObject *\r
4546posix_readlink(PyObject *self, PyObject *args)\r
4547{\r
4548 PyObject* v;\r
4549 char buf[MAXPATHLEN];\r
4550 char *path;\r
4551 int n;\r
4552#ifdef Py_USING_UNICODE\r
4553 int arg_is_unicode = 0;\r
4554#endif\r
4555\r
4556 if (!PyArg_ParseTuple(args, "et:readlink",\r
4557 Py_FileSystemDefaultEncoding, &path))\r
4558 return NULL;\r
4559#ifdef Py_USING_UNICODE\r
4560 v = PySequence_GetItem(args, 0);\r
4561 if (v == NULL) {\r
4562 PyMem_Free(path);\r
4563 return NULL;\r
4564 }\r
4565\r
4566 if (PyUnicode_Check(v)) {\r
4567 arg_is_unicode = 1;\r
4568 }\r
4569 Py_DECREF(v);\r
4570#endif\r
4571\r
4572 Py_BEGIN_ALLOW_THREADS\r
4573 n = readlink(path, buf, (int) sizeof buf);\r
4574 Py_END_ALLOW_THREADS\r
4575 if (n < 0)\r
4576 return posix_error_with_allocated_filename(path);\r
4577\r
4578 PyMem_Free(path);\r
4579 v = PyString_FromStringAndSize(buf, n);\r
4580#ifdef Py_USING_UNICODE\r
4581 if (arg_is_unicode) {\r
4582 PyObject *w;\r
4583\r
4584 w = PyUnicode_FromEncodedObject(v,\r
4585 Py_FileSystemDefaultEncoding,\r
4586 "strict");\r
4587 if (w != NULL) {\r
4588 Py_DECREF(v);\r
4589 v = w;\r
4590 }\r
4591 else {\r
4592 /* fall back to the original byte string, as\r
4593 discussed in patch #683592 */\r
4594 PyErr_Clear();\r
4595 }\r
4596 }\r
4597#endif\r
4598 return v;\r
4599}\r
4600#endif /* HAVE_READLINK */\r
4601\r
4602\r
4603#ifdef HAVE_SYMLINK\r
4604PyDoc_STRVAR(posix_symlink__doc__,\r
4605"symlink(src, dst)\n\n\\r
4606Create a symbolic link pointing to src named dst.");\r
4607\r
4608static PyObject *\r
4609posix_symlink(PyObject *self, PyObject *args)\r
4610{\r
4611 return posix_2str(args, "etet:symlink", symlink);\r
4612}\r
4613#endif /* HAVE_SYMLINK */\r
4614\r
4615\r
4616#ifdef HAVE_TIMES\r
4617#if defined(PYCC_VACPP) && defined(PYOS_OS2)\r
4618static long\r
4619system_uptime(void)\r
4620{\r
4621 ULONG value = 0;\r
4622\r
4623 Py_BEGIN_ALLOW_THREADS\r
4624 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));\r
4625 Py_END_ALLOW_THREADS\r
4626\r
4627 return value;\r
4628}\r
4629\r
4630static PyObject *\r
4631posix_times(PyObject *self, PyObject *noargs)\r
4632{\r
4633 /* Currently Only Uptime is Provided -- Others Later */\r
4634 return Py_BuildValue("ddddd",\r
4635 (double)0 /* t.tms_utime / HZ */,\r
4636 (double)0 /* t.tms_stime / HZ */,\r
4637 (double)0 /* t.tms_cutime / HZ */,\r
4638 (double)0 /* t.tms_cstime / HZ */,\r
4639 (double)system_uptime() / 1000);\r
4640}\r
4641#else /* not OS2 */\r
4642#define NEED_TICKS_PER_SECOND\r
4643static long ticks_per_second = -1;\r
4644static PyObject *\r
4645posix_times(PyObject *self, PyObject *noargs)\r
4646{\r
4647 struct tms t;\r
4648 clock_t c;\r
4649 errno = 0;\r
4650 c = times(&t);\r
4651 if (c == (clock_t) -1)\r
4652 return posix_error();\r
4653 return Py_BuildValue("ddddd",\r
4654 (double)t.tms_utime / ticks_per_second,\r
4655 (double)t.tms_stime / ticks_per_second,\r
4656 (double)t.tms_cutime / ticks_per_second,\r
4657 (double)t.tms_cstime / ticks_per_second,\r
4658 (double)c / ticks_per_second);\r
4659}\r
4660#endif /* not OS2 */\r
4661#endif /* HAVE_TIMES */\r
4662\r
4663\r
4664#ifdef HAVE_TIMES\r
4665PyDoc_STRVAR(posix_times__doc__,\r
4666"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\\r
4667Return a tuple of floating point numbers indicating process times.");\r
4668#endif\r
4669\r
4670\r
4671#ifdef HAVE_GETSID\r
4672PyDoc_STRVAR(posix_getsid__doc__,\r
4673"getsid(pid) -> sid\n\n\\r
4674Call the system call getsid().");\r
4675\r
4676static PyObject *\r
4677posix_getsid(PyObject *self, PyObject *args)\r
4678{\r
4679 pid_t pid;\r
4680 int sid;\r
4681 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))\r
4682 return NULL;\r
4683 sid = getsid(pid);\r
4684 if (sid < 0)\r
4685 return posix_error();\r
4686 return PyInt_FromLong((long)sid);\r
4687}\r
4688#endif /* HAVE_GETSID */\r
4689\r
4690\r
4691#ifdef HAVE_SETSID\r
4692PyDoc_STRVAR(posix_setsid__doc__,\r
4693"setsid()\n\n\\r
4694Call the system call setsid().");\r
4695\r
4696static PyObject *\r
4697posix_setsid(PyObject *self, PyObject *noargs)\r
4698{\r
4699 if (setsid() < 0)\r
4700 return posix_error();\r
4701 Py_INCREF(Py_None);\r
4702 return Py_None;\r
4703}\r
4704#endif /* HAVE_SETSID */\r
4705\r
4706#ifdef HAVE_SETPGID\r
4707PyDoc_STRVAR(posix_setpgid__doc__,\r
4708"setpgid(pid, pgrp)\n\n\\r
4709Call the system call setpgid().");\r
4710\r
4711static PyObject *\r
4712posix_setpgid(PyObject *self, PyObject *args)\r
4713{\r
4714 pid_t pid;\r
4715 int pgrp;\r
4716 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))\r
4717 return NULL;\r
4718 if (setpgid(pid, pgrp) < 0)\r
4719 return posix_error();\r
4720 Py_INCREF(Py_None);\r
4721 return Py_None;\r
4722}\r
4723#endif /* HAVE_SETPGID */\r
4724\r
4725\r
4726#ifdef HAVE_TCGETPGRP\r
4727PyDoc_STRVAR(posix_tcgetpgrp__doc__,\r
4728"tcgetpgrp(fd) -> pgid\n\n\\r
4729Return the process group associated with the terminal given by a fd.");\r
4730\r
4731static PyObject *\r
4732posix_tcgetpgrp(PyObject *self, PyObject *args)\r
4733{\r
4734 int fd;\r
4735 pid_t pgid;\r
4736 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))\r
4737 return NULL;\r
4738 pgid = tcgetpgrp(fd);\r
4739 if (pgid < 0)\r
4740 return posix_error();\r
4741 return PyLong_FromPid(pgid);\r
4742}\r
4743#endif /* HAVE_TCGETPGRP */\r
4744\r
4745\r
4746#ifdef HAVE_TCSETPGRP\r
4747PyDoc_STRVAR(posix_tcsetpgrp__doc__,\r
4748"tcsetpgrp(fd, pgid)\n\n\\r
4749Set the process group associated with the terminal given by a fd.");\r
4750\r
4751static PyObject *\r
4752posix_tcsetpgrp(PyObject *self, PyObject *args)\r
4753{\r
4754 int fd;\r
4755 pid_t pgid;\r
4756 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))\r
4757 return NULL;\r
4758 if (tcsetpgrp(fd, pgid) < 0)\r
4759 return posix_error();\r
4760 Py_INCREF(Py_None);\r
4761 return Py_None;\r
4762}\r
4763#endif /* HAVE_TCSETPGRP */\r
4764\r
4765/* Functions acting on file descriptors */\r
4766\r
4767PyDoc_STRVAR(posix_open__doc__,\r
4768"open(filename, flag [, mode=0777]) -> fd\n\n\\r
4769Open a file (for low level IO).");\r
4770\r
4771static PyObject *\r
4772posix_open(PyObject *self, PyObject *args)\r
4773{\r
4774 char *file = NULL;\r
4775 int flag;\r
4776 int mode = 0777;\r
4777 int fd;\r
4778\r
4779 if (!PyArg_ParseTuple(args, "eti|i",\r
4780 Py_FileSystemDefaultEncoding, &file,\r
4781 &flag, &mode))\r
4782 return NULL;\r
4783\r
4784 Py_BEGIN_ALLOW_THREADS\r
4785 fd = open(file, flag, mode);\r
4786 Py_END_ALLOW_THREADS\r
4787 if (fd < 0)\r
4788 return posix_error_with_allocated_filename(file);\r
4789 PyMem_Free(file);\r
4790 return PyInt_FromLong((long)fd);\r
4791}\r
4792\r
4793\r
4794PyDoc_STRVAR(posix_close__doc__,\r
4795"close(fd)\n\n\\r
4796Close a file descriptor (for low level IO).");\r
4797\r
4798static PyObject *\r
4799posix_close(PyObject *self, PyObject *args)\r
4800{\r
4801 int fd, res;\r
4802 if (!PyArg_ParseTuple(args, "i:close", &fd))\r
4803 return NULL;\r
4804 if (!_PyVerify_fd(fd))\r
4805 return posix_error();\r
4806 Py_BEGIN_ALLOW_THREADS\r
4807 res = close(fd);\r
4808 Py_END_ALLOW_THREADS\r
4809 if (res < 0)\r
4810 return posix_error();\r
4811 Py_INCREF(Py_None);\r
4812 return Py_None;\r
4813}\r
4814\r
4815\r
4816PyDoc_STRVAR(posix_closerange__doc__,\r
4817"closerange(fd_low, fd_high)\n\n\\r
4818Closes all file descriptors in [fd_low, fd_high), ignoring errors.");\r
4819\r
4820static PyObject *\r
4821posix_closerange(PyObject *self, PyObject *args)\r
4822{\r
4823 int fd_from, fd_to, i;\r
4824 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))\r
4825 return NULL;\r
4826 Py_BEGIN_ALLOW_THREADS\r
4827 for (i = fd_from; i < fd_to; i++)\r
4828 if (_PyVerify_fd(i))\r
4829 close(i);\r
4830 Py_END_ALLOW_THREADS\r
4831 Py_RETURN_NONE;\r
4832}\r
4833\r
4834\r
4835PyDoc_STRVAR(posix_dup__doc__,\r
4836"dup(fd) -> fd2\n\n\\r
4837Return a duplicate of a file descriptor.");\r
4838\r
4839static PyObject *\r
4840posix_dup(PyObject *self, PyObject *args)\r
4841{\r
4842 int fd;\r
4843 if (!PyArg_ParseTuple(args, "i:dup", &fd))\r
4844 return NULL;\r
4845 if (!_PyVerify_fd(fd))\r
4846 return posix_error();\r
4847 Py_BEGIN_ALLOW_THREADS\r
4848 fd = dup(fd);\r
4849 Py_END_ALLOW_THREADS\r
4850 if (fd < 0)\r
4851 return posix_error();\r
4852 return PyInt_FromLong((long)fd);\r
4853}\r
4854\r
4855\r
4856PyDoc_STRVAR(posix_dup2__doc__,\r
4857"dup2(old_fd, new_fd)\n\n\\r
4858Duplicate file descriptor.");\r
4859\r
4860static PyObject *\r
4861posix_dup2(PyObject *self, PyObject *args)\r
4862{\r
4863 int fd, fd2, res;\r
4864 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))\r
4865 return NULL;\r
4866 if (!_PyVerify_fd_dup2(fd, fd2))\r
4867 return posix_error();\r
4868 Py_BEGIN_ALLOW_THREADS\r
4869 res = dup2(fd, fd2);\r
4870 Py_END_ALLOW_THREADS\r
4871 if (res < 0)\r
4872 return posix_error();\r
4873 Py_INCREF(Py_None);\r
4874 return Py_None;\r
4875}\r
4876\r
4877\r
4878PyDoc_STRVAR(posix_lseek__doc__,\r
4879"lseek(fd, pos, how) -> newpos\n\n\\r
4880Set the current position of a file descriptor.");\r
4881\r
4882static PyObject *\r
4883posix_lseek(PyObject *self, PyObject *args)\r
4884{\r
4885 int fd, how;\r
4886 off_t pos, res;\r
4887 PyObject *posobj;\r
4888 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))\r
4889 return NULL;\r
4890#ifdef SEEK_SET\r
4891 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */\r
4892 switch (how) {\r
4893 case 0: how = SEEK_SET; break;\r
4894 case 1: how = SEEK_CUR; break;\r
4895 case 2: how = SEEK_END; break;\r
4896 }\r
4897#endif /* SEEK_END */\r
4898\r
4899#if !defined(HAVE_LARGEFILE_SUPPORT)\r
4900 pos = PyInt_AsLong(posobj);\r
4901#else\r
4902 pos = PyLong_Check(posobj) ?\r
4903 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);\r
4904#endif\r
4905 if (PyErr_Occurred())\r
4906 return NULL;\r
4907\r
4908 if (!_PyVerify_fd(fd))\r
4909 return posix_error();\r
4910 Py_BEGIN_ALLOW_THREADS\r
4911 res = lseek(fd, pos, how);\r
4912 Py_END_ALLOW_THREADS\r
4913 if (res < 0)\r
4914 return posix_error();\r
4915\r
4916#if !defined(HAVE_LARGEFILE_SUPPORT)\r
4917 return PyInt_FromLong(res);\r
4918#else\r
4919 return PyLong_FromLongLong(res);\r
4920#endif\r
4921}\r
4922\r
4923\r
4924PyDoc_STRVAR(posix_read__doc__,\r
4925"read(fd, buffersize) -> string\n\n\\r
4926Read a file descriptor.");\r
4927\r
4928static PyObject *\r
4929posix_read(PyObject *self, PyObject *args)\r
4930{\r
4931 int fd, size, n;\r
4932 PyObject *buffer;\r
4933 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))\r
4934 return NULL;\r
4935 if (size < 0) {\r
4936 errno = EINVAL;\r
4937 return posix_error();\r
4938 }\r
4939 buffer = PyString_FromStringAndSize((char *)NULL, size);\r
4940 if (buffer == NULL)\r
4941 return NULL;\r
4942 if (!_PyVerify_fd(fd)) {\r
4943 Py_DECREF(buffer);\r
4944 return posix_error();\r
4945 }\r
4946 Py_BEGIN_ALLOW_THREADS\r
4947 n = read(fd, PyString_AsString(buffer), size);\r
4948 Py_END_ALLOW_THREADS\r
4949 if (n < 0) {\r
4950 Py_DECREF(buffer);\r
4951 return posix_error();\r
4952 }\r
4953 if (n != size)\r
4954 _PyString_Resize(&buffer, n);\r
4955 return buffer;\r
4956}\r
4957\r
4958\r
4959PyDoc_STRVAR(posix_write__doc__,\r
4960"write(fd, string) -> byteswritten\n\n\\r
4961Write a string to a file descriptor.");\r
4962\r
4963static PyObject *\r
4964posix_write(PyObject *self, PyObject *args)\r
4965{\r
4966 Py_buffer pbuf;\r
4967 int fd;\r
4968 Py_ssize_t size;\r
4969\r
4970 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))\r
4971 return NULL;\r
4972 if (!_PyVerify_fd(fd)) {\r
4973 PyBuffer_Release(&pbuf);\r
4974 return posix_error();\r
4975 }\r
4976 Py_BEGIN_ALLOW_THREADS\r
4977 size = write(fd, pbuf.buf, (size_t)pbuf.len);\r
4978 Py_END_ALLOW_THREADS\r
4979 PyBuffer_Release(&pbuf);\r
4980 if (size < 0)\r
4981 return posix_error();\r
4982 return PyInt_FromSsize_t(size);\r
4983}\r
4984\r
4985\r
4986PyDoc_STRVAR(posix_fstat__doc__,\r
4987"fstat(fd) -> stat result\n\n\\r
4988Like stat(), but for an open file descriptor.");\r
4989\r
4990static PyObject *\r
4991posix_fstat(PyObject *self, PyObject *args)\r
4992{\r
4993 int fd;\r
4994 STRUCT_STAT st;\r
4995 int res;\r
4996 if (!PyArg_ParseTuple(args, "i:fstat", &fd))\r
4997 return NULL;\r
4998 if (!_PyVerify_fd(fd))\r
4999 return posix_error();\r
5000 Py_BEGIN_ALLOW_THREADS\r
5001 res = FSTAT(fd, &st);\r
5002 Py_END_ALLOW_THREADS\r
5003 if (res != 0) {\r
5004 return posix_error();\r
5005 }\r
5006\r
5007 return _pystat_fromstructstat(&st);\r
5008}\r
5009\r
5010\r
5011PyDoc_STRVAR(posix_fdopen__doc__,\r
5012"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\\r
5013Return an open file object connected to a file descriptor.");\r
5014\r
5015static PyObject *\r
5016posix_fdopen(PyObject *self, PyObject *args)\r
5017{\r
5018 int fd;\r
5019 char *orgmode = "r";\r
5020 int bufsize = -1;\r
5021 FILE *fp;\r
5022 PyObject *f;\r
5023 char *mode;\r
5024 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))\r
5025 return NULL;\r
5026\r
5027 /* Sanitize mode. See fileobject.c */\r
5028 mode = PyMem_MALLOC(strlen(orgmode)+3);\r
5029 if (!mode) {\r
5030 PyErr_NoMemory();\r
5031 return NULL;\r
5032 }\r
5033 strcpy(mode, orgmode);\r
5034 if (_PyFile_SanitizeMode(mode)) {\r
5035 PyMem_FREE(mode);\r
5036 return NULL;\r
5037 }\r
5038 if (!_PyVerify_fd(fd))\r
5039 return posix_error();\r
5040 Py_BEGIN_ALLOW_THREADS\r
5041#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)\r
5042 if (mode[0] == 'a') {\r
5043 /* try to make sure the O_APPEND flag is set */\r
5044 int flags;\r
5045 flags = fcntl(fd, F_GETFL);\r
5046 if (flags != -1)\r
5047 fcntl(fd, F_SETFL, flags | O_APPEND);\r
5048 fp = fdopen(fd, mode);\r
5049 if (fp == NULL && flags != -1)\r
5050 /* restore old mode if fdopen failed */\r
5051 fcntl(fd, F_SETFL, flags);\r
5052 } else {\r
5053 fp = fdopen(fd, mode);\r
5054 }\r
5055#else\r
5056 fp = fdopen(fd, mode);\r
5057#endif\r
5058 Py_END_ALLOW_THREADS\r
5059 PyMem_FREE(mode);\r
5060 if (fp == NULL)\r
5061 return posix_error();\r
5062 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);\r
5063 if (f != NULL)\r
5064 PyFile_SetBufSize(f, bufsize);\r
5065 return f;\r
5066}\r
5067\r
5068PyDoc_STRVAR(posix_isatty__doc__,\r
5069"isatty(fd) -> bool\n\n\\r
5070Return True if the file descriptor 'fd' is an open file descriptor\n\\r
5071connected to the slave end of a terminal.");\r
5072\r
5073static PyObject *\r
5074posix_isatty(PyObject *self, PyObject *args)\r
5075{\r
5076 int fd;\r
5077 if (!PyArg_ParseTuple(args, "i:isatty", &fd))\r
5078 return NULL;\r
5079 if (!_PyVerify_fd(fd))\r
5080 return PyBool_FromLong(0);\r
5081 return PyBool_FromLong(isatty(fd));\r
5082}\r
5083\r
5084#ifdef HAVE_PIPE\r
5085PyDoc_STRVAR(posix_pipe__doc__,\r
5086"pipe() -> (read_end, write_end)\n\n\\r
5087Create a pipe.");\r
5088\r
5089static PyObject *\r
5090posix_pipe(PyObject *self, PyObject *noargs)\r
5091{\r
5092#if defined(PYOS_OS2)\r
5093 HFILE read, write;\r
5094 APIRET rc;\r
5095\r
5096 Py_BEGIN_ALLOW_THREADS\r
5097 rc = DosCreatePipe( &read, &write, 4096);\r
5098 Py_END_ALLOW_THREADS\r
5099 if (rc != NO_ERROR)\r
5100 return os2_error(rc);\r
5101\r
5102 return Py_BuildValue("(ii)", read, write);\r
5103#else\r
5104#if !defined(MS_WINDOWS)\r
5105 int fds[2];\r
5106 int res;\r
5107 Py_BEGIN_ALLOW_THREADS\r
5108 res = pipe(fds);\r
5109 Py_END_ALLOW_THREADS\r
5110 if (res != 0)\r
5111 return posix_error();\r
5112 return Py_BuildValue("(ii)", fds[0], fds[1]);\r
5113#else /* MS_WINDOWS */\r
5114 HANDLE read, write;\r
5115 int read_fd, write_fd;\r
5116 BOOL ok;\r
5117 Py_BEGIN_ALLOW_THREADS\r
5118 ok = CreatePipe(&read, &write, NULL, 0);\r
5119 Py_END_ALLOW_THREADS\r
5120 if (!ok)\r
5121 return win32_error("CreatePipe", NULL);\r
5122 read_fd = _open_osfhandle((Py_intptr_t)read, 0);\r
5123 write_fd = _open_osfhandle((Py_intptr_t)write, 1);\r
5124 return Py_BuildValue("(ii)", read_fd, write_fd);\r
5125#endif /* MS_WINDOWS */\r
5126#endif\r
5127}\r
5128#endif /* HAVE_PIPE */\r
5129\r
5130\r
5131#ifdef HAVE_MKFIFO\r
5132PyDoc_STRVAR(posix_mkfifo__doc__,\r
5133"mkfifo(filename [, mode=0666])\n\n\\r
5134Create a FIFO (a POSIX named pipe).");\r
5135\r
5136static PyObject *\r
5137posix_mkfifo(PyObject *self, PyObject *args)\r
5138{\r
5139 char *filename;\r
5140 int mode = 0666;\r
5141 int res;\r
5142 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))\r
5143 return NULL;\r
5144 Py_BEGIN_ALLOW_THREADS\r
5145 res = mkfifo(filename, mode);\r
5146 Py_END_ALLOW_THREADS\r
5147 if (res < 0)\r
5148 return posix_error();\r
5149 Py_INCREF(Py_None);\r
5150 return Py_None;\r
5151}\r
5152#endif\r
5153\r
5154\r
5155#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)\r
5156PyDoc_STRVAR(posix_mknod__doc__,\r
5157"mknod(filename [, mode=0600, device])\n\n\\r
5158Create a filesystem node (file, device special file or named pipe)\n\\r
5159named filename. mode specifies both the permissions to use and the\n\\r
5160type of node to be created, being combined (bitwise OR) with one of\n\\r
5161S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\\r
5162device defines the newly created device special file (probably using\n\\r
5163os.makedev()), otherwise it is ignored.");\r
5164\r
5165\r
5166static PyObject *\r
5167posix_mknod(PyObject *self, PyObject *args)\r
5168{\r
5169 char *filename;\r
5170 int mode = 0600;\r
5171 int device = 0;\r
5172 int res;\r
5173 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))\r
5174 return NULL;\r
5175 Py_BEGIN_ALLOW_THREADS\r
5176 res = mknod(filename, mode, device);\r
5177 Py_END_ALLOW_THREADS\r
5178 if (res < 0)\r
5179 return posix_error();\r
5180 Py_INCREF(Py_None);\r
5181 return Py_None;\r
5182}\r
5183#endif\r
5184\r
5185#ifdef HAVE_DEVICE_MACROS\r
5186PyDoc_STRVAR(posix_major__doc__,\r
5187"major(device) -> major number\n\\r
5188Extracts a device major number from a raw device number.");\r
5189\r
5190static PyObject *\r
5191posix_major(PyObject *self, PyObject *args)\r
5192{\r
5193 int device;\r
5194 if (!PyArg_ParseTuple(args, "i:major", &device))\r
5195 return NULL;\r
5196 return PyInt_FromLong((long)major(device));\r
5197}\r
5198\r
5199PyDoc_STRVAR(posix_minor__doc__,\r
5200"minor(device) -> minor number\n\\r
5201Extracts a device minor number from a raw device number.");\r
5202\r
5203static PyObject *\r
5204posix_minor(PyObject *self, PyObject *args)\r
5205{\r
5206 int device;\r
5207 if (!PyArg_ParseTuple(args, "i:minor", &device))\r
5208 return NULL;\r
5209 return PyInt_FromLong((long)minor(device));\r
5210}\r
5211\r
5212PyDoc_STRVAR(posix_makedev__doc__,\r
5213"makedev(major, minor) -> device number\n\\r
5214Composes a raw device number from the major and minor device numbers.");\r
5215\r
5216static PyObject *\r
5217posix_makedev(PyObject *self, PyObject *args)\r
5218{\r
5219 int major, minor;\r
5220 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))\r
5221 return NULL;\r
5222 return PyInt_FromLong((long)makedev(major, minor));\r
5223}\r
5224#endif /* device macros */\r
5225\r
5226\r
5227#ifdef HAVE_FTRUNCATE\r
5228PyDoc_STRVAR(posix_ftruncate__doc__,\r
5229"ftruncate(fd, length)\n\n\\r
5230Truncate a file to a specified length.");\r
5231\r
5232static PyObject *\r
5233posix_ftruncate(PyObject *self, PyObject *args)\r
5234{\r
5235 int fd;\r
5236 off_t length;\r
5237 int res;\r
5238 PyObject *lenobj;\r
5239\r
5240 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))\r
5241 return NULL;\r
5242\r
5243#if !defined(HAVE_LARGEFILE_SUPPORT)\r
5244 length = PyInt_AsLong(lenobj);\r
5245#else\r
5246 length = PyLong_Check(lenobj) ?\r
5247 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);\r
5248#endif\r
5249 if (PyErr_Occurred())\r
5250 return NULL;\r
5251\r
5252 Py_BEGIN_ALLOW_THREADS\r
5253 res = ftruncate(fd, length);\r
5254 Py_END_ALLOW_THREADS\r
5255 if (res < 0)\r
5256 return posix_error();\r
5257 Py_INCREF(Py_None);\r
5258 return Py_None;\r
5259}\r
5260#endif\r
5261\r
5262#ifdef HAVE_PUTENV\r
5263PyDoc_STRVAR(posix_putenv__doc__,\r
5264"putenv(key, value)\n\n\\r
5265Change or add an environment variable.");\r
5266\r
5267/* Save putenv() parameters as values here, so we can collect them when they\r
5268 * get re-set with another call for the same key. */\r
5269static PyObject *posix_putenv_garbage;\r
5270\r
5271static PyObject *\r
5272posix_putenv(PyObject *self, PyObject *args)\r
5273{\r
5274 char *s1, *s2;\r
5275 char *newenv;\r
5276 PyObject *newstr;\r
5277 size_t len;\r
5278\r
5279 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))\r
5280 return NULL;\r
5281\r
5282#if defined(PYOS_OS2)\r
5283 if (stricmp(s1, "BEGINLIBPATH") == 0) {\r
5284 APIRET rc;\r
5285\r
5286 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);\r
5287 if (rc != NO_ERROR)\r
5288 return os2_error(rc);\r
5289\r
5290 } else if (stricmp(s1, "ENDLIBPATH") == 0) {\r
5291 APIRET rc;\r
5292\r
5293 rc = DosSetExtLIBPATH(s2, END_LIBPATH);\r
5294 if (rc != NO_ERROR)\r
5295 return os2_error(rc);\r
5296 } else {\r
5297#endif\r
5298\r
5299 /* XXX This can leak memory -- not easy to fix :-( */\r
5300 len = strlen(s1) + strlen(s2) + 2;\r
5301 /* len includes space for a trailing \0; the size arg to\r
5302 PyString_FromStringAndSize does not count that */\r
5303 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);\r
5304 if (newstr == NULL)\r
5305 return PyErr_NoMemory();\r
5306 newenv = PyString_AS_STRING(newstr);\r
5307 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);\r
5308 if (putenv(newenv)) {\r
5309 Py_DECREF(newstr);\r
5310 posix_error();\r
5311 return NULL;\r
5312 }\r
5313 /* Install the first arg and newstr in posix_putenv_garbage;\r
5314 * this will cause previous value to be collected. This has to\r
5315 * happen after the real putenv() call because the old value\r
5316 * was still accessible until then. */\r
5317 if (PyDict_SetItem(posix_putenv_garbage,\r
5318 PyTuple_GET_ITEM(args, 0), newstr)) {\r
5319 /* really not much we can do; just leak */\r
5320 PyErr_Clear();\r
5321 }\r
5322 else {\r
5323 Py_DECREF(newstr);\r
5324 }\r
5325\r
5326#if defined(PYOS_OS2)\r
5327 }\r
5328#endif\r
5329 Py_INCREF(Py_None);\r
5330 return Py_None;\r
5331}\r
5332#endif /* putenv */\r
5333\r
5334#ifdef HAVE_UNSETENV\r
5335PyDoc_STRVAR(posix_unsetenv__doc__,\r
5336"unsetenv(key)\n\n\\r
5337Delete an environment variable.");\r
5338\r
5339static PyObject *\r
5340posix_unsetenv(PyObject *self, PyObject *args)\r
5341{\r
5342 char *s1;\r
5343\r
5344 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))\r
5345 return NULL;\r
5346\r
5347 unsetenv(s1);\r
5348\r
5349 /* Remove the key from posix_putenv_garbage;\r
5350 * this will cause it to be collected. This has to\r
5351 * happen after the real unsetenv() call because the\r
5352 * old value was still accessible until then.\r
5353 */\r
5354 if (PyDict_DelItem(posix_putenv_garbage,\r
5355 PyTuple_GET_ITEM(args, 0))) {\r
5356 /* really not much we can do; just leak */\r
5357 PyErr_Clear();\r
5358 }\r
5359\r
5360 Py_INCREF(Py_None);\r
5361 return Py_None;\r
5362}\r
5363#endif /* unsetenv */\r
5364\r
5365PyDoc_STRVAR(posix_strerror__doc__,\r
5366"strerror(code) -> string\n\n\\r
5367Translate an error code to a message string.");\r
5368\r
5369static PyObject *\r
5370posix_strerror(PyObject *self, PyObject *args)\r
5371{\r
5372 int code;\r
5373 char *message;\r
5374 if (!PyArg_ParseTuple(args, "i:strerror", &code))\r
5375 return NULL;\r
5376 message = strerror(code);\r
5377 if (message == NULL) {\r
5378 PyErr_SetString(PyExc_ValueError,\r
5379 "strerror() argument out of range");\r
5380 return NULL;\r
5381 }\r
5382 return PyString_FromString(message);\r
5383}\r
5384\r
5385\r
5386#ifdef HAVE_SYS_WAIT_H\r
5387\r
5388#ifdef WCOREDUMP\r
5389PyDoc_STRVAR(posix_WCOREDUMP__doc__,\r
5390"WCOREDUMP(status) -> bool\n\n\\r
5391Return True if the process returning 'status' was dumped to a core file.");\r
5392\r
5393static PyObject *\r
5394posix_WCOREDUMP(PyObject *self, PyObject *args)\r
5395{\r
5396 WAIT_TYPE status;\r
5397 WAIT_STATUS_INT(status) = 0;\r
5398\r
5399 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))\r
5400 return NULL;\r
5401\r
5402 return PyBool_FromLong(WCOREDUMP(status));\r
5403}\r
5404#endif /* WCOREDUMP */\r
5405\r
5406#ifdef WIFCONTINUED\r
5407PyDoc_STRVAR(posix_WIFCONTINUED__doc__,\r
5408"WIFCONTINUED(status) -> bool\n\n\\r
5409Return True if the process returning 'status' was continued from a\n\\r
5410job control stop.");\r
5411\r
5412static PyObject *\r
5413posix_WIFCONTINUED(PyObject *self, PyObject *args)\r
5414{\r
5415 WAIT_TYPE status;\r
5416 WAIT_STATUS_INT(status) = 0;\r
5417\r
5418 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))\r
5419 return NULL;\r
5420\r
5421 return PyBool_FromLong(WIFCONTINUED(status));\r
5422}\r
5423#endif /* WIFCONTINUED */\r
5424\r
5425#ifdef WIFSTOPPED\r
5426PyDoc_STRVAR(posix_WIFSTOPPED__doc__,\r
5427"WIFSTOPPED(status) -> bool\n\n\\r
5428Return True if the process returning 'status' was stopped.");\r
5429\r
5430static PyObject *\r
5431posix_WIFSTOPPED(PyObject *self, PyObject *args)\r
5432{\r
5433 WAIT_TYPE status;\r
5434 WAIT_STATUS_INT(status) = 0;\r
5435\r
5436 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))\r
5437 return NULL;\r
5438\r
5439 return PyBool_FromLong(WIFSTOPPED(status));\r
5440}\r
5441#endif /* WIFSTOPPED */\r
5442\r
5443#ifdef WIFSIGNALED\r
5444PyDoc_STRVAR(posix_WIFSIGNALED__doc__,\r
5445"WIFSIGNALED(status) -> bool\n\n\\r
5446Return True if the process returning 'status' was terminated by a signal.");\r
5447\r
5448static PyObject *\r
5449posix_WIFSIGNALED(PyObject *self, PyObject *args)\r
5450{\r
5451 WAIT_TYPE status;\r
5452 WAIT_STATUS_INT(status) = 0;\r
5453\r
5454 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))\r
5455 return NULL;\r
5456\r
5457 return PyBool_FromLong(WIFSIGNALED(status));\r
5458}\r
5459#endif /* WIFSIGNALED */\r
5460\r
5461#ifdef WIFEXITED\r
5462PyDoc_STRVAR(posix_WIFEXITED__doc__,\r
5463"WIFEXITED(status) -> bool\n\n\\r
5464Return true if the process returning 'status' exited using the exit()\n\\r
5465system call.");\r
5466\r
5467static PyObject *\r
5468posix_WIFEXITED(PyObject *self, PyObject *args)\r
5469{\r
5470 WAIT_TYPE status;\r
5471 WAIT_STATUS_INT(status) = 0;\r
5472\r
5473 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))\r
5474 return NULL;\r
5475\r
5476 return PyBool_FromLong(WIFEXITED(status));\r
5477}\r
5478#endif /* WIFEXITED */\r
5479\r
5480#ifdef WEXITSTATUS\r
5481PyDoc_STRVAR(posix_WEXITSTATUS__doc__,\r
5482"WEXITSTATUS(status) -> integer\n\n\\r
5483Return the process return code from 'status'.");\r
5484\r
5485static PyObject *\r
5486posix_WEXITSTATUS(PyObject *self, PyObject *args)\r
5487{\r
5488 WAIT_TYPE status;\r
5489 WAIT_STATUS_INT(status) = 0;\r
5490\r
5491 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))\r
5492 return NULL;\r
5493\r
5494 return Py_BuildValue("i", WEXITSTATUS(status));\r
5495}\r
5496#endif /* WEXITSTATUS */\r
5497\r
5498#ifdef WTERMSIG\r
5499PyDoc_STRVAR(posix_WTERMSIG__doc__,\r
5500"WTERMSIG(status) -> integer\n\n\\r
5501Return the signal that terminated the process that provided the 'status'\n\\r
5502value.");\r
5503\r
5504static PyObject *\r
5505posix_WTERMSIG(PyObject *self, PyObject *args)\r
5506{\r
5507 WAIT_TYPE status;\r
5508 WAIT_STATUS_INT(status) = 0;\r
5509\r
5510 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))\r
5511 return NULL;\r
5512\r
5513 return Py_BuildValue("i", WTERMSIG(status));\r
5514}\r
5515#endif /* WTERMSIG */\r
5516\r
5517#ifdef WSTOPSIG\r
5518PyDoc_STRVAR(posix_WSTOPSIG__doc__,\r
5519"WSTOPSIG(status) -> integer\n\n\\r
5520Return the signal that stopped the process that provided\n\\r
5521the 'status' value.");\r
5522\r
5523static PyObject *\r
5524posix_WSTOPSIG(PyObject *self, PyObject *args)\r
5525{\r
5526 WAIT_TYPE status;\r
5527 WAIT_STATUS_INT(status) = 0;\r
5528\r
5529 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))\r
5530 return NULL;\r
5531\r
5532 return Py_BuildValue("i", WSTOPSIG(status));\r
5533}\r
5534#endif /* WSTOPSIG */\r
5535\r
5536#endif /* HAVE_SYS_WAIT_H */\r
5537\r
5538\r
5539#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)\r
5540#ifdef _SCO_DS\r
5541/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the\r
5542 needed definitions in sys/statvfs.h */\r
5543#define _SVID3\r
5544#endif\r
5545#include <sys/statvfs.h>\r
5546\r
5547static PyObject*\r
5548_pystatvfs_fromstructstatvfs(struct statvfs st) {\r
5549 PyObject *v = PyStructSequence_New(&StatVFSResultType);\r
5550 if (v == NULL)\r
5551 return NULL;\r
5552\r
5553#if !defined(HAVE_LARGEFILE_SUPPORT)\r
5554 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));\r
5555 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));\r
5556 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));\r
5557 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));\r
5558 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));\r
5559 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));\r
5560 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));\r
5561 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));\r
5562 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));\r
5563 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));\r
5564#else\r
5565 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));\r
5566 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));\r
5567 PyStructSequence_SET_ITEM(v, 2,\r
5568 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));\r
5569 PyStructSequence_SET_ITEM(v, 3,\r
5570 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));\r
5571 PyStructSequence_SET_ITEM(v, 4,\r
5572 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));\r
5573 PyStructSequence_SET_ITEM(v, 5,\r
5574 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));\r
5575 PyStructSequence_SET_ITEM(v, 6,\r
5576 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));\r
5577 PyStructSequence_SET_ITEM(v, 7,\r
5578 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));\r
5579 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));\r
5580 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));\r
5581#endif\r
5582\r
5583 return v;\r
5584}\r
5585\r
5586PyDoc_STRVAR(posix_fstatvfs__doc__,\r
5587"fstatvfs(fd) -> statvfs result\n\n\\r
5588Perform an fstatvfs system call on the given fd.");\r
5589\r
5590static PyObject *\r
5591posix_fstatvfs(PyObject *self, PyObject *args)\r
5592{\r
5593 int fd, res;\r
5594 struct statvfs st;\r
5595\r
5596 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))\r
5597 return NULL;\r
5598 Py_BEGIN_ALLOW_THREADS\r
5599 res = fstatvfs(fd, &st);\r
5600 Py_END_ALLOW_THREADS\r
5601 if (res != 0)\r
5602 return posix_error();\r
5603\r
5604 return _pystatvfs_fromstructstatvfs(st);\r
5605}\r
5606#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */\r
5607\r
5608\r
5609#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)\r
5610#include <sys/statvfs.h>\r
5611\r
5612PyDoc_STRVAR(posix_statvfs__doc__,\r
5613"statvfs(path) -> statvfs result\n\n\\r
5614Perform a statvfs system call on the given path.");\r
5615\r
5616static PyObject *\r
5617posix_statvfs(PyObject *self, PyObject *args)\r
5618{\r
5619 char *path;\r
5620 int res;\r
5621 struct statvfs st;\r
5622 if (!PyArg_ParseTuple(args, "s:statvfs", &path))\r
5623 return NULL;\r
5624 Py_BEGIN_ALLOW_THREADS\r
5625 res = statvfs(path, &st);\r
5626 Py_END_ALLOW_THREADS\r
5627 if (res != 0)\r
5628 return posix_error_with_filename(path);\r
5629\r
5630 return _pystatvfs_fromstructstatvfs(st);\r
5631}\r
5632#endif /* HAVE_STATVFS */\r
5633\r
5634\r
5635#ifdef HAVE_TEMPNAM\r
5636PyDoc_STRVAR(posix_tempnam__doc__,\r
5637"tempnam([dir[, prefix]]) -> string\n\n\\r
5638Return a unique name for a temporary file.\n\\r
5639The directory and a prefix may be specified as strings; they may be omitted\n\\r
5640or None if not needed.");\r
5641\r
5642static PyObject *\r
5643posix_tempnam(PyObject *self, PyObject *args)\r
5644{\r
5645 PyObject *result = NULL;\r
5646 char *dir = NULL;\r
5647 char *pfx = NULL;\r
5648 char *name;\r
5649\r
5650 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))\r
5651 return NULL;\r
5652\r
5653 if (PyErr_Warn(PyExc_RuntimeWarning,\r
5654 "tempnam is a potential security risk to your program") < 0)\r
5655 return NULL;\r
5656\r
5657 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "\r
5658 "use the tempfile module", 1) < 0)\r
5659 return NULL;\r
5660\r
5661 name = tempnam(dir, pfx);\r
5662 if (name == NULL)\r
5663 return PyErr_NoMemory();\r
5664 result = PyString_FromString(name);\r
5665 free(name);\r
5666 return result;\r
5667}\r
5668#endif\r
5669\r
5670\r
5671#ifdef HAVE_TMPFILE\r
5672PyDoc_STRVAR(posix_tmpfile__doc__,\r
5673"tmpfile() -> file object\n\n\\r
5674Create a temporary file with no directory entries.");\r
5675\r
5676static PyObject *\r
5677posix_tmpfile(PyObject *self, PyObject *noargs)\r
5678{\r
5679 FILE *fp;\r
5680\r
5681 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "\r
5682 "use the tempfile module", 1) < 0)\r
5683 return NULL;\r
5684\r
5685 fp = tmpfile();\r
5686 if (fp == NULL)\r
5687 return posix_error();\r
5688 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);\r
5689}\r
5690#endif\r
5691\r
5692\r
5693#ifdef HAVE_TMPNAM\r
5694PyDoc_STRVAR(posix_tmpnam__doc__,\r
5695"tmpnam() -> string\n\n\\r
5696Return a unique name for a temporary file.");\r
5697\r
5698static PyObject *\r
5699posix_tmpnam(PyObject *self, PyObject *noargs)\r
5700{\r
5701 char buffer[L_tmpnam];\r
5702 char *name;\r
5703\r
5704 if (PyErr_Warn(PyExc_RuntimeWarning,\r
5705 "tmpnam is a potential security risk to your program") < 0)\r
5706 return NULL;\r
5707\r
5708 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "\r
5709 "use the tempfile module", 1) < 0)\r
5710 return NULL;\r
5711\r
5712#ifdef USE_TMPNAM_R\r
5713 name = tmpnam_r(buffer);\r
5714#else\r
5715 name = tmpnam(buffer);\r
5716#endif\r
5717 if (name == NULL) {\r
5718 PyObject *err = Py_BuildValue("is", 0,\r
5719#ifdef USE_TMPNAM_R\r
5720 "unexpected NULL from tmpnam_r"\r
5721#else\r
5722 "unexpected NULL from tmpnam"\r
5723#endif\r
5724 );\r
5725 PyErr_SetObject(PyExc_OSError, err);\r
5726 Py_XDECREF(err);\r
5727 return NULL;\r
5728 }\r
5729 return PyString_FromString(buffer);\r
5730}\r
5731#endif\r
5732\r
5733\r
5734/* This is used for fpathconf(), pathconf(), confstr() and sysconf().\r
5735 * It maps strings representing configuration variable names to\r
5736 * integer values, allowing those functions to be called with the\r
5737 * magic names instead of polluting the module's namespace with tons of\r
5738 * rarely-used constants. There are three separate tables that use\r
5739 * these definitions.\r
5740 *\r
5741 * This code is always included, even if none of the interfaces that\r
5742 * need it are included. The #if hackery needed to avoid it would be\r
5743 * sufficiently pervasive that it's not worth the loss of readability.\r
5744 */\r
5745struct constdef {\r
5746 char *name;\r
5747 long value;\r
5748};\r
5749\r
5750#ifndef UEFI_C_SOURCE\r
5751static int\r
5752conv_confname(PyObject *arg, int *valuep, struct constdef *table,\r
5753 size_t tablesize)\r
5754{\r
5755 if (PyInt_Check(arg)) {\r
5756 *valuep = PyInt_AS_LONG(arg);\r
5757 return 1;\r
5758 }\r
5759 if (PyString_Check(arg)) {\r
5760 /* look up the value in the table using a binary search */\r
5761 size_t lo = 0;\r
5762 size_t mid;\r
5763 size_t hi = tablesize;\r
5764 int cmp;\r
5765 char *confname = PyString_AS_STRING(arg);\r
5766 while (lo < hi) {\r
5767 mid = (lo + hi) / 2;\r
5768 cmp = strcmp(confname, table[mid].name);\r
5769 if (cmp < 0)\r
5770 hi = mid;\r
5771 else if (cmp > 0)\r
5772 lo = mid + 1;\r
5773 else {\r
5774 *valuep = table[mid].value;\r
5775 return 1;\r
5776 }\r
5777 }\r
5778 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");\r
5779 }\r
5780 else\r
5781 PyErr_SetString(PyExc_TypeError,\r
5782 "configuration names must be strings or integers");\r
5783 return 0;\r
5784}\r
5785#endif /* UEFI_C_SOURCE */\r
5786\r
5787#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)\r
5788static struct constdef posix_constants_pathconf[] = {\r
5789#ifdef _PC_ABI_AIO_XFER_MAX\r
5790 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},\r
5791#endif\r
5792#ifdef _PC_ABI_ASYNC_IO\r
5793 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},\r
5794#endif\r
5795#ifdef _PC_ASYNC_IO\r
5796 {"PC_ASYNC_IO", _PC_ASYNC_IO},\r
5797#endif\r
5798#ifdef _PC_CHOWN_RESTRICTED\r
5799 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},\r
5800#endif\r
5801#ifdef _PC_FILESIZEBITS\r
5802 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},\r
5803#endif\r
5804#ifdef _PC_LAST\r
5805 {"PC_LAST", _PC_LAST},\r
5806#endif\r
5807#ifdef _PC_LINK_MAX\r
5808 {"PC_LINK_MAX", _PC_LINK_MAX},\r
5809#endif\r
5810#ifdef _PC_MAX_CANON\r
5811 {"PC_MAX_CANON", _PC_MAX_CANON},\r
5812#endif\r
5813#ifdef _PC_MAX_INPUT\r
5814 {"PC_MAX_INPUT", _PC_MAX_INPUT},\r
5815#endif\r
5816#ifdef _PC_NAME_MAX\r
5817 {"PC_NAME_MAX", _PC_NAME_MAX},\r
5818#endif\r
5819#ifdef _PC_NO_TRUNC\r
5820 {"PC_NO_TRUNC", _PC_NO_TRUNC},\r
5821#endif\r
5822#ifdef _PC_PATH_MAX\r
5823 {"PC_PATH_MAX", _PC_PATH_MAX},\r
5824#endif\r
5825#ifdef _PC_PIPE_BUF\r
5826 {"PC_PIPE_BUF", _PC_PIPE_BUF},\r
5827#endif\r
5828#ifdef _PC_PRIO_IO\r
5829 {"PC_PRIO_IO", _PC_PRIO_IO},\r
5830#endif\r
5831#ifdef _PC_SOCK_MAXBUF\r
5832 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},\r
5833#endif\r
5834#ifdef _PC_SYNC_IO\r
5835 {"PC_SYNC_IO", _PC_SYNC_IO},\r
5836#endif\r
5837#ifdef _PC_VDISABLE\r
5838 {"PC_VDISABLE", _PC_VDISABLE},\r
5839#endif\r
5840};\r
5841\r
5842static int\r
5843conv_path_confname(PyObject *arg, int *valuep)\r
5844{\r
5845 return conv_confname(arg, valuep, posix_constants_pathconf,\r
5846 sizeof(posix_constants_pathconf)\r
5847 / sizeof(struct constdef));\r
5848}\r
5849#endif\r
5850\r
5851#ifdef HAVE_FPATHCONF\r
5852PyDoc_STRVAR(posix_fpathconf__doc__,\r
5853"fpathconf(fd, name) -> integer\n\n\\r
5854Return the configuration limit name for the file descriptor fd.\n\\r
5855If there is no limit, return -1.");\r
5856\r
5857static PyObject *\r
5858posix_fpathconf(PyObject *self, PyObject *args)\r
5859{\r
5860 PyObject *result = NULL;\r
5861 int name, fd;\r
5862\r
5863 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,\r
5864 conv_path_confname, &name)) {\r
5865 long limit;\r
5866\r
5867 errno = 0;\r
5868 limit = fpathconf(fd, name);\r
5869 if (limit == -1 && errno != 0)\r
5870 posix_error();\r
5871 else\r
5872 result = PyInt_FromLong(limit);\r
5873 }\r
5874 return result;\r
5875}\r
5876#endif\r
5877\r
5878\r
5879#ifdef HAVE_PATHCONF\r
5880PyDoc_STRVAR(posix_pathconf__doc__,\r
5881"pathconf(path, name) -> integer\n\n\\r
5882Return the configuration limit name for the file or directory path.\n\\r
5883If there is no limit, return -1.");\r
5884\r
5885static PyObject *\r
5886posix_pathconf(PyObject *self, PyObject *args)\r
5887{\r
5888 PyObject *result = NULL;\r
5889 int name;\r
5890 char *path;\r
5891\r
5892 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,\r
5893 conv_path_confname, &name)) {\r
5894 long limit;\r
5895\r
5896 errno = 0;\r
5897 limit = pathconf(path, name);\r
5898 if (limit == -1 && errno != 0) {\r
5899 if (errno == EINVAL)\r
5900 /* could be a path or name problem */\r
5901 posix_error();\r
5902 else\r
5903 posix_error_with_filename(path);\r
5904 }\r
5905 else\r
5906 result = PyInt_FromLong(limit);\r
5907 }\r
5908 return result;\r
5909}\r
5910#endif\r
5911\r
5912#ifdef HAVE_CONFSTR\r
5913static struct constdef posix_constants_confstr[] = {\r
5914#ifdef _CS_ARCHITECTURE\r
5915 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},\r
5916#endif\r
5917#ifdef _CS_HOSTNAME\r
5918 {"CS_HOSTNAME", _CS_HOSTNAME},\r
5919#endif\r
5920#ifdef _CS_HW_PROVIDER\r
5921 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},\r
5922#endif\r
5923#ifdef _CS_HW_SERIAL\r
5924 {"CS_HW_SERIAL", _CS_HW_SERIAL},\r
5925#endif\r
5926#ifdef _CS_INITTAB_NAME\r
5927 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},\r
5928#endif\r
5929#ifdef _CS_LFS64_CFLAGS\r
5930 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},\r
5931#endif\r
5932#ifdef _CS_LFS64_LDFLAGS\r
5933 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},\r
5934#endif\r
5935#ifdef _CS_LFS64_LIBS\r
5936 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},\r
5937#endif\r
5938#ifdef _CS_LFS64_LINTFLAGS\r
5939 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},\r
5940#endif\r
5941#ifdef _CS_LFS_CFLAGS\r
5942 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},\r
5943#endif\r
5944#ifdef _CS_LFS_LDFLAGS\r
5945 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},\r
5946#endif\r
5947#ifdef _CS_LFS_LIBS\r
5948 {"CS_LFS_LIBS", _CS_LFS_LIBS},\r
5949#endif\r
5950#ifdef _CS_LFS_LINTFLAGS\r
5951 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},\r
5952#endif\r
5953#ifdef _CS_MACHINE\r
5954 {"CS_MACHINE", _CS_MACHINE},\r
5955#endif\r
5956#ifdef _CS_PATH\r
5957 {"CS_PATH", _CS_PATH},\r
5958#endif\r
5959#ifdef _CS_RELEASE\r
5960 {"CS_RELEASE", _CS_RELEASE},\r
5961#endif\r
5962#ifdef _CS_SRPC_DOMAIN\r
5963 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},\r
5964#endif\r
5965#ifdef _CS_SYSNAME\r
5966 {"CS_SYSNAME", _CS_SYSNAME},\r
5967#endif\r
5968#ifdef _CS_VERSION\r
5969 {"CS_VERSION", _CS_VERSION},\r
5970#endif\r
5971#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS\r
5972 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},\r
5973#endif\r
5974#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS\r
5975 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},\r
5976#endif\r
5977#ifdef _CS_XBS5_ILP32_OFF32_LIBS\r
5978 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},\r
5979#endif\r
5980#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS\r
5981 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},\r
5982#endif\r
5983#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS\r
5984 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},\r
5985#endif\r
5986#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS\r
5987 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},\r
5988#endif\r
5989#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS\r
5990 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},\r
5991#endif\r
5992#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS\r
5993 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},\r
5994#endif\r
5995#ifdef _CS_XBS5_LP64_OFF64_CFLAGS\r
5996 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},\r
5997#endif\r
5998#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS\r
5999 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},\r
6000#endif\r
6001#ifdef _CS_XBS5_LP64_OFF64_LIBS\r
6002 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},\r
6003#endif\r
6004#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS\r
6005 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},\r
6006#endif\r
6007#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS\r
6008 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},\r
6009#endif\r
6010#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS\r
6011 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},\r
6012#endif\r
6013#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS\r
6014 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},\r
6015#endif\r
6016#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS\r
6017 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},\r
6018#endif\r
6019#ifdef _MIPS_CS_AVAIL_PROCESSORS\r
6020 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},\r
6021#endif\r
6022#ifdef _MIPS_CS_BASE\r
6023 {"MIPS_CS_BASE", _MIPS_CS_BASE},\r
6024#endif\r
6025#ifdef _MIPS_CS_HOSTID\r
6026 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},\r
6027#endif\r
6028#ifdef _MIPS_CS_HW_NAME\r
6029 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},\r
6030#endif\r
6031#ifdef _MIPS_CS_NUM_PROCESSORS\r
6032 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},\r
6033#endif\r
6034#ifdef _MIPS_CS_OSREL_MAJ\r
6035 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},\r
6036#endif\r
6037#ifdef _MIPS_CS_OSREL_MIN\r
6038 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},\r
6039#endif\r
6040#ifdef _MIPS_CS_OSREL_PATCH\r
6041 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},\r
6042#endif\r
6043#ifdef _MIPS_CS_OS_NAME\r
6044 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},\r
6045#endif\r
6046#ifdef _MIPS_CS_OS_PROVIDER\r
6047 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},\r
6048#endif\r
6049#ifdef _MIPS_CS_PROCESSORS\r
6050 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},\r
6051#endif\r
6052#ifdef _MIPS_CS_SERIAL\r
6053 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},\r
6054#endif\r
6055#ifdef _MIPS_CS_VENDOR\r
6056 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},\r
6057#endif\r
6058};\r
6059\r
6060static int\r
6061conv_confstr_confname(PyObject *arg, int *valuep)\r
6062{\r
6063 return conv_confname(arg, valuep, posix_constants_confstr,\r
6064 sizeof(posix_constants_confstr)\r
6065 / sizeof(struct constdef));\r
6066}\r
6067\r
6068PyDoc_STRVAR(posix_confstr__doc__,\r
6069"confstr(name) -> string\n\n\\r
6070Return a string-valued system configuration variable.");\r
6071\r
6072static PyObject *\r
6073posix_confstr(PyObject *self, PyObject *args)\r
6074{\r
6075 PyObject *result = NULL;\r
6076 int name;\r
6077 char buffer[256];\r
6078\r
6079 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {\r
6080 int len;\r
6081\r
6082 errno = 0;\r
6083 len = confstr(name, buffer, sizeof(buffer));\r
6084 if (len == 0) {\r
6085 if (errno) {\r
6086 posix_error();\r
6087 }\r
6088 else {\r
6089 result = Py_None;\r
6090 Py_INCREF(Py_None);\r
6091 }\r
6092 }\r
6093 else {\r
6094 if ((unsigned int)len >= sizeof(buffer)) {\r
6095 result = PyString_FromStringAndSize(NULL, len-1);\r
6096 if (result != NULL)\r
6097 confstr(name, PyString_AS_STRING(result), len);\r
6098 }\r
6099 else\r
6100 result = PyString_FromStringAndSize(buffer, len-1);\r
6101 }\r
6102 }\r
6103 return result;\r
6104}\r
6105#endif\r
6106\r
6107\r
6108#ifdef HAVE_SYSCONF\r
6109static struct constdef posix_constants_sysconf[] = {\r
6110#ifdef _SC_2_CHAR_TERM\r
6111 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},\r
6112#endif\r
6113#ifdef _SC_2_C_BIND\r
6114 {"SC_2_C_BIND", _SC_2_C_BIND},\r
6115#endif\r
6116#ifdef _SC_2_C_DEV\r
6117 {"SC_2_C_DEV", _SC_2_C_DEV},\r
6118#endif\r
6119#ifdef _SC_2_C_VERSION\r
6120 {"SC_2_C_VERSION", _SC_2_C_VERSION},\r
6121#endif\r
6122#ifdef _SC_2_FORT_DEV\r
6123 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},\r
6124#endif\r
6125#ifdef _SC_2_FORT_RUN\r
6126 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},\r
6127#endif\r
6128#ifdef _SC_2_LOCALEDEF\r
6129 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},\r
6130#endif\r
6131#ifdef _SC_2_SW_DEV\r
6132 {"SC_2_SW_DEV", _SC_2_SW_DEV},\r
6133#endif\r
6134#ifdef _SC_2_UPE\r
6135 {"SC_2_UPE", _SC_2_UPE},\r
6136#endif\r
6137#ifdef _SC_2_VERSION\r
6138 {"SC_2_VERSION", _SC_2_VERSION},\r
6139#endif\r
6140#ifdef _SC_ABI_ASYNCHRONOUS_IO\r
6141 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},\r
6142#endif\r
6143#ifdef _SC_ACL\r
6144 {"SC_ACL", _SC_ACL},\r
6145#endif\r
6146#ifdef _SC_AIO_LISTIO_MAX\r
6147 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},\r
6148#endif\r
6149#ifdef _SC_AIO_MAX\r
6150 {"SC_AIO_MAX", _SC_AIO_MAX},\r
6151#endif\r
6152#ifdef _SC_AIO_PRIO_DELTA_MAX\r
6153 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},\r
6154#endif\r
6155#ifdef _SC_ARG_MAX\r
6156 {"SC_ARG_MAX", _SC_ARG_MAX},\r
6157#endif\r
6158#ifdef _SC_ASYNCHRONOUS_IO\r
6159 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},\r
6160#endif\r
6161#ifdef _SC_ATEXIT_MAX\r
6162 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},\r
6163#endif\r
6164#ifdef _SC_AUDIT\r
6165 {"SC_AUDIT", _SC_AUDIT},\r
6166#endif\r
6167#ifdef _SC_AVPHYS_PAGES\r
6168 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},\r
6169#endif\r
6170#ifdef _SC_BC_BASE_MAX\r
6171 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},\r
6172#endif\r
6173#ifdef _SC_BC_DIM_MAX\r
6174 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},\r
6175#endif\r
6176#ifdef _SC_BC_SCALE_MAX\r
6177 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},\r
6178#endif\r
6179#ifdef _SC_BC_STRING_MAX\r
6180 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},\r
6181#endif\r
6182#ifdef _SC_CAP\r
6183 {"SC_CAP", _SC_CAP},\r
6184#endif\r
6185#ifdef _SC_CHARCLASS_NAME_MAX\r
6186 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},\r
6187#endif\r
6188#ifdef _SC_CHAR_BIT\r
6189 {"SC_CHAR_BIT", _SC_CHAR_BIT},\r
6190#endif\r
6191#ifdef _SC_CHAR_MAX\r
6192 {"SC_CHAR_MAX", _SC_CHAR_MAX},\r
6193#endif\r
6194#ifdef _SC_CHAR_MIN\r
6195 {"SC_CHAR_MIN", _SC_CHAR_MIN},\r
6196#endif\r
6197#ifdef _SC_CHILD_MAX\r
6198 {"SC_CHILD_MAX", _SC_CHILD_MAX},\r
6199#endif\r
6200#ifdef _SC_CLK_TCK\r
6201 {"SC_CLK_TCK", _SC_CLK_TCK},\r
6202#endif\r
6203#ifdef _SC_COHER_BLKSZ\r
6204 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},\r
6205#endif\r
6206#ifdef _SC_COLL_WEIGHTS_MAX\r
6207 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},\r
6208#endif\r
6209#ifdef _SC_DCACHE_ASSOC\r
6210 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},\r
6211#endif\r
6212#ifdef _SC_DCACHE_BLKSZ\r
6213 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},\r
6214#endif\r
6215#ifdef _SC_DCACHE_LINESZ\r
6216 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},\r
6217#endif\r
6218#ifdef _SC_DCACHE_SZ\r
6219 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},\r
6220#endif\r
6221#ifdef _SC_DCACHE_TBLKSZ\r
6222 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},\r
6223#endif\r
6224#ifdef _SC_DELAYTIMER_MAX\r
6225 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},\r
6226#endif\r
6227#ifdef _SC_EQUIV_CLASS_MAX\r
6228 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},\r
6229#endif\r
6230#ifdef _SC_EXPR_NEST_MAX\r
6231 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},\r
6232#endif\r
6233#ifdef _SC_FSYNC\r
6234 {"SC_FSYNC", _SC_FSYNC},\r
6235#endif\r
6236#ifdef _SC_GETGR_R_SIZE_MAX\r
6237 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},\r
6238#endif\r
6239#ifdef _SC_GETPW_R_SIZE_MAX\r
6240 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},\r
6241#endif\r
6242#ifdef _SC_ICACHE_ASSOC\r
6243 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},\r
6244#endif\r
6245#ifdef _SC_ICACHE_BLKSZ\r
6246 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},\r
6247#endif\r
6248#ifdef _SC_ICACHE_LINESZ\r
6249 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},\r
6250#endif\r
6251#ifdef _SC_ICACHE_SZ\r
6252 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},\r
6253#endif\r
6254#ifdef _SC_INF\r
6255 {"SC_INF", _SC_INF},\r
6256#endif\r
6257#ifdef _SC_INT_MAX\r
6258 {"SC_INT_MAX", _SC_INT_MAX},\r
6259#endif\r
6260#ifdef _SC_INT_MIN\r
6261 {"SC_INT_MIN", _SC_INT_MIN},\r
6262#endif\r
6263#ifdef _SC_IOV_MAX\r
6264 {"SC_IOV_MAX", _SC_IOV_MAX},\r
6265#endif\r
6266#ifdef _SC_IP_SECOPTS\r
6267 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},\r
6268#endif\r
6269#ifdef _SC_JOB_CONTROL\r
6270 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},\r
6271#endif\r
6272#ifdef _SC_KERN_POINTERS\r
6273 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},\r
6274#endif\r
6275#ifdef _SC_KERN_SIM\r
6276 {"SC_KERN_SIM", _SC_KERN_SIM},\r
6277#endif\r
6278#ifdef _SC_LINE_MAX\r
6279 {"SC_LINE_MAX", _SC_LINE_MAX},\r
6280#endif\r
6281#ifdef _SC_LOGIN_NAME_MAX\r
6282 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},\r
6283#endif\r
6284#ifdef _SC_LOGNAME_MAX\r
6285 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},\r
6286#endif\r
6287#ifdef _SC_LONG_BIT\r
6288 {"SC_LONG_BIT", _SC_LONG_BIT},\r
6289#endif\r
6290#ifdef _SC_MAC\r
6291 {"SC_MAC", _SC_MAC},\r
6292#endif\r
6293#ifdef _SC_MAPPED_FILES\r
6294 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},\r
6295#endif\r
6296#ifdef _SC_MAXPID\r
6297 {"SC_MAXPID", _SC_MAXPID},\r
6298#endif\r
6299#ifdef _SC_MB_LEN_MAX\r
6300 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},\r
6301#endif\r
6302#ifdef _SC_MEMLOCK\r
6303 {"SC_MEMLOCK", _SC_MEMLOCK},\r
6304#endif\r
6305#ifdef _SC_MEMLOCK_RANGE\r
6306 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},\r
6307#endif\r
6308#ifdef _SC_MEMORY_PROTECTION\r
6309 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},\r
6310#endif\r
6311#ifdef _SC_MESSAGE_PASSING\r
6312 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},\r
6313#endif\r
6314#ifdef _SC_MMAP_FIXED_ALIGNMENT\r
6315 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},\r
6316#endif\r
6317#ifdef _SC_MQ_OPEN_MAX\r
6318 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},\r
6319#endif\r
6320#ifdef _SC_MQ_PRIO_MAX\r
6321 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},\r
6322#endif\r
6323#ifdef _SC_NACLS_MAX\r
6324 {"SC_NACLS_MAX", _SC_NACLS_MAX},\r
6325#endif\r
6326#ifdef _SC_NGROUPS_MAX\r
6327 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},\r
6328#endif\r
6329#ifdef _SC_NL_ARGMAX\r
6330 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},\r
6331#endif\r
6332#ifdef _SC_NL_LANGMAX\r
6333 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},\r
6334#endif\r
6335#ifdef _SC_NL_MSGMAX\r
6336 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},\r
6337#endif\r
6338#ifdef _SC_NL_NMAX\r
6339 {"SC_NL_NMAX", _SC_NL_NMAX},\r
6340#endif\r
6341#ifdef _SC_NL_SETMAX\r
6342 {"SC_NL_SETMAX", _SC_NL_SETMAX},\r
6343#endif\r
6344#ifdef _SC_NL_TEXTMAX\r
6345 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},\r
6346#endif\r
6347#ifdef _SC_NPROCESSORS_CONF\r
6348 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},\r
6349#endif\r
6350#ifdef _SC_NPROCESSORS_ONLN\r
6351 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},\r
6352#endif\r
6353#ifdef _SC_NPROC_CONF\r
6354 {"SC_NPROC_CONF", _SC_NPROC_CONF},\r
6355#endif\r
6356#ifdef _SC_NPROC_ONLN\r
6357 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},\r
6358#endif\r
6359#ifdef _SC_NZERO\r
6360 {"SC_NZERO", _SC_NZERO},\r
6361#endif\r
6362#ifdef _SC_OPEN_MAX\r
6363 {"SC_OPEN_MAX", _SC_OPEN_MAX},\r
6364#endif\r
6365#ifdef _SC_PAGESIZE\r
6366 {"SC_PAGESIZE", _SC_PAGESIZE},\r
6367#endif\r
6368#ifdef _SC_PAGE_SIZE\r
6369 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},\r
6370#endif\r
6371#ifdef _SC_PASS_MAX\r
6372 {"SC_PASS_MAX", _SC_PASS_MAX},\r
6373#endif\r
6374#ifdef _SC_PHYS_PAGES\r
6375 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},\r
6376#endif\r
6377#ifdef _SC_PII\r
6378 {"SC_PII", _SC_PII},\r
6379#endif\r
6380#ifdef _SC_PII_INTERNET\r
6381 {"SC_PII_INTERNET", _SC_PII_INTERNET},\r
6382#endif\r
6383#ifdef _SC_PII_INTERNET_DGRAM\r
6384 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},\r
6385#endif\r
6386#ifdef _SC_PII_INTERNET_STREAM\r
6387 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},\r
6388#endif\r
6389#ifdef _SC_PII_OSI\r
6390 {"SC_PII_OSI", _SC_PII_OSI},\r
6391#endif\r
6392#ifdef _SC_PII_OSI_CLTS\r
6393 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},\r
6394#endif\r
6395#ifdef _SC_PII_OSI_COTS\r
6396 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},\r
6397#endif\r
6398#ifdef _SC_PII_OSI_M\r
6399 {"SC_PII_OSI_M", _SC_PII_OSI_M},\r
6400#endif\r
6401#ifdef _SC_PII_SOCKET\r
6402 {"SC_PII_SOCKET", _SC_PII_SOCKET},\r
6403#endif\r
6404#ifdef _SC_PII_XTI\r
6405 {"SC_PII_XTI", _SC_PII_XTI},\r
6406#endif\r
6407#ifdef _SC_POLL\r
6408 {"SC_POLL", _SC_POLL},\r
6409#endif\r
6410#ifdef _SC_PRIORITIZED_IO\r
6411 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},\r
6412#endif\r
6413#ifdef _SC_PRIORITY_SCHEDULING\r
6414 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},\r
6415#endif\r
6416#ifdef _SC_REALTIME_SIGNALS\r
6417 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},\r
6418#endif\r
6419#ifdef _SC_RE_DUP_MAX\r
6420 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},\r
6421#endif\r
6422#ifdef _SC_RTSIG_MAX\r
6423 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},\r
6424#endif\r
6425#ifdef _SC_SAVED_IDS\r
6426 {"SC_SAVED_IDS", _SC_SAVED_IDS},\r
6427#endif\r
6428#ifdef _SC_SCHAR_MAX\r
6429 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},\r
6430#endif\r
6431#ifdef _SC_SCHAR_MIN\r
6432 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},\r
6433#endif\r
6434#ifdef _SC_SELECT\r
6435 {"SC_SELECT", _SC_SELECT},\r
6436#endif\r
6437#ifdef _SC_SEMAPHORES\r
6438 {"SC_SEMAPHORES", _SC_SEMAPHORES},\r
6439#endif\r
6440#ifdef _SC_SEM_NSEMS_MAX\r
6441 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},\r
6442#endif\r
6443#ifdef _SC_SEM_VALUE_MAX\r
6444 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},\r
6445#endif\r
6446#ifdef _SC_SHARED_MEMORY_OBJECTS\r
6447 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},\r
6448#endif\r
6449#ifdef _SC_SHRT_MAX\r
6450 {"SC_SHRT_MAX", _SC_SHRT_MAX},\r
6451#endif\r
6452#ifdef _SC_SHRT_MIN\r
6453 {"SC_SHRT_MIN", _SC_SHRT_MIN},\r
6454#endif\r
6455#ifdef _SC_SIGQUEUE_MAX\r
6456 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},\r
6457#endif\r
6458#ifdef _SC_SIGRT_MAX\r
6459 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},\r
6460#endif\r
6461#ifdef _SC_SIGRT_MIN\r
6462 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},\r
6463#endif\r
6464#ifdef _SC_SOFTPOWER\r
6465 {"SC_SOFTPOWER", _SC_SOFTPOWER},\r
6466#endif\r
6467#ifdef _SC_SPLIT_CACHE\r
6468 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},\r
6469#endif\r
6470#ifdef _SC_SSIZE_MAX\r
6471 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},\r
6472#endif\r
6473#ifdef _SC_STACK_PROT\r
6474 {"SC_STACK_PROT", _SC_STACK_PROT},\r
6475#endif\r
6476#ifdef _SC_STREAM_MAX\r
6477 {"SC_STREAM_MAX", _SC_STREAM_MAX},\r
6478#endif\r
6479#ifdef _SC_SYNCHRONIZED_IO\r
6480 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},\r
6481#endif\r
6482#ifdef _SC_THREADS\r
6483 {"SC_THREADS", _SC_THREADS},\r
6484#endif\r
6485#ifdef _SC_THREAD_ATTR_STACKADDR\r
6486 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},\r
6487#endif\r
6488#ifdef _SC_THREAD_ATTR_STACKSIZE\r
6489 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},\r
6490#endif\r
6491#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS\r
6492 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},\r
6493#endif\r
6494#ifdef _SC_THREAD_KEYS_MAX\r
6495 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},\r
6496#endif\r
6497#ifdef _SC_THREAD_PRIORITY_SCHEDULING\r
6498 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},\r
6499#endif\r
6500#ifdef _SC_THREAD_PRIO_INHERIT\r
6501 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},\r
6502#endif\r
6503#ifdef _SC_THREAD_PRIO_PROTECT\r
6504 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},\r
6505#endif\r
6506#ifdef _SC_THREAD_PROCESS_SHARED\r
6507 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},\r
6508#endif\r
6509#ifdef _SC_THREAD_SAFE_FUNCTIONS\r
6510 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},\r
6511#endif\r
6512#ifdef _SC_THREAD_STACK_MIN\r
6513 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},\r
6514#endif\r
6515#ifdef _SC_THREAD_THREADS_MAX\r
6516 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},\r
6517#endif\r
6518#ifdef _SC_TIMERS\r
6519 {"SC_TIMERS", _SC_TIMERS},\r
6520#endif\r
6521#ifdef _SC_TIMER_MAX\r
6522 {"SC_TIMER_MAX", _SC_TIMER_MAX},\r
6523#endif\r
6524#ifdef _SC_TTY_NAME_MAX\r
6525 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},\r
6526#endif\r
6527#ifdef _SC_TZNAME_MAX\r
6528 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},\r
6529#endif\r
6530#ifdef _SC_T_IOV_MAX\r
6531 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},\r
6532#endif\r
6533#ifdef _SC_UCHAR_MAX\r
6534 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},\r
6535#endif\r
6536#ifdef _SC_UINT_MAX\r
6537 {"SC_UINT_MAX", _SC_UINT_MAX},\r
6538#endif\r
6539#ifdef _SC_UIO_MAXIOV\r
6540 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},\r
6541#endif\r
6542#ifdef _SC_ULONG_MAX\r
6543 {"SC_ULONG_MAX", _SC_ULONG_MAX},\r
6544#endif\r
6545#ifdef _SC_USHRT_MAX\r
6546 {"SC_USHRT_MAX", _SC_USHRT_MAX},\r
6547#endif\r
6548#ifdef _SC_VERSION\r
6549 {"SC_VERSION", _SC_VERSION},\r
6550#endif\r
6551#ifdef _SC_WORD_BIT\r
6552 {"SC_WORD_BIT", _SC_WORD_BIT},\r
6553#endif\r
6554#ifdef _SC_XBS5_ILP32_OFF32\r
6555 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},\r
6556#endif\r
6557#ifdef _SC_XBS5_ILP32_OFFBIG\r
6558 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},\r
6559#endif\r
6560#ifdef _SC_XBS5_LP64_OFF64\r
6561 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},\r
6562#endif\r
6563#ifdef _SC_XBS5_LPBIG_OFFBIG\r
6564 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},\r
6565#endif\r
6566#ifdef _SC_XOPEN_CRYPT\r
6567 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},\r
6568#endif\r
6569#ifdef _SC_XOPEN_ENH_I18N\r
6570 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},\r
6571#endif\r
6572#ifdef _SC_XOPEN_LEGACY\r
6573 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},\r
6574#endif\r
6575#ifdef _SC_XOPEN_REALTIME\r
6576 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},\r
6577#endif\r
6578#ifdef _SC_XOPEN_REALTIME_THREADS\r
6579 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},\r
6580#endif\r
6581#ifdef _SC_XOPEN_SHM\r
6582 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},\r
6583#endif\r
6584#ifdef _SC_XOPEN_UNIX\r
6585 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},\r
6586#endif\r
6587#ifdef _SC_XOPEN_VERSION\r
6588 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},\r
6589#endif\r
6590#ifdef _SC_XOPEN_XCU_VERSION\r
6591 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},\r
6592#endif\r
6593#ifdef _SC_XOPEN_XPG2\r
6594 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},\r
6595#endif\r
6596#ifdef _SC_XOPEN_XPG3\r
6597 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},\r
6598#endif\r
6599#ifdef _SC_XOPEN_XPG4\r
6600 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},\r
6601#endif\r
6602};\r
6603\r
6604static int\r
6605conv_sysconf_confname(PyObject *arg, int *valuep)\r
6606{\r
6607 return conv_confname(arg, valuep, posix_constants_sysconf,\r
6608 sizeof(posix_constants_sysconf)\r
6609 / sizeof(struct constdef));\r
6610}\r
6611\r
6612PyDoc_STRVAR(posix_sysconf__doc__,\r
6613"sysconf(name) -> integer\n\n\\r
6614Return an integer-valued system configuration variable.");\r
6615\r
6616static PyObject *\r
6617posix_sysconf(PyObject *self, PyObject *args)\r
6618{\r
6619 PyObject *result = NULL;\r
6620 int name;\r
6621\r
6622 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {\r
6623 int value;\r
6624\r
6625 errno = 0;\r
6626 value = sysconf(name);\r
6627 if (value == -1 && errno != 0)\r
6628 posix_error();\r
6629 else\r
6630 result = PyInt_FromLong(value);\r
6631 }\r
6632 return result;\r
6633}\r
6634#endif\r
6635\r
6636\r
6637#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) || defined(HAVE_CONFSTR) || defined(HAVE_SYSCONF)\r
6638/* This code is used to ensure that the tables of configuration value names\r
6639 * are in sorted order as required by conv_confname(), and also to build the\r
6640 * the exported dictionaries that are used to publish information about the\r
6641 * names available on the host platform.\r
6642 *\r
6643 * Sorting the table at runtime ensures that the table is properly ordered\r
6644 * when used, even for platforms we're not able to test on. It also makes\r
6645 * it easier to add additional entries to the tables.\r
6646 */\r
6647\r
6648static int\r
6649cmp_constdefs(const void *v1, const void *v2)\r
6650{\r
6651 const struct constdef *c1 =\r
6652 (const struct constdef *) v1;\r
6653 const struct constdef *c2 =\r
6654 (const struct constdef *) v2;\r
6655\r
6656 return strcmp(c1->name, c2->name);\r
6657}\r
6658\r
6659static int\r
6660setup_confname_table(struct constdef *table, size_t tablesize,\r
6661 char *tablename, PyObject *module)\r
6662{\r
6663 PyObject *d = NULL;\r
6664 size_t i;\r
6665\r
6666 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);\r
6667 d = PyDict_New();\r
6668 if (d == NULL)\r
6669 return -1;\r
6670\r
6671 for (i=0; i < tablesize; ++i) {\r
6672 PyObject *o = PyInt_FromLong(table[i].value);\r
6673 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {\r
6674 Py_XDECREF(o);\r
6675 Py_DECREF(d);\r
6676 return -1;\r
6677 }\r
6678 Py_DECREF(o);\r
6679 }\r
6680 return PyModule_AddObject(module, tablename, d);\r
6681}\r
6682#endif /* HAVE_FPATHCONF || HAVE_PATHCONF || HAVE_CONFSTR || HAVE_SYSCONF */\r
6683\r
6684/* Return -1 on failure, 0 on success. */\r
6685static int\r
6686setup_confname_tables(PyObject *module)\r
6687{\r
6688#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)\r
6689 if (setup_confname_table(posix_constants_pathconf,\r
6690 sizeof(posix_constants_pathconf)\r
6691 / sizeof(struct constdef),\r
6692 "pathconf_names", module))\r
6693 return -1;\r
6694#endif\r
6695#ifdef HAVE_CONFSTR\r
6696 if (setup_confname_table(posix_constants_confstr,\r
6697 sizeof(posix_constants_confstr)\r
6698 / sizeof(struct constdef),\r
6699 "confstr_names", module))\r
6700 return -1;\r
6701#endif\r
6702#ifdef HAVE_SYSCONF\r
6703 if (setup_confname_table(posix_constants_sysconf,\r
6704 sizeof(posix_constants_sysconf)\r
6705 / sizeof(struct constdef),\r
6706 "sysconf_names", module))\r
6707 return -1;\r
6708#endif\r
6709 return 0;\r
6710}\r
6711\r
6712\r
6713PyDoc_STRVAR(posix_abort__doc__,\r
6714"abort() -> does not return!\n\n\\r
6715Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\\r
6716in the hardest way possible on the hosting operating system.");\r
6717\r
6718static PyObject *\r
6719posix_abort(PyObject *self, PyObject *noargs)\r
6720{\r
6721 abort();\r
6722 /*NOTREACHED*/\r
6723 Py_FatalError("abort() called from Python code didn't abort!");\r
6724 return NULL;\r
6725}\r
6726\r
6727#ifdef HAVE_SETRESUID\r
6728PyDoc_STRVAR(posix_setresuid__doc__,\r
6729"setresuid(ruid, euid, suid)\n\n\\r
6730Set the current process's real, effective, and saved user ids.");\r
6731\r
6732static PyObject*\r
6733posix_setresuid (PyObject *self, PyObject *args)\r
6734{\r
6735 /* We assume uid_t is no larger than a long. */\r
6736 long ruid, euid, suid;\r
6737 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))\r
6738 return NULL;\r
6739 if (setresuid(ruid, euid, suid) < 0)\r
6740 return posix_error();\r
6741 Py_RETURN_NONE;\r
6742}\r
6743#endif\r
6744\r
6745#ifdef HAVE_SETRESGID\r
6746PyDoc_STRVAR(posix_setresgid__doc__,\r
6747"setresgid(rgid, egid, sgid)\n\n\\r
6748Set the current process's real, effective, and saved group ids.");\r
6749\r
6750static PyObject*\r
6751posix_setresgid (PyObject *self, PyObject *args)\r
6752{\r
6753 /* We assume uid_t is no larger than a long. */\r
6754 long rgid, egid, sgid;\r
6755 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))\r
6756 return NULL;\r
6757 if (setresgid(rgid, egid, sgid) < 0)\r
6758 return posix_error();\r
6759 Py_RETURN_NONE;\r
6760}\r
6761#endif\r
6762\r
6763#ifdef HAVE_GETRESUID\r
6764PyDoc_STRVAR(posix_getresuid__doc__,\r
6765"getresuid() -> (ruid, euid, suid)\n\n\\r
6766Get tuple of the current process's real, effective, and saved user ids.");\r
6767\r
6768static PyObject*\r
6769posix_getresuid (PyObject *self, PyObject *noargs)\r
6770{\r
6771 uid_t ruid, euid, suid;\r
6772 long l_ruid, l_euid, l_suid;\r
6773 if (getresuid(&ruid, &euid, &suid) < 0)\r
6774 return posix_error();\r
6775 /* Force the values into long's as we don't know the size of uid_t. */\r
6776 l_ruid = ruid;\r
6777 l_euid = euid;\r
6778 l_suid = suid;\r
6779 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);\r
6780}\r
6781#endif\r
6782\r
6783#ifdef HAVE_GETRESGID\r
6784PyDoc_STRVAR(posix_getresgid__doc__,\r
6785"getresgid() -> (rgid, egid, sgid)\n\n\\r
6786Get tuple of the current process's real, effective, and saved group ids.");\r
6787\r
6788static PyObject*\r
6789posix_getresgid (PyObject *self, PyObject *noargs)\r
6790{\r
6791 uid_t rgid, egid, sgid;\r
6792 long l_rgid, l_egid, l_sgid;\r
6793 if (getresgid(&rgid, &egid, &sgid) < 0)\r
6794 return posix_error();\r
6795 /* Force the values into long's as we don't know the size of uid_t. */\r
6796 l_rgid = rgid;\r
6797 l_egid = egid;\r
6798 l_sgid = sgid;\r
6799 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);\r
6800}\r
6801#endif\r
6802\r
6803static PyMethodDef posix_methods[] = {\r
6804 {"access", posix_access, METH_VARARGS, posix_access__doc__},\r
6805#ifdef HAVE_TTYNAME\r
6806 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},\r
6807#endif\r
6808 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},\r
6809#ifdef HAVE_CHFLAGS\r
6810 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},\r
6811#endif /* HAVE_CHFLAGS */\r
6812 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},\r
6813#ifdef HAVE_FCHMOD\r
6814 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},\r
6815#endif /* HAVE_FCHMOD */\r
6816#ifdef HAVE_CHOWN\r
6817 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},\r
6818#endif /* HAVE_CHOWN */\r
6819#ifdef HAVE_LCHMOD\r
6820 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},\r
6821#endif /* HAVE_LCHMOD */\r
6822#ifdef HAVE_FCHOWN\r
6823 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},\r
6824#endif /* HAVE_FCHOWN */\r
6825#ifdef HAVE_LCHFLAGS\r
6826 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},\r
6827#endif /* HAVE_LCHFLAGS */\r
6828#ifdef HAVE_LCHOWN\r
6829 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},\r
6830#endif /* HAVE_LCHOWN */\r
6831#ifdef HAVE_CHROOT\r
6832 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},\r
6833#endif\r
6834#ifdef HAVE_CTERMID\r
6835 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},\r
6836#endif\r
6837#ifdef HAVE_GETCWD\r
6838 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},\r
6839#ifdef Py_USING_UNICODE\r
6840 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},\r
6841#endif\r
6842#endif\r
6843#ifdef HAVE_LINK\r
6844 {"link", posix_link, METH_VARARGS, posix_link__doc__},\r
6845#endif /* HAVE_LINK */\r
6846 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},\r
6847 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},\r
6848 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},\r
6849#ifdef HAVE_NICE\r
6850 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},\r
6851#endif /* HAVE_NICE */\r
6852#ifdef HAVE_READLINK\r
6853 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},\r
6854#endif /* HAVE_READLINK */\r
6855 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},\r
6856 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},\r
6857 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},\r
6858 //{"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},\r
6859#ifdef HAVE_SYMLINK\r
6860 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},\r
6861#endif /* HAVE_SYMLINK */\r
6862#ifdef HAVE_SYSTEM\r
6863 {"system", posix_system, METH_VARARGS, posix_system__doc__},\r
6864#endif\r
6865 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},\r
6866#ifdef HAVE_UNAME\r
6867 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},\r
6868#endif /* HAVE_UNAME */\r
6869 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},\r
6870 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},\r
6871 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},\r
6872#ifdef HAVE_TIMES\r
6873 {"times", posix_times, METH_NOARGS, posix_times__doc__},\r
6874#endif /* HAVE_TIMES */\r
6875 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},\r
6876#ifdef HAVE_EXECV\r
6877 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},\r
6878 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},\r
6879#endif /* HAVE_EXECV */\r
6880#ifdef HAVE_SPAWNV\r
6881 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},\r
6882 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},\r
6883#if defined(PYOS_OS2)\r
6884 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},\r
6885 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},\r
6886#endif /* PYOS_OS2 */\r
6887#endif /* HAVE_SPAWNV */\r
6888#ifdef HAVE_FORK1\r
6889 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},\r
6890#endif /* HAVE_FORK1 */\r
6891#ifdef HAVE_FORK\r
6892 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},\r
6893#endif /* HAVE_FORK */\r
6894#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)\r
6895 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},\r
6896#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */\r
6897#ifdef HAVE_FORKPTY\r
6898 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},\r
6899#endif /* HAVE_FORKPTY */\r
6900#ifdef HAVE_GETEGID\r
6901 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},\r
6902#endif /* HAVE_GETEGID */\r
6903#ifdef HAVE_GETEUID\r
6904 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},\r
6905#endif /* HAVE_GETEUID */\r
6906#ifdef HAVE_GETGID\r
6907 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},\r
6908#endif /* HAVE_GETGID */\r
6909#ifdef HAVE_GETGROUPS\r
6910 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},\r
6911#endif\r
6912 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},\r
6913#ifdef HAVE_GETPGRP\r
6914 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},\r
6915#endif /* HAVE_GETPGRP */\r
6916#ifdef HAVE_GETPPID\r
6917 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},\r
6918#endif /* HAVE_GETPPID */\r
6919#ifdef HAVE_GETUID\r
6920 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},\r
6921#endif /* HAVE_GETUID */\r
6922#ifdef HAVE_GETLOGIN\r
6923 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},\r
6924#endif\r
6925#ifdef HAVE_KILL\r
6926 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},\r
6927#endif /* HAVE_KILL */\r
6928#ifdef HAVE_KILLPG\r
6929 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},\r
6930#endif /* HAVE_KILLPG */\r
6931#ifdef HAVE_PLOCK\r
6932 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},\r
6933#endif /* HAVE_PLOCK */\r
6934#ifdef HAVE_POPEN\r
6935 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},\r
6936#ifdef MS_WINDOWS\r
6937 {"popen2", win32_popen2, METH_VARARGS},\r
6938 {"popen3", win32_popen3, METH_VARARGS},\r
6939 {"popen4", win32_popen4, METH_VARARGS},\r
6940 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},\r
6941 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},\r
6942#else\r
6943#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
6944 {"popen2", os2emx_popen2, METH_VARARGS},\r
6945 {"popen3", os2emx_popen3, METH_VARARGS},\r
6946 {"popen4", os2emx_popen4, METH_VARARGS},\r
6947#endif\r
6948#endif\r
6949#endif /* HAVE_POPEN */\r
6950#ifdef HAVE_SETUID\r
6951 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},\r
6952#endif /* HAVE_SETUID */\r
6953#ifdef HAVE_SETEUID\r
6954 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},\r
6955#endif /* HAVE_SETEUID */\r
6956#ifdef HAVE_SETEGID\r
6957 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},\r
6958#endif /* HAVE_SETEGID */\r
6959#ifdef HAVE_SETREUID\r
6960 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},\r
6961#endif /* HAVE_SETREUID */\r
6962#ifdef HAVE_SETREGID\r
6963 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},\r
6964#endif /* HAVE_SETREGID */\r
6965#ifdef HAVE_SETGID\r
6966 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},\r
6967#endif /* HAVE_SETGID */\r
6968#ifdef HAVE_SETGROUPS\r
6969 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},\r
6970#endif /* HAVE_SETGROUPS */\r
6971#ifdef HAVE_INITGROUPS\r
6972 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},\r
6973#endif /* HAVE_INITGROUPS */\r
6974#ifdef HAVE_GETPGID\r
6975 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},\r
6976#endif /* HAVE_GETPGID */\r
6977#ifdef HAVE_SETPGRP\r
6978 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},\r
6979#endif /* HAVE_SETPGRP */\r
6980#ifdef HAVE_WAIT\r
6981 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},\r
6982#endif /* HAVE_WAIT */\r
6983#ifdef HAVE_WAIT3\r
6984 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},\r
6985#endif /* HAVE_WAIT3 */\r
6986#ifdef HAVE_WAIT4\r
6987 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},\r
6988#endif /* HAVE_WAIT4 */\r
6989#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)\r
6990 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},\r
6991#endif /* HAVE_WAITPID */\r
6992#ifdef HAVE_GETSID\r
6993 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},\r
6994#endif /* HAVE_GETSID */\r
6995#ifdef HAVE_SETSID\r
6996 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},\r
6997#endif /* HAVE_SETSID */\r
6998#ifdef HAVE_SETPGID\r
6999 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},\r
7000#endif /* HAVE_SETPGID */\r
7001#ifdef HAVE_TCGETPGRP\r
7002 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},\r
7003#endif /* HAVE_TCGETPGRP */\r
7004#ifdef HAVE_TCSETPGRP\r
7005 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},\r
7006#endif /* HAVE_TCSETPGRP */\r
7007 {"open", posix_open, METH_VARARGS, posix_open__doc__},\r
7008 {"close", posix_close, METH_VARARGS, posix_close__doc__},\r
7009 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},\r
7010 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},\r
7011 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},\r
7012 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},\r
7013 {"read", posix_read, METH_VARARGS, posix_read__doc__},\r
7014 {"write", posix_write, METH_VARARGS, posix_write__doc__},\r
7015 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},\r
7016 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},\r
7017 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},\r
7018#ifdef HAVE_PIPE\r
7019 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},\r
7020#endif\r
7021#ifdef HAVE_MKFIFO\r
7022 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},\r
7023#endif\r
7024#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)\r
7025 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},\r
7026#endif\r
7027#ifdef HAVE_DEVICE_MACROS\r
7028 {"major", posix_major, METH_VARARGS, posix_major__doc__},\r
7029 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},\r
7030 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},\r
7031#endif\r
7032#ifdef HAVE_FTRUNCATE\r
7033 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},\r
7034#endif\r
7035#ifdef HAVE_PUTENV\r
7036 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},\r
7037#endif\r
7038#ifdef HAVE_UNSETENV\r
7039 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},\r
7040#endif\r
7041 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},\r
7042#ifdef HAVE_FCHDIR\r
7043 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},\r
7044#endif\r
7045#ifdef HAVE_FSYNC\r
7046 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},\r
7047#endif\r
7048#ifdef HAVE_FDATASYNC\r
7049 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},\r
7050#endif\r
7051#ifdef HAVE_SYS_WAIT_H\r
7052#ifdef WCOREDUMP\r
7053 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},\r
7054#endif /* WCOREDUMP */\r
7055#ifdef WIFCONTINUED\r
7056 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},\r
7057#endif /* WIFCONTINUED */\r
7058#ifdef WIFSTOPPED\r
7059 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},\r
7060#endif /* WIFSTOPPED */\r
7061#ifdef WIFSIGNALED\r
7062 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},\r
7063#endif /* WIFSIGNALED */\r
7064#ifdef WIFEXITED\r
7065 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},\r
7066#endif /* WIFEXITED */\r
7067#ifdef WEXITSTATUS\r
7068 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},\r
7069#endif /* WEXITSTATUS */\r
7070#ifdef WTERMSIG\r
7071 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},\r
7072#endif /* WTERMSIG */\r
7073#ifdef WSTOPSIG\r
7074 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},\r
7075#endif /* WSTOPSIG */\r
7076#endif /* HAVE_SYS_WAIT_H */\r
7077#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)\r
7078 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},\r
7079#endif\r
7080#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)\r
7081 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},\r
7082#endif\r
7083#ifdef HAVE_TMPFILE\r
7084 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},\r
7085#endif\r
7086#ifdef HAVE_TEMPNAM\r
7087 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},\r
7088#endif\r
7089#ifdef HAVE_TMPNAM\r
7090 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},\r
7091#endif\r
7092#ifdef HAVE_CONFSTR\r
7093 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},\r
7094#endif\r
7095#ifdef HAVE_SYSCONF\r
7096 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},\r
7097#endif\r
7098#ifdef HAVE_FPATHCONF\r
7099 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},\r
7100#endif\r
7101#ifdef HAVE_PATHCONF\r
7102 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},\r
7103#endif\r
7104 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},\r
7105#ifdef HAVE_SETRESUID\r
7106 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},\r
7107#endif\r
7108#ifdef HAVE_SETRESGID\r
7109 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},\r
7110#endif\r
7111#ifdef HAVE_GETRESUID\r
7112 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},\r
7113#endif\r
7114#ifdef HAVE_GETRESGID\r
7115 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},\r
7116#endif\r
7117\r
7118 {NULL, NULL} /* Sentinel */\r
7119};\r
7120\r
7121\r
7122static int\r
7123ins(PyObject *module, char *symbol, long value)\r
7124{\r
7125 return PyModule_AddIntConstant(module, symbol, value);\r
7126}\r
7127\r
7128static int\r
7129all_ins(PyObject *d)\r
7130{\r
7131#ifdef F_OK\r
7132 if (ins(d, "F_OK", (long)F_OK)) return -1;\r
7133#endif\r
7134#ifdef R_OK\r
7135 if (ins(d, "R_OK", (long)R_OK)) return -1;\r
7136#endif\r
7137#ifdef W_OK\r
7138 if (ins(d, "W_OK", (long)W_OK)) return -1;\r
7139#endif\r
7140#ifdef X_OK\r
7141 if (ins(d, "X_OK", (long)X_OK)) return -1;\r
7142#endif\r
7143#ifdef NGROUPS_MAX\r
7144 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;\r
7145#endif\r
7146#ifdef TMP_MAX\r
7147 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;\r
7148#endif\r
7149#ifdef WCONTINUED\r
7150 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;\r
7151#endif\r
7152#ifdef WNOHANG\r
7153 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;\r
7154#endif\r
7155#ifdef WUNTRACED\r
7156 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;\r
7157#endif\r
7158#ifdef O_RDONLY\r
7159 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;\r
7160#endif\r
7161#ifdef O_WRONLY\r
7162 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;\r
7163#endif\r
7164#ifdef O_RDWR\r
7165 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;\r
7166#endif\r
7167#ifdef O_NDELAY\r
7168 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;\r
7169#endif\r
7170#ifdef O_NONBLOCK\r
7171 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;\r
7172#endif\r
7173#ifdef O_APPEND\r
7174 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;\r
7175#endif\r
7176#ifdef O_DSYNC\r
7177 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;\r
7178#endif\r
7179#ifdef O_RSYNC\r
7180 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;\r
7181#endif\r
7182#ifdef O_SYNC\r
7183 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;\r
7184#endif\r
7185#ifdef O_NOCTTY\r
7186 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;\r
7187#endif\r
7188#ifdef O_CREAT\r
7189 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;\r
7190#endif\r
7191#ifdef O_EXCL\r
7192 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;\r
7193#endif\r
7194#ifdef O_TRUNC\r
7195 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;\r
7196#endif\r
7197#ifdef O_BINARY\r
7198 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;\r
7199#endif\r
7200#ifdef O_TEXT\r
7201 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;\r
7202#endif\r
7203#ifdef O_LARGEFILE\r
7204 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;\r
7205#endif\r
7206#ifdef O_SHLOCK\r
7207 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;\r
7208#endif\r
7209#ifdef O_EXLOCK\r
7210 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;\r
7211#endif\r
7212\r
7213/* MS Windows */\r
7214#ifdef O_NOINHERIT\r
7215 /* Don't inherit in child processes. */\r
7216 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;\r
7217#endif\r
7218#ifdef _O_SHORT_LIVED\r
7219 /* Optimize for short life (keep in memory). */\r
7220 /* MS forgot to define this one with a non-underscore form too. */\r
7221 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;\r
7222#endif\r
7223#ifdef O_TEMPORARY\r
7224 /* Automatically delete when last handle is closed. */\r
7225 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;\r
7226#endif\r
7227#ifdef O_RANDOM\r
7228 /* Optimize for random access. */\r
7229 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;\r
7230#endif\r
7231#ifdef O_SEQUENTIAL\r
7232 /* Optimize for sequential access. */\r
7233 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;\r
7234#endif\r
7235\r
7236/* GNU extensions. */\r
7237#ifdef O_ASYNC\r
7238 /* Send a SIGIO signal whenever input or output\r
7239 becomes available on file descriptor */\r
7240 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;\r
7241#endif\r
7242#ifdef O_DIRECT\r
7243 /* Direct disk access. */\r
7244 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;\r
7245#endif\r
7246#ifdef O_DIRECTORY\r
7247 /* Must be a directory. */\r
7248 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;\r
7249#endif\r
7250#ifdef O_NOFOLLOW\r
7251 /* Do not follow links. */\r
7252 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;\r
7253#endif\r
7254#ifdef O_NOATIME\r
7255 /* Do not update the access time. */\r
7256 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;\r
7257#endif\r
7258\r
7259 /* These come from sysexits.h */\r
7260#ifdef EX_OK\r
7261 if (ins(d, "EX_OK", (long)EX_OK)) return -1;\r
7262#endif /* EX_OK */\r
7263#ifdef EX_USAGE\r
7264 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;\r
7265#endif /* EX_USAGE */\r
7266#ifdef EX_DATAERR\r
7267 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;\r
7268#endif /* EX_DATAERR */\r
7269#ifdef EX_NOINPUT\r
7270 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;\r
7271#endif /* EX_NOINPUT */\r
7272#ifdef EX_NOUSER\r
7273 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;\r
7274#endif /* EX_NOUSER */\r
7275#ifdef EX_NOHOST\r
7276 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;\r
7277#endif /* EX_NOHOST */\r
7278#ifdef EX_UNAVAILABLE\r
7279 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;\r
7280#endif /* EX_UNAVAILABLE */\r
7281#ifdef EX_SOFTWARE\r
7282 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;\r
7283#endif /* EX_SOFTWARE */\r
7284#ifdef EX_OSERR\r
7285 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;\r
7286#endif /* EX_OSERR */\r
7287#ifdef EX_OSFILE\r
7288 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;\r
7289#endif /* EX_OSFILE */\r
7290#ifdef EX_CANTCREAT\r
7291 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;\r
7292#endif /* EX_CANTCREAT */\r
7293#ifdef EX_IOERR\r
7294 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;\r
7295#endif /* EX_IOERR */\r
7296#ifdef EX_TEMPFAIL\r
7297 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;\r
7298#endif /* EX_TEMPFAIL */\r
7299#ifdef EX_PROTOCOL\r
7300 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;\r
7301#endif /* EX_PROTOCOL */\r
7302#ifdef EX_NOPERM\r
7303 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;\r
7304#endif /* EX_NOPERM */\r
7305#ifdef EX_CONFIG\r
7306 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;\r
7307#endif /* EX_CONFIG */\r
7308#ifdef EX_NOTFOUND\r
7309 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;\r
7310#endif /* EX_NOTFOUND */\r
7311\r
7312#ifdef HAVE_SPAWNV\r
7313#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
7314 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;\r
7315 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;\r
7316 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;\r
7317 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;\r
7318 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;\r
7319 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;\r
7320 if (ins(d, "P_PM", (long)P_PM)) return -1;\r
7321 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;\r
7322 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;\r
7323 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;\r
7324 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;\r
7325 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;\r
7326 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;\r
7327 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;\r
7328 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;\r
7329 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;\r
7330 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;\r
7331 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;\r
7332 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;\r
7333 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;\r
7334#else\r
7335 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;\r
7336 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;\r
7337 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;\r
7338 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;\r
7339 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;\r
7340#endif\r
7341#endif\r
7342 return 0;\r
7343}\r
7344\r
7345#define INITFUNC initedk2\r
7346#define MODNAME "edk2"\r
7347\r
7348PyMODINIT_FUNC\r
7349INITFUNC(void)\r
7350{\r
7351 PyObject *m;\r
7352\r
7353#ifndef UEFI_C_SOURCE\r
7354 PyObject *v;\r
7355#endif\r
7356\r
7357 m = Py_InitModule3(MODNAME,\r
7358 posix_methods,\r
7359 edk2__doc__);\r
7360 if (m == NULL)\r
7361 return;\r
7362\r
7363#ifndef UEFI_C_SOURCE\r
7364 /* Initialize environ dictionary */\r
7365 v = convertenviron();\r
7366 Py_XINCREF(v);\r
7367 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)\r
7368 return;\r
7369 Py_DECREF(v);\r
7370#endif /* UEFI_C_SOURCE */\r
7371\r
7372 if (all_ins(m))\r
7373 return;\r
7374\r
7375 if (setup_confname_tables(m))\r
7376 return;\r
7377\r
7378 Py_INCREF(PyExc_OSError);\r
7379 PyModule_AddObject(m, "error", PyExc_OSError);\r
7380\r
7381#ifdef HAVE_PUTENV\r
7382 if (posix_putenv_garbage == NULL)\r
7383 posix_putenv_garbage = PyDict_New();\r
7384#endif\r
7385\r
7386 if (!initialized) {\r
7387 stat_result_desc.name = MODNAME ".stat_result";\r
7388 stat_result_desc.fields[2].name = PyStructSequence_UnnamedField;\r
7389 stat_result_desc.fields[3].name = PyStructSequence_UnnamedField;\r
7390 stat_result_desc.fields[4].name = PyStructSequence_UnnamedField;\r
7391 PyStructSequence_InitType(&StatResultType, &stat_result_desc);\r
7392 structseq_new = StatResultType.tp_new;\r
7393 StatResultType.tp_new = statresult_new;\r
7394\r
7395 //statvfs_result_desc.name = MODNAME ".statvfs_result";\r
7396 //PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);\r
7397#ifdef NEED_TICKS_PER_SECOND\r
7398# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)\r
7399 ticks_per_second = sysconf(_SC_CLK_TCK);\r
7400# elif defined(HZ)\r
7401 ticks_per_second = HZ;\r
7402# else\r
7403 ticks_per_second = 60; /* magic fallback value; may be bogus */\r
7404# endif\r
7405#endif\r
7406 }\r
7407 Py_INCREF((PyObject*) &StatResultType);\r
7408 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);\r
7409 //Py_INCREF((PyObject*) &StatVFSResultType);\r
7410 //PyModule_AddObject(m, "statvfs_result",\r
7411 // (PyObject*) &StatVFSResultType);\r
7412 initialized = 1;\r
7413\r
7414}\r
7415\r
7416#ifdef __cplusplus\r
7417}\r
7418#endif\r
7419\r
7420\r