Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | r"""OS routines for Mac, DOS, NT, or Posix depending on what system we're on. |
2 | ||
3 | This exports: | |
4 | - all functions from posix, nt, os2, mac, or ce, e.g. unlink, stat, etc. | |
5 | - os.path is one of the modules posixpath, ntpath, or macpath | |
6 | - os.name is 'posix', 'nt', 'os2', 'mac', 'ce' or 'riscos' | |
7 | - os.curdir is a string representing the current directory ('.' or ':') | |
8 | - os.pardir is a string representing the parent directory ('..' or '::') | |
9 | - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\') | |
10 | - os.extsep is the extension separator ('.' or '/') | |
11 | - os.altsep is the alternate pathname separator (None or '/') | |
12 | - os.pathsep is the component separator used in $PATH etc | |
13 | - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n') | |
14 | - os.defpath is the default search path for executables | |
15 | - os.devnull is the file path of the null device ('/dev/null', etc.) | |
16 | ||
17 | Programs that import and use 'os' stand a better chance of being | |
18 | portable between different platforms. Of course, they must then | |
19 | only use functions that are defined by all platforms (e.g., unlink | |
20 | and opendir), and leave all pathname manipulation to os.path | |
21 | (e.g., split and join). | |
22 | """ | |
23 | ||
24 | #' | |
25 | ||
26 | import sys | |
27 | ||
28 | _names = sys.builtin_module_names | |
29 | ||
30 | # Note: more names are added to __all__ later. | |
31 | __all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", | |
32 | "defpath", "name", "path", "devnull"] | |
33 | ||
34 | def _get_exports_list(module): | |
35 | try: | |
36 | return list(module.__all__) | |
37 | except AttributeError: | |
38 | return [n for n in dir(module) if n[0] != '_'] | |
39 | ||
40 | if 'posix' in _names: | |
41 | name = 'posix' | |
42 | linesep = '\n' | |
43 | from posix import * | |
44 | try: | |
45 | from posix import _exit | |
46 | except ImportError: | |
47 | pass | |
48 | import posixpath as path | |
49 | ||
50 | import posix | |
51 | __all__.extend(_get_exports_list(posix)) | |
52 | del posix | |
53 | ||
54 | elif 'nt' in _names: | |
55 | name = 'nt' | |
56 | linesep = '\r\n' | |
57 | from nt import * | |
58 | try: | |
59 | from nt import _exit | |
60 | except ImportError: | |
61 | pass | |
62 | import ntpath as path | |
63 | ||
64 | import nt | |
65 | __all__.extend(_get_exports_list(nt)) | |
66 | del nt | |
67 | ||
68 | elif 'os2' in _names: | |
69 | name = 'os2' | |
70 | linesep = '\r\n' | |
71 | from os2 import * | |
72 | try: | |
73 | from os2 import _exit | |
74 | except ImportError: | |
75 | pass | |
76 | if sys.version.find('EMX GCC') == -1: | |
77 | import ntpath as path | |
78 | else: | |
79 | import os2emxpath as path | |
80 | from _emx_link import link | |
81 | ||
82 | import os2 | |
83 | __all__.extend(_get_exports_list(os2)) | |
84 | del os2 | |
85 | ||
86 | elif 'mac' in _names: | |
87 | name = 'mac' | |
88 | linesep = '\r' | |
89 | from mac import * | |
90 | try: | |
91 | from mac import _exit | |
92 | except ImportError: | |
93 | pass | |
94 | import macpath as path | |
95 | ||
96 | import mac | |
97 | __all__.extend(_get_exports_list(mac)) | |
98 | del mac | |
99 | ||
100 | elif 'ce' in _names: | |
101 | name = 'ce' | |
102 | linesep = '\r\n' | |
103 | from ce import * | |
104 | try: | |
105 | from ce import _exit | |
106 | except ImportError: | |
107 | pass | |
108 | # We can use the standard Windows path. | |
109 | import ntpath as path | |
110 | ||
111 | import ce | |
112 | __all__.extend(_get_exports_list(ce)) | |
113 | del ce | |
114 | ||
115 | elif 'riscos' in _names: | |
116 | name = 'riscos' | |
117 | linesep = '\n' | |
118 | from riscos import * | |
119 | try: | |
120 | from riscos import _exit | |
121 | except ImportError: | |
122 | pass | |
123 | import riscospath as path | |
124 | ||
125 | import riscos | |
126 | __all__.extend(_get_exports_list(riscos)) | |
127 | del riscos | |
128 | ||
129 | else: | |
130 | raise ImportError, 'no os specific module found' | |
131 | ||
132 | sys.modules['os.path'] = path | |
133 | from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep, | |
134 | devnull) | |
135 | ||
136 | del _names | |
137 | ||
138 | #' | |
139 | ||
140 | # Super directory utilities. | |
141 | # (Inspired by Eric Raymond; the doc strings are mostly his) | |
142 | ||
143 | def makedirs(name, mode=0777): | |
144 | """makedirs(path [, mode=0777]) | |
145 | ||
146 | Super-mkdir; create a leaf directory and all intermediate ones. | |
147 | Works like mkdir, except that any intermediate path segment (not | |
148 | just the rightmost) will be created if it does not exist. This is | |
149 | recursive. | |
150 | ||
151 | """ | |
152 | head, tail = path.split(name) | |
153 | if not tail: | |
154 | head, tail = path.split(head) | |
155 | if head and tail and not path.exists(head): | |
156 | makedirs(head, mode) | |
157 | if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists | |
158 | return | |
159 | mkdir(name, mode) | |
160 | ||
161 | def removedirs(name): | |
162 | """removedirs(path) | |
163 | ||
164 | Super-rmdir; remove a leaf directory and empty all intermediate | |
165 | ones. Works like rmdir except that, if the leaf directory is | |
166 | successfully removed, directories corresponding to rightmost path | |
167 | segments will be pruned away until either the whole path is | |
168 | consumed or an error occurs. Errors during this latter phase are | |
169 | ignored -- they generally mean that a directory was not empty. | |
170 | ||
171 | """ | |
172 | rmdir(name) | |
173 | head, tail = path.split(name) | |
174 | if not tail: | |
175 | head, tail = path.split(head) | |
176 | while head and tail: | |
177 | try: | |
178 | rmdir(head) | |
179 | except error: | |
180 | break | |
181 | head, tail = path.split(head) | |
182 | ||
183 | def renames(old, new): | |
184 | """renames(old, new) | |
185 | ||
186 | Super-rename; create directories as necessary and delete any left | |
187 | empty. Works like rename, except creation of any intermediate | |
188 | directories needed to make the new pathname good is attempted | |
189 | first. After the rename, directories corresponding to rightmost | |
190 | path segments of the old name will be pruned way until either the | |
191 | whole path is consumed or a nonempty directory is found. | |
192 | ||
193 | Note: this function can fail with the new directory structure made | |
194 | if you lack permissions needed to unlink the leaf directory or | |
195 | file. | |
196 | ||
197 | """ | |
198 | head, tail = path.split(new) | |
199 | if head and tail and not path.exists(head): | |
200 | makedirs(head) | |
201 | rename(old, new) | |
202 | head, tail = path.split(old) | |
203 | if head and tail: | |
204 | try: | |
205 | removedirs(head) | |
206 | except error: | |
207 | pass | |
208 | ||
209 | __all__.extend(["makedirs", "removedirs", "renames"]) | |
210 | ||
211 | def walk(top, topdown=True, onerror=None): | |
212 | """Directory tree generator. | |
213 | ||
214 | For each directory in the directory tree rooted at top (including top | |
215 | itself, but excluding '.' and '..'), yields a 3-tuple | |
216 | ||
217 | dirpath, dirnames, filenames | |
218 | ||
219 | dirpath is a string, the path to the directory. dirnames is a list of | |
220 | the names of the subdirectories in dirpath (excluding '.' and '..'). | |
221 | filenames is a list of the names of the non-directory files in dirpath. | |
222 | Note that the names in the lists are just names, with no path components. | |
223 | To get a full path (which begins with top) to a file or directory in | |
224 | dirpath, do os.path.join(dirpath, name). | |
225 | ||
226 | If optional arg 'topdown' is true or not specified, the triple for a | |
227 | directory is generated before the triples for any of its subdirectories | |
228 | (directories are generated top down). If topdown is false, the triple | |
229 | for a directory is generated after the triples for all of its | |
230 | subdirectories (directories are generated bottom up). | |
231 | ||
232 | When topdown is true, the caller can modify the dirnames list in-place | |
233 | (e.g., via del or slice assignment), and walk will only recurse into the | |
234 | subdirectories whose names remain in dirnames; this can be used to prune | |
235 | the search, or to impose a specific order of visiting. Modifying | |
236 | dirnames when topdown is false is ineffective, since the directories in | |
237 | dirnames have already been generated by the time dirnames itself is | |
238 | generated. | |
239 | ||
240 | By default errors from the os.listdir() call are ignored. If | |
241 | optional arg 'onerror' is specified, it should be a function; it | |
242 | will be called with one argument, an os.error instance. It can | |
243 | report the error to continue with the walk, or raise the exception | |
244 | to abort the walk. Note that the filename is available as the | |
245 | filename attribute of the exception object. | |
246 | ||
247 | Caution: if you pass a relative pathname for top, don't change the | |
248 | current working directory between resumptions of walk. walk never | |
249 | changes the current directory, and assumes that the client doesn't | |
250 | either. | |
251 | ||
252 | Example: | |
253 | ||
254 | from os.path import join, getsize | |
255 | for root, dirs, files in walk('python/Lib/email'): | |
256 | print root, "consumes", | |
257 | print sum([getsize(join(root, name)) for name in files]), | |
258 | print "bytes in", len(files), "non-directory files" | |
259 | if 'CVS' in dirs: | |
260 | dirs.remove('CVS') # don't visit CVS directories | |
261 | """ | |
262 | ||
263 | from os.path import join, isdir, islink | |
264 | ||
265 | # We may not have read permission for top, in which case we can't | |
266 | # get a list of the files the directory contains. os.path.walk | |
267 | # always suppressed the exception then, rather than blow up for a | |
268 | # minor reason when (say) a thousand readable directories are still | |
269 | # left to visit. That logic is copied here. | |
270 | try: | |
271 | # Note that listdir and error are globals in this module due | |
272 | # to earlier import-*. | |
273 | names = listdir(top) | |
274 | except error, err: | |
275 | if onerror is not None: | |
276 | onerror(err) | |
277 | return | |
278 | ||
279 | dirs, nondirs = [], [] | |
280 | for name in names: | |
281 | if isdir(join(top, name)): | |
282 | dirs.append(name) | |
283 | else: | |
284 | nondirs.append(name) | |
285 | ||
286 | if topdown: | |
287 | yield top, dirs, nondirs | |
288 | for name in dirs: | |
289 | path = join(top, name) | |
290 | if not islink(path): | |
291 | for x in walk(path, topdown, onerror): | |
292 | yield x | |
293 | if not topdown: | |
294 | yield top, dirs, nondirs | |
295 | ||
296 | __all__.append("walk") | |
297 | ||
298 | # Make sure os.environ exists, at least | |
299 | try: | |
300 | environ | |
301 | except NameError: | |
302 | environ = {} | |
303 | ||
304 | def execl(file, *args): | |
305 | """execl(file, *args) | |
306 | ||
307 | Execute the executable file with argument list args, replacing the | |
308 | current process. """ | |
309 | execv(file, args) | |
310 | ||
311 | def execle(file, *args): | |
312 | """execle(file, *args, env) | |
313 | ||
314 | Execute the executable file with argument list args and | |
315 | environment env, replacing the current process. """ | |
316 | env = args[-1] | |
317 | execve(file, args[:-1], env) | |
318 | ||
319 | def execlp(file, *args): | |
320 | """execlp(file, *args) | |
321 | ||
322 | Execute the executable file (which is searched for along $PATH) | |
323 | with argument list args, replacing the current process. """ | |
324 | execvp(file, args) | |
325 | ||
326 | def execlpe(file, *args): | |
327 | """execlpe(file, *args, env) | |
328 | ||
329 | Execute the executable file (which is searched for along $PATH) | |
330 | with argument list args and environment env, replacing the current | |
331 | process. """ | |
332 | env = args[-1] | |
333 | execvpe(file, args[:-1], env) | |
334 | ||
335 | def execvp(file, args): | |
336 | """execp(file, args) | |
337 | ||
338 | Execute the executable file (which is searched for along $PATH) | |
339 | with argument list args, replacing the current process. | |
340 | args may be a list or tuple of strings. """ | |
341 | _execvpe(file, args) | |
342 | ||
343 | def execvpe(file, args, env): | |
344 | """execvpe(file, args, env) | |
345 | ||
346 | Execute the executable file (which is searched for along $PATH) | |
347 | with argument list args and environment env , replacing the | |
348 | current process. | |
349 | args may be a list or tuple of strings. """ | |
350 | _execvpe(file, args, env) | |
351 | ||
352 | __all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"]) | |
353 | ||
354 | def _execvpe(file, args, env=None): | |
355 | from errno import ENOENT, ENOTDIR | |
356 | ||
357 | if env is not None: | |
358 | func = execve | |
359 | argrest = (args, env) | |
360 | else: | |
361 | func = execv | |
362 | argrest = (args,) | |
363 | env = environ | |
364 | ||
365 | head, tail = path.split(file) | |
366 | if head: | |
367 | func(file, *argrest) | |
368 | return | |
369 | if 'PATH' in env: | |
370 | envpath = env['PATH'] | |
371 | else: | |
372 | envpath = defpath | |
373 | PATH = envpath.split(pathsep) | |
374 | saved_exc = None | |
375 | saved_tb = None | |
376 | for dir in PATH: | |
377 | fullname = path.join(dir, file) | |
378 | try: | |
379 | func(fullname, *argrest) | |
380 | except error, e: | |
381 | tb = sys.exc_info()[2] | |
382 | if (e.errno != ENOENT and e.errno != ENOTDIR | |
383 | and saved_exc is None): | |
384 | saved_exc = e | |
385 | saved_tb = tb | |
386 | if saved_exc: | |
387 | raise error, saved_exc, saved_tb | |
388 | raise error, e, tb | |
389 | ||
390 | # Change environ to automatically call putenv() if it exists | |
391 | try: | |
392 | # This will fail if there's no putenv | |
393 | putenv | |
394 | except NameError: | |
395 | pass | |
396 | else: | |
397 | import UserDict | |
398 | ||
399 | # Fake unsetenv() for Windows | |
400 | # not sure about os2 here but | |
401 | # I'm guessing they are the same. | |
402 | ||
403 | if name in ('os2', 'nt'): | |
404 | def unsetenv(key): | |
405 | putenv(key, "") | |
406 | ||
407 | if name == "riscos": | |
408 | # On RISC OS, all env access goes through getenv and putenv | |
409 | from riscosenviron import _Environ | |
410 | elif name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE | |
411 | # But we store them as upper case | |
412 | class _Environ(UserDict.IterableUserDict): | |
413 | def __init__(self, environ): | |
414 | UserDict.UserDict.__init__(self) | |
415 | data = self.data | |
416 | for k, v in environ.items(): | |
417 | data[k.upper()] = v | |
418 | def __setitem__(self, key, item): | |
419 | putenv(key, item) | |
420 | self.data[key.upper()] = item | |
421 | def __getitem__(self, key): | |
422 | return self.data[key.upper()] | |
423 | try: | |
424 | unsetenv | |
425 | except NameError: | |
426 | def __delitem__(self, key): | |
427 | del self.data[key.upper()] | |
428 | else: | |
429 | def __delitem__(self, key): | |
430 | unsetenv(key) | |
431 | del self.data[key.upper()] | |
432 | def has_key(self, key): | |
433 | return key.upper() in self.data | |
434 | def __contains__(self, key): | |
435 | return key.upper() in self.data | |
436 | def get(self, key, failobj=None): | |
437 | return self.data.get(key.upper(), failobj) | |
438 | def update(self, dict=None, **kwargs): | |
439 | if dict: | |
440 | try: | |
441 | keys = dict.keys() | |
442 | except AttributeError: | |
443 | # List of (key, value) | |
444 | for k, v in dict: | |
445 | self[k] = v | |
446 | else: | |
447 | # got keys | |
448 | # cannot use items(), since mappings | |
449 | # may not have them. | |
450 | for k in keys: | |
451 | self[k] = dict[k] | |
452 | if kwargs: | |
453 | self.update(kwargs) | |
454 | def copy(self): | |
455 | return dict(self) | |
456 | ||
457 | else: # Where Env Var Names Can Be Mixed Case | |
458 | class _Environ(UserDict.IterableUserDict): | |
459 | def __init__(self, environ): | |
460 | UserDict.UserDict.__init__(self) | |
461 | self.data = environ | |
462 | def __setitem__(self, key, item): | |
463 | putenv(key, item) | |
464 | self.data[key] = item | |
465 | def update(self, dict=None, **kwargs): | |
466 | if dict: | |
467 | try: | |
468 | keys = dict.keys() | |
469 | except AttributeError: | |
470 | # List of (key, value) | |
471 | for k, v in dict: | |
472 | self[k] = v | |
473 | else: | |
474 | # got keys | |
475 | # cannot use items(), since mappings | |
476 | # may not have them. | |
477 | for k in keys: | |
478 | self[k] = dict[k] | |
479 | if kwargs: | |
480 | self.update(kwargs) | |
481 | try: | |
482 | unsetenv | |
483 | except NameError: | |
484 | pass | |
485 | else: | |
486 | def __delitem__(self, key): | |
487 | unsetenv(key) | |
488 | del self.data[key] | |
489 | def copy(self): | |
490 | return dict(self) | |
491 | ||
492 | ||
493 | environ = _Environ(environ) | |
494 | ||
495 | def getenv(key, default=None): | |
496 | """Get an environment variable, return None if it doesn't exist. | |
497 | The optional second argument can specify an alternate default.""" | |
498 | return environ.get(key, default) | |
499 | __all__.append("getenv") | |
500 | ||
501 | def _exists(name): | |
502 | try: | |
503 | eval(name) | |
504 | return True | |
505 | except NameError: | |
506 | return False | |
507 | ||
508 | # Supply spawn*() (probably only for Unix) | |
509 | if _exists("fork") and not _exists("spawnv") and _exists("execv"): | |
510 | ||
511 | P_WAIT = 0 | |
512 | P_NOWAIT = P_NOWAITO = 1 | |
513 | ||
514 | # XXX Should we support P_DETACH? I suppose it could fork()**2 | |
515 | # and close the std I/O streams. Also, P_OVERLAY is the same | |
516 | # as execv*()? | |
517 | ||
518 | def _spawnvef(mode, file, args, env, func): | |
519 | # Internal helper; func is the exec*() function to use | |
520 | pid = fork() | |
521 | if not pid: | |
522 | # Child | |
523 | try: | |
524 | if env is None: | |
525 | func(file, args) | |
526 | else: | |
527 | func(file, args, env) | |
528 | except: | |
529 | _exit(127) | |
530 | else: | |
531 | # Parent | |
532 | if mode == P_NOWAIT: | |
533 | return pid # Caller is responsible for waiting! | |
534 | while 1: | |
535 | wpid, sts = waitpid(pid, 0) | |
536 | if WIFSTOPPED(sts): | |
537 | continue | |
538 | elif WIFSIGNALED(sts): | |
539 | return -WTERMSIG(sts) | |
540 | elif WIFEXITED(sts): | |
541 | return WEXITSTATUS(sts) | |
542 | else: | |
543 | raise error, "Not stopped, signaled or exited???" | |
544 | ||
545 | def spawnv(mode, file, args): | |
546 | """spawnv(mode, file, args) -> integer | |
547 | ||
548 | Execute file with arguments from args in a subprocess. | |
549 | If mode == P_NOWAIT return the pid of the process. | |
550 | If mode == P_WAIT return the process's exit code if it exits normally; | |
551 | otherwise return -SIG, where SIG is the signal that killed it. """ | |
552 | return _spawnvef(mode, file, args, None, execv) | |
553 | ||
554 | def spawnve(mode, file, args, env): | |
555 | """spawnve(mode, file, args, env) -> integer | |
556 | ||
557 | Execute file with arguments from args in a subprocess with the | |
558 | specified environment. | |
559 | If mode == P_NOWAIT return the pid of the process. | |
560 | If mode == P_WAIT return the process's exit code if it exits normally; | |
561 | otherwise return -SIG, where SIG is the signal that killed it. """ | |
562 | return _spawnvef(mode, file, args, env, execve) | |
563 | ||
564 | # Note: spawnvp[e] is't currently supported on Windows | |
565 | ||
566 | def spawnvp(mode, file, args): | |
567 | """spawnvp(mode, file, args) -> integer | |
568 | ||
569 | Execute file (which is looked for along $PATH) with arguments from | |
570 | args in a subprocess. | |
571 | If mode == P_NOWAIT return the pid of the process. | |
572 | If mode == P_WAIT return the process's exit code if it exits normally; | |
573 | otherwise return -SIG, where SIG is the signal that killed it. """ | |
574 | return _spawnvef(mode, file, args, None, execvp) | |
575 | ||
576 | def spawnvpe(mode, file, args, env): | |
577 | """spawnvpe(mode, file, args, env) -> integer | |
578 | ||
579 | Execute file (which is looked for along $PATH) with arguments from | |
580 | args in a subprocess with the supplied environment. | |
581 | If mode == P_NOWAIT return the pid of the process. | |
582 | If mode == P_WAIT return the process's exit code if it exits normally; | |
583 | otherwise return -SIG, where SIG is the signal that killed it. """ | |
584 | return _spawnvef(mode, file, args, env, execvpe) | |
585 | ||
586 | if _exists("spawnv"): | |
587 | # These aren't supplied by the basic Windows code | |
588 | # but can be easily implemented in Python | |
589 | ||
590 | def spawnl(mode, file, *args): | |
591 | """spawnl(mode, file, *args) -> integer | |
592 | ||
593 | Execute file with arguments from args in a subprocess. | |
594 | If mode == P_NOWAIT return the pid of the process. | |
595 | If mode == P_WAIT return the process's exit code if it exits normally; | |
596 | otherwise return -SIG, where SIG is the signal that killed it. """ | |
597 | return spawnv(mode, file, args) | |
598 | ||
599 | def spawnle(mode, file, *args): | |
600 | """spawnle(mode, file, *args, env) -> integer | |
601 | ||
602 | Execute file with arguments from args in a subprocess with the | |
603 | supplied environment. | |
604 | If mode == P_NOWAIT return the pid of the process. | |
605 | If mode == P_WAIT return the process's exit code if it exits normally; | |
606 | otherwise return -SIG, where SIG is the signal that killed it. """ | |
607 | env = args[-1] | |
608 | return spawnve(mode, file, args[:-1], env) | |
609 | ||
610 | ||
611 | __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",]) | |
612 | ||
613 | ||
614 | if _exists("spawnvp"): | |
615 | # At the moment, Windows doesn't implement spawnvp[e], | |
616 | # so it won't have spawnlp[e] either. | |
617 | def spawnlp(mode, file, *args): | |
618 | """spawnlp(mode, file, *args) -> integer | |
619 | ||
620 | Execute file (which is looked for along $PATH) with arguments from | |
621 | args in a subprocess with the supplied environment. | |
622 | If mode == P_NOWAIT return the pid of the process. | |
623 | If mode == P_WAIT return the process's exit code if it exits normally; | |
624 | otherwise return -SIG, where SIG is the signal that killed it. """ | |
625 | return spawnvp(mode, file, args) | |
626 | ||
627 | def spawnlpe(mode, file, *args): | |
628 | """spawnlpe(mode, file, *args, env) -> integer | |
629 | ||
630 | Execute file (which is looked for along $PATH) with arguments from | |
631 | args in a subprocess with the supplied environment. | |
632 | If mode == P_NOWAIT return the pid of the process. | |
633 | If mode == P_WAIT return the process's exit code if it exits normally; | |
634 | otherwise return -SIG, where SIG is the signal that killed it. """ | |
635 | env = args[-1] | |
636 | return spawnvpe(mode, file, args[:-1], env) | |
637 | ||
638 | ||
639 | __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",]) | |
640 | ||
641 | ||
642 | # Supply popen2 etc. (for Unix) | |
643 | if _exists("fork"): | |
644 | if not _exists("popen2"): | |
645 | def popen2(cmd, mode="t", bufsize=-1): | |
646 | """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' | |
647 | may be a sequence, in which case arguments will be passed directly to | |
648 | the program without shell intervention (as with os.spawnv()). If 'cmd' | |
649 | is a string it will be passed to the shell (as with os.system()). If | |
650 | 'bufsize' is specified, it sets the buffer size for the I/O pipes. The | |
651 | file objects (child_stdin, child_stdout) are returned.""" | |
652 | import popen2 | |
653 | stdout, stdin = popen2.popen2(cmd, bufsize) | |
654 | return stdin, stdout | |
655 | __all__.append("popen2") | |
656 | ||
657 | if not _exists("popen3"): | |
658 | def popen3(cmd, mode="t", bufsize=-1): | |
659 | """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' | |
660 | may be a sequence, in which case arguments will be passed directly to | |
661 | the program without shell intervention (as with os.spawnv()). If 'cmd' | |
662 | is a string it will be passed to the shell (as with os.system()). If | |
663 | 'bufsize' is specified, it sets the buffer size for the I/O pipes. The | |
664 | file objects (child_stdin, child_stdout, child_stderr) are returned.""" | |
665 | import popen2 | |
666 | stdout, stdin, stderr = popen2.popen3(cmd, bufsize) | |
667 | return stdin, stdout, stderr | |
668 | __all__.append("popen3") | |
669 | ||
670 | if not _exists("popen4"): | |
671 | def popen4(cmd, mode="t", bufsize=-1): | |
672 | """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' | |
673 | may be a sequence, in which case arguments will be passed directly to | |
674 | the program without shell intervention (as with os.spawnv()). If 'cmd' | |
675 | is a string it will be passed to the shell (as with os.system()). If | |
676 | 'bufsize' is specified, it sets the buffer size for the I/O pipes. The | |
677 | file objects (child_stdin, child_stdout_stderr) are returned.""" | |
678 | import popen2 | |
679 | stdout, stdin = popen2.popen4(cmd, bufsize) | |
680 | return stdin, stdout | |
681 | __all__.append("popen4") | |
682 | ||
683 | import copy_reg as _copy_reg | |
684 | ||
685 | def _make_stat_result(tup, dict): | |
686 | return stat_result(tup, dict) | |
687 | ||
688 | def _pickle_stat_result(sr): | |
689 | (type, args) = sr.__reduce__() | |
690 | return (_make_stat_result, args) | |
691 | ||
692 | try: | |
693 | _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result) | |
694 | except NameError: # stat_result may not exist | |
695 | pass | |
696 | ||
697 | def _make_statvfs_result(tup, dict): | |
698 | return statvfs_result(tup, dict) | |
699 | ||
700 | def _pickle_statvfs_result(sr): | |
701 | (type, args) = sr.__reduce__() | |
702 | return (_make_statvfs_result, args) | |
703 | ||
704 | try: | |
705 | _copy_reg.pickle(statvfs_result, _pickle_statvfs_result, | |
706 | _make_statvfs_result) | |
707 | except NameError: # statvfs_result may not exist | |
708 | pass | |
709 | ||
710 | if not _exists("urandom"): | |
711 | def urandom(n): | |
712 | """urandom(n) -> str | |
713 | ||
714 | Return a string of n random bytes suitable for cryptographic use. | |
715 | ||
716 | """ | |
717 | try: | |
718 | _urandomfd = open("/dev/urandom", O_RDONLY) | |
719 | except: | |
720 | raise NotImplementedError("/dev/urandom (or equivalent) not found") | |
721 | bytes = "" | |
722 | while len(bytes) < n: | |
723 | bytes += read(_urandomfd, n - len(bytes)) | |
724 | close(_urandomfd) | |
725 | return bytes |