Move setting of ioready 'wait' earlier in call chain, to
[python/dscho.git] / Lib / os.py
blob358c8c6269fa6ac8e80654843290f4bee3ee1451
1 r"""OS routines for Mac, DOS, NT, or Posix depending on what system we're on.
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
16 Programs that import and use 'os' stand a better chance of being
17 portable between different platforms. Of course, they must then
18 only use functions that are defined by all platforms (e.g., unlink
19 and opendir), and leave all pathname manipulation to os.path
20 (e.g., split and join).
21 """
25 import sys
27 _names = sys.builtin_module_names
29 __all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
30 "defpath", "name", "path"]
32 def _get_exports_list(module):
33 try:
34 return list(module.__all__)
35 except AttributeError:
36 return [n for n in dir(module) if n[0] != '_']
38 if 'posix' in _names:
39 name = 'posix'
40 linesep = '\n'
41 from posix import *
42 try:
43 from posix import _exit
44 except ImportError:
45 pass
46 import posixpath as path
48 import posix
49 __all__.extend(_get_exports_list(posix))
50 del posix
52 elif 'nt' in _names:
53 name = 'nt'
54 linesep = '\r\n'
55 from nt import *
56 try:
57 from nt import _exit
58 except ImportError:
59 pass
60 import ntpath as path
62 import nt
63 __all__.extend(_get_exports_list(nt))
64 del nt
66 elif 'os2' in _names:
67 name = 'os2'
68 linesep = '\r\n'
69 from os2 import *
70 try:
71 from os2 import _exit
72 except ImportError:
73 pass
74 if sys.version.find('EMX GCC') == -1:
75 import ntpath as path
76 else:
77 import os2emxpath as path
79 import os2
80 __all__.extend(_get_exports_list(os2))
81 del os2
83 elif 'mac' in _names:
84 name = 'mac'
85 linesep = '\r'
86 from mac import *
87 try:
88 from mac import _exit
89 except ImportError:
90 pass
91 import macpath as path
93 import mac
94 __all__.extend(_get_exports_list(mac))
95 del mac
97 elif 'ce' in _names:
98 name = 'ce'
99 linesep = '\r\n'
100 from ce import *
101 try:
102 from ce import _exit
103 except ImportError:
104 pass
105 # We can use the standard Windows path.
106 import ntpath as path
108 import ce
109 __all__.extend(_get_exports_list(ce))
110 del ce
112 elif 'riscos' in _names:
113 name = 'riscos'
114 linesep = '\n'
115 from riscos import *
116 try:
117 from riscos import _exit
118 except ImportError:
119 pass
120 import riscospath as path
122 import riscos
123 __all__.extend(_get_exports_list(riscos))
124 del riscos
126 else:
127 raise ImportError, 'no os specific module found'
129 sys.modules['os.path'] = path
130 from os.path import curdir, pardir, sep, pathsep, defpath, extsep, altsep
132 del _names
136 # Super directory utilities.
137 # (Inspired by Eric Raymond; the doc strings are mostly his)
139 def makedirs(name, mode=0777):
140 """makedirs(path [, mode=0777])
142 Super-mkdir; create a leaf directory and all intermediate ones.
143 Works like mkdir, except that any intermediate path segment (not
144 just the rightmost) will be created if it does not exist. This is
145 recursive.
148 head, tail = path.split(name)
149 if not tail:
150 head, tail = path.split(head)
151 if head and tail and not path.exists(head):
152 makedirs(head, mode)
153 mkdir(name, mode)
155 def removedirs(name):
156 """removedirs(path)
158 Super-rmdir; remove a leaf directory and empty all intermediate
159 ones. Works like rmdir except that, if the leaf directory is
160 successfully removed, directories corresponding to rightmost path
161 segments will be pruned way until either the whole path is
162 consumed or an error occurs. Errors during this latter phase are
163 ignored -- they generally mean that a directory was not empty.
166 rmdir(name)
167 head, tail = path.split(name)
168 if not tail:
169 head, tail = path.split(head)
170 while head and tail:
171 try:
172 rmdir(head)
173 except error:
174 break
175 head, tail = path.split(head)
177 def renames(old, new):
178 """renames(old, new)
180 Super-rename; create directories as necessary and delete any left
181 empty. Works like rename, except creation of any intermediate
182 directories needed to make the new pathname good is attempted
183 first. After the rename, directories corresponding to rightmost
184 path segments of the old name will be pruned way until either the
185 whole path is consumed or a nonempty directory is found.
187 Note: this function can fail with the new directory structure made
188 if you lack permissions needed to unlink the leaf directory or
189 file.
192 head, tail = path.split(new)
193 if head and tail and not path.exists(head):
194 makedirs(head)
195 rename(old, new)
196 head, tail = path.split(old)
197 if head and tail:
198 try:
199 removedirs(head)
200 except error:
201 pass
203 __all__.extend(["makedirs", "removedirs", "renames"])
205 # Make sure os.environ exists, at least
206 try:
207 environ
208 except NameError:
209 environ = {}
211 def execl(file, *args):
212 """execl(file, *args)
214 Execute the executable file with argument list args, replacing the
215 current process. """
216 execv(file, args)
218 def execle(file, *args):
219 """execle(file, *args, env)
221 Execute the executable file with argument list args and
222 environment env, replacing the current process. """
223 env = args[-1]
224 execve(file, args[:-1], env)
226 def execlp(file, *args):
227 """execlp(file, *args)
229 Execute the executable file (which is searched for along $PATH)
230 with argument list args, replacing the current process. """
231 execvp(file, args)
233 def execlpe(file, *args):
234 """execlpe(file, *args, env)
236 Execute the executable file (which is searched for along $PATH)
237 with argument list args and environment env, replacing the current
238 process. """
239 env = args[-1]
240 execvpe(file, args[:-1], env)
242 def execvp(file, args):
243 """execp(file, args)
245 Execute the executable file (which is searched for along $PATH)
246 with argument list args, replacing the current process.
247 args may be a list or tuple of strings. """
248 _execvpe(file, args)
250 def execvpe(file, args, env):
251 """execvpe(file, args, env)
253 Execute the executable file (which is searched for along $PATH)
254 with argument list args and environment env , replacing the
255 current process.
256 args may be a list or tuple of strings. """
257 _execvpe(file, args, env)
259 __all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
261 def _execvpe(file, args, env=None):
262 from errno import ENOENT, ENOTDIR
264 if env is not None:
265 func = execve
266 argrest = (args, env)
267 else:
268 func = execv
269 argrest = (args,)
270 env = environ
272 head, tail = path.split(file)
273 if head:
274 func(file, *argrest)
275 return
276 if 'PATH' in env:
277 envpath = env['PATH']
278 else:
279 envpath = defpath
280 PATH = envpath.split(pathsep)
281 saved_exc = None
282 saved_tb = None
283 for dir in PATH:
284 fullname = path.join(dir, file)
285 try:
286 func(fullname, *argrest)
287 except error, e:
288 tb = sys.exc_info()[2]
289 if (e.errno != ENOENT and e.errno != ENOTDIR
290 and saved_exc is None):
291 saved_exc = e
292 saved_tb = tb
293 if saved_exc:
294 raise error, saved_exc, saved_tb
295 raise error, e, tb
297 # Change environ to automatically call putenv() if it exists
298 try:
299 # This will fail if there's no putenv
300 putenv
301 except NameError:
302 pass
303 else:
304 import UserDict
306 # Fake unsetenv() for Windows
307 # not sure about os2 here but
308 # I'm guessing they are the same.
310 if name in ('os2', 'nt'):
311 def unsetenv(key):
312 putenv(key, "")
314 if name == "riscos":
315 # On RISC OS, all env access goes through getenv and putenv
316 from riscosenviron import _Environ
317 elif name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE
318 # But we store them as upper case
319 class _Environ(UserDict.IterableUserDict):
320 def __init__(self, environ):
321 UserDict.UserDict.__init__(self)
322 data = self.data
323 for k, v in environ.items():
324 data[k.upper()] = v
325 def __setitem__(self, key, item):
326 putenv(key, item)
327 self.data[key.upper()] = item
328 def __getitem__(self, key):
329 return self.data[key.upper()]
330 try:
331 unsetenv
332 except NameError:
333 def __delitem__(self, key):
334 del self.data[key.upper()]
335 else:
336 def __delitem__(self, key):
337 unsetenv(key)
338 del self.data[key.upper()]
339 def has_key(self, key):
340 return key.upper() in self.data
341 def __contains__(self, key):
342 return key.upper() in self.data
343 def get(self, key, failobj=None):
344 return self.data.get(key.upper(), failobj)
345 def update(self, dict):
346 for k, v in dict.items():
347 self[k] = v
348 def copy(self):
349 return dict(self)
351 else: # Where Env Var Names Can Be Mixed Case
352 class _Environ(UserDict.IterableUserDict):
353 def __init__(self, environ):
354 UserDict.UserDict.__init__(self)
355 self.data = environ
356 def __setitem__(self, key, item):
357 putenv(key, item)
358 self.data[key] = item
359 def update(self, dict):
360 for k, v in dict.items():
361 self[k] = v
362 try:
363 unsetenv
364 except NameError:
365 pass
366 else:
367 def __delitem__(self, key):
368 unsetenv(key)
369 del self.data[key]
370 def copy(self):
371 return dict(self)
374 environ = _Environ(environ)
376 def getenv(key, default=None):
377 """Get an environment variable, return None if it doesn't exist.
378 The optional second argument can specify an alternate default."""
379 return environ.get(key, default)
380 __all__.append("getenv")
382 def _exists(name):
383 try:
384 eval(name)
385 return True
386 except NameError:
387 return False
389 # Supply spawn*() (probably only for Unix)
390 if _exists("fork") and not _exists("spawnv") and _exists("execv"):
392 P_WAIT = 0
393 P_NOWAIT = P_NOWAITO = 1
395 # XXX Should we support P_DETACH? I suppose it could fork()**2
396 # and close the std I/O streams. Also, P_OVERLAY is the same
397 # as execv*()?
399 def _spawnvef(mode, file, args, env, func):
400 # Internal helper; func is the exec*() function to use
401 pid = fork()
402 if not pid:
403 # Child
404 try:
405 if env is None:
406 func(file, args)
407 else:
408 func(file, args, env)
409 except:
410 _exit(127)
411 else:
412 # Parent
413 if mode == P_NOWAIT:
414 return pid # Caller is responsible for waiting!
415 while 1:
416 wpid, sts = waitpid(pid, 0)
417 if WIFSTOPPED(sts):
418 continue
419 elif WIFSIGNALED(sts):
420 return -WTERMSIG(sts)
421 elif WIFEXITED(sts):
422 return WEXITSTATUS(sts)
423 else:
424 raise error, "Not stopped, signaled or exited???"
426 def spawnv(mode, file, args):
427 """spawnv(mode, file, args) -> integer
429 Execute file with arguments from args in a subprocess.
430 If mode == P_NOWAIT return the pid of the process.
431 If mode == P_WAIT return the process's exit code if it exits normally;
432 otherwise return -SIG, where SIG is the signal that killed it. """
433 return _spawnvef(mode, file, args, None, execv)
435 def spawnve(mode, file, args, env):
436 """spawnve(mode, file, args, env) -> integer
438 Execute file with arguments from args in a subprocess with the
439 specified environment.
440 If mode == P_NOWAIT return the pid of the process.
441 If mode == P_WAIT return the process's exit code if it exits normally;
442 otherwise return -SIG, where SIG is the signal that killed it. """
443 return _spawnvef(mode, file, args, env, execve)
445 # Note: spawnvp[e] is't currently supported on Windows
447 def spawnvp(mode, file, args):
448 """spawnvp(mode, file, args) -> integer
450 Execute file (which is looked for along $PATH) with arguments from
451 args in a subprocess.
452 If mode == P_NOWAIT return the pid of the process.
453 If mode == P_WAIT return the process's exit code if it exits normally;
454 otherwise return -SIG, where SIG is the signal that killed it. """
455 return _spawnvef(mode, file, args, None, execvp)
457 def spawnvpe(mode, file, args, env):
458 """spawnvpe(mode, file, args, env) -> integer
460 Execute file (which is looked for along $PATH) with arguments from
461 args in a subprocess with the supplied environment.
462 If mode == P_NOWAIT return the pid of the process.
463 If mode == P_WAIT return the process's exit code if it exits normally;
464 otherwise return -SIG, where SIG is the signal that killed it. """
465 return _spawnvef(mode, file, args, env, execvpe)
467 if _exists("spawnv"):
468 # These aren't supplied by the basic Windows code
469 # but can be easily implemented in Python
471 def spawnl(mode, file, *args):
472 """spawnl(mode, file, *args) -> integer
474 Execute file with arguments from args in a subprocess.
475 If mode == P_NOWAIT return the pid of the process.
476 If mode == P_WAIT return the process's exit code if it exits normally;
477 otherwise return -SIG, where SIG is the signal that killed it. """
478 return spawnv(mode, file, args)
480 def spawnle(mode, file, *args):
481 """spawnle(mode, file, *args, env) -> integer
483 Execute file with arguments from args in a subprocess with the
484 supplied environment.
485 If mode == P_NOWAIT return the pid of the process.
486 If mode == P_WAIT return the process's exit code if it exits normally;
487 otherwise return -SIG, where SIG is the signal that killed it. """
488 env = args[-1]
489 return spawnve(mode, file, args[:-1], env)
491 if _exists("spawnvp"):
492 # At the moment, Windows doesn't implement spawnvp[e],
493 # so it won't have spawnlp[e] either.
494 def spawnlp(mode, file, *args):
495 """spawnlp(mode, file, *args, env) -> integer
497 Execute file (which is looked for along $PATH) with arguments from
498 args in a subprocess with the supplied environment.
499 If mode == P_NOWAIT return the pid of the process.
500 If mode == P_WAIT return the process's exit code if it exits normally;
501 otherwise return -SIG, where SIG is the signal that killed it. """
502 return spawnvp(mode, file, args)
504 def spawnlpe(mode, file, *args):
505 """spawnlpe(mode, file, *args, env) -> integer
507 Execute file (which is looked for along $PATH) with arguments from
508 args in a subprocess with the supplied environment.
509 If mode == P_NOWAIT return the pid of the process.
510 If mode == P_WAIT return the process's exit code if it exits normally;
511 otherwise return -SIG, where SIG is the signal that killed it. """
512 env = args[-1]
513 return spawnvpe(mode, file, args[:-1], env)
516 __all__.extend(["spawnlp","spawnlpe","spawnv", "spawnve","spawnvp",
517 "spawnvpe","spawnl","spawnle",])
520 # Supply popen2 etc. (for Unix)
521 if _exists("fork"):
522 if not _exists("popen2"):
523 def popen2(cmd, mode="t", bufsize=-1):
524 import popen2
525 stdout, stdin = popen2.popen2(cmd, bufsize)
526 return stdin, stdout
527 __all__.append("popen2")
529 if not _exists("popen3"):
530 def popen3(cmd, mode="t", bufsize=-1):
531 import popen2
532 stdout, stdin, stderr = popen2.popen3(cmd, bufsize)
533 return stdin, stdout, stderr
534 __all__.append("popen3")
536 if not _exists("popen4"):
537 def popen4(cmd, mode="t", bufsize=-1):
538 import popen2
539 stdout, stdin = popen2.popen4(cmd, bufsize)
540 return stdin, stdout
541 __all__.append("popen4")
543 import copy_reg as _copy_reg
545 def _make_stat_result(tup, dict):
546 return stat_result(tup, dict)
548 def _pickle_stat_result(sr):
549 (type, args) = sr.__reduce__()
550 return (_make_stat_result, args)
552 try:
553 _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
554 except NameError: # stat_result may not exist
555 pass
557 def _make_statvfs_result(tup, dict):
558 return statvfs_result(tup, dict)
560 def _pickle_statvfs_result(sr):
561 (type, args) = sr.__reduce__()
562 return (_make_statvfs_result, args)
564 try:
565 _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
566 _make_statvfs_result)
567 except NameError: # statvfs_result may not exist
568 pass