This commit was manufactured by cvs2svn to create tag
[python/dscho.git] / Lib / os.py
blobbf31ddcce0df47a045b9662382621d94a962bed6
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, dos, os2, mac, or ce, e.g. unlink, stat, etc.
5 - os.path is one of the modules posixpath, ntpath, macpath, or dospath
6 - os.name is 'posix', 'nt', 'dos', '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 altsep = None
31 __all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
32 "defpath", "name"]
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] != '_']
40 if 'posix' in _names:
41 name = 'posix'
42 linesep = '\n'
43 curdir = '.'; pardir = '..'; sep = '/'; pathsep = ':'
44 defpath = ':/bin:/usr/bin'
45 from posix import *
46 try:
47 from posix import _exit
48 except ImportError:
49 pass
50 import posixpath
51 path = posixpath
52 del posixpath
54 import posix
55 __all__.extend(_get_exports_list(posix))
56 del posix
58 elif 'nt' in _names:
59 name = 'nt'
60 linesep = '\r\n'
61 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
62 defpath = '.;C:\\bin'
63 from nt import *
64 for i in ['_exit']:
65 try:
66 exec "from nt import " + i
67 except ImportError:
68 pass
69 import ntpath
70 path = ntpath
71 del ntpath
73 import nt
74 __all__.extend(_get_exports_list(nt))
75 del nt
77 elif 'dos' in _names:
78 name = 'dos'
79 linesep = '\r\n'
80 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
81 defpath = '.;C:\\bin'
82 from dos import *
83 try:
84 from dos import _exit
85 except ImportError:
86 pass
87 import dospath
88 path = dospath
89 del dospath
91 import dos
92 __all__.extend(_get_exports_list(dos))
93 del dos
95 elif 'os2' in _names:
96 name = 'os2'
97 linesep = '\r\n'
98 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
99 defpath = '.;C:\\bin'
100 from os2 import *
101 try:
102 from os2 import _exit
103 except ImportError:
104 pass
105 import ntpath
106 path = ntpath
107 del ntpath
109 import os2
110 __all__.extend(_get_exports_list(os2))
111 del os2
113 elif 'mac' in _names:
114 name = 'mac'
115 linesep = '\r'
116 curdir = ':'; pardir = '::'; sep = ':'; pathsep = '\n'
117 defpath = ':'
118 from mac import *
119 try:
120 from mac import _exit
121 except ImportError:
122 pass
123 import macpath
124 path = macpath
125 del macpath
127 import mac
128 __all__.extend(_get_exports_list(mac))
129 del mac
131 elif 'ce' in _names:
132 name = 'ce'
133 linesep = '\r\n'
134 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
135 defpath = '\\Windows'
136 from ce import *
137 for i in ['_exit']:
138 try:
139 exec "from ce import " + i
140 except ImportError:
141 pass
142 # We can use the standard Windows path.
143 import ntpath
144 path = ntpath
145 del ntpath
147 import ce
148 __all__.extend(_get_exports_list(ce))
149 del ce
151 elif 'riscos' in _names:
152 name = 'riscos'
153 linesep = '\n'
154 curdir = '@'; pardir = '^'; sep = '.'; pathsep = ','
155 defpath = '<Run$Dir>'
156 from riscos import *
157 try:
158 from riscos import _exit
159 except ImportError:
160 pass
161 import riscospath
162 path = riscospath
163 del riscospath
165 import riscos
166 __all__.extend(_get_exports_list(riscos))
167 del riscos
169 else:
170 raise ImportError, 'no os specific module found'
173 if sep=='.':
174 extsep = '/'
175 else:
176 extsep = '.'
178 __all__.append("path")
180 del _names
182 sys.modules['os.path'] = path
186 # Super directory utilities.
187 # (Inspired by Eric Raymond; the doc strings are mostly his)
189 def makedirs(name, mode=0777):
190 """makedirs(path [, mode=0777]) -> None
192 Super-mkdir; create a leaf directory and all intermediate ones.
193 Works like mkdir, except that any intermediate path segment (not
194 just the rightmost) will be created if it does not exist. This is
195 recursive.
198 head, tail = path.split(name)
199 if not tail:
200 head, tail = path.split(head)
201 if head and tail and not path.exists(head):
202 makedirs(head, mode)
203 mkdir(name, mode)
205 def removedirs(name):
206 """removedirs(path) -> None
208 Super-rmdir; remove a leaf directory and empty all intermediate
209 ones. Works like rmdir except that, if the leaf directory is
210 successfully removed, directories corresponding to rightmost path
211 segments will be pruned way until either the whole path is
212 consumed or an error occurs. Errors during this latter phase are
213 ignored -- they generally mean that a directory was not empty.
216 rmdir(name)
217 head, tail = path.split(name)
218 if not tail:
219 head, tail = path.split(head)
220 while head and tail:
221 try:
222 rmdir(head)
223 except error:
224 break
225 head, tail = path.split(head)
227 def renames(old, new):
228 """renames(old, new) -> None
230 Super-rename; create directories as necessary and delete any left
231 empty. Works like rename, except creation of any intermediate
232 directories needed to make the new pathname good is attempted
233 first. After the rename, directories corresponding to rightmost
234 path segments of the old name will be pruned way until either the
235 whole path is consumed or a nonempty directory is found.
237 Note: this function can fail with the new directory structure made
238 if you lack permissions needed to unlink the leaf directory or
239 file.
242 head, tail = path.split(new)
243 if head and tail and not path.exists(head):
244 makedirs(head)
245 rename(old, new)
246 head, tail = path.split(old)
247 if head and tail:
248 try:
249 removedirs(head)
250 except error:
251 pass
253 __all__.extend(["makedirs", "removedirs", "renames"])
255 # Make sure os.environ exists, at least
256 try:
257 environ
258 except NameError:
259 environ = {}
261 def execl(file, *args):
262 """execl(file, *args)
264 Execute the executable file with argument list args, replacing the
265 current process. """
266 execv(file, args)
268 def execle(file, *args):
269 """execle(file, *args, env)
271 Execute the executable file with argument list args and
272 environment env, replacing the current process. """
273 env = args[-1]
274 execve(file, args[:-1], env)
276 def execlp(file, *args):
277 """execlp(file, *args)
279 Execute the executable file (which is searched for along $PATH)
280 with argument list args, replacing the current process. """
281 execvp(file, args)
283 def execlpe(file, *args):
284 """execlpe(file, *args, env)
286 Execute the executable file (which is searched for along $PATH)
287 with argument list args and environment env, replacing the current
288 process. """
289 env = args[-1]
290 execvpe(file, args[:-1], env)
292 def execvp(file, args):
293 """execp(file, args)
295 Execute the executable file (which is searched for along $PATH)
296 with argument list args, replacing the current process.
297 args may be a list or tuple of strings. """
298 _execvpe(file, args)
300 def execvpe(file, args, env):
301 """execv(file, args, env)
303 Execute the executable file (which is searched for along $PATH)
304 with argument list args and environment env , replacing the
305 current process.
306 args may be a list or tuple of strings. """
307 _execvpe(file, args, env)
309 __all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
311 _notfound = None
312 def _execvpe(file, args, env=None):
313 if env is not None:
314 func = execve
315 argrest = (args, env)
316 else:
317 func = execv
318 argrest = (args,)
319 env = environ
320 global _notfound
321 head, tail = path.split(file)
322 if head:
323 apply(func, (file,) + argrest)
324 return
325 if env.has_key('PATH'):
326 envpath = env['PATH']
327 else:
328 envpath = defpath
329 PATH = envpath.split(pathsep)
330 if not _notfound:
331 if sys.platform[:4] == 'beos':
332 # Process handling (fork, wait) under BeOS (up to 5.0)
333 # doesn't interoperate reliably with the thread interlocking
334 # that happens during an import. The actual error we need
335 # is the same on BeOS for posix.open() et al., ENOENT.
336 try: unlink('/_#.# ## #.#')
337 except error, _notfound: pass
338 else:
339 import tempfile
340 t = tempfile.mktemp()
341 # Exec a file that is guaranteed not to exist
342 try: execv(t, ('blah',))
343 except error, _notfound: pass
344 exc, arg = error, _notfound
345 for dir in PATH:
346 fullname = path.join(dir, file)
347 try:
348 apply(func, (fullname,) + argrest)
349 except error, (errno, msg):
350 if errno != arg[0]:
351 exc, arg = error, (errno, msg)
352 raise exc, arg
355 # Change environ to automatically call putenv() if it exists
356 try:
357 # This will fail if there's no putenv
358 putenv
359 except NameError:
360 pass
361 else:
362 import UserDict
364 # Fake unsetenv() for Windows
365 # not sure about os2 and dos here but
366 # I'm guessing they are the same.
368 if name in ('os2', 'nt', 'dos'):
369 def unsetenv(key):
370 putenv(key, "")
372 if name == "riscos":
373 # On RISC OS, all env access goes through getenv and putenv
374 from riscosenviron import _Environ
375 elif name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE
376 # But we store them as upper case
377 class _Environ(UserDict.UserDict):
378 def __init__(self, environ):
379 UserDict.UserDict.__init__(self)
380 data = self.data
381 for k, v in environ.items():
382 data[k.upper()] = v
383 def __setitem__(self, key, item):
384 putenv(key, item)
385 self.data[key.upper()] = item
386 def __getitem__(self, key):
387 return self.data[key.upper()]
388 try:
389 unsetenv
390 except NameError:
391 def __delitem__(self, key):
392 del self.data[key.upper()]
393 else:
394 def __delitem__(self, key):
395 unsetenv(key)
396 del self.data[key.upper()]
397 def has_key(self, key):
398 return self.data.has_key(key.upper())
399 def get(self, key, failobj=None):
400 return self.data.get(key.upper(), failobj)
401 def update(self, dict):
402 for k, v in dict.items():
403 self[k] = v
405 else: # Where Env Var Names Can Be Mixed Case
406 class _Environ(UserDict.UserDict):
407 def __init__(self, environ):
408 UserDict.UserDict.__init__(self)
409 self.data = environ
410 def __setitem__(self, key, item):
411 putenv(key, item)
412 self.data[key] = item
413 def update(self, dict):
414 for k, v in dict.items():
415 self[k] = v
416 try:
417 unsetenv
418 except NameError:
419 pass
420 else:
421 def __delitem__(self, key):
422 unsetenv(key)
423 del self.data[key]
426 environ = _Environ(environ)
428 def getenv(key, default=None):
429 """Get an environment variable, return None if it doesn't exist.
430 The optional second argument can specify an alternate default."""
431 return environ.get(key, default)
432 __all__.append("getenv")
434 def _exists(name):
435 try:
436 eval(name)
437 return 1
438 except NameError:
439 return 0
441 # Supply spawn*() (probably only for Unix)
442 if _exists("fork") and not _exists("spawnv") and _exists("execv"):
444 P_WAIT = 0
445 P_NOWAIT = P_NOWAITO = 1
447 # XXX Should we support P_DETACH? I suppose it could fork()**2
448 # and close the std I/O streams. Also, P_OVERLAY is the same
449 # as execv*()?
451 def _spawnvef(mode, file, args, env, func):
452 # Internal helper; func is the exec*() function to use
453 pid = fork()
454 if not pid:
455 # Child
456 try:
457 if env is None:
458 func(file, args)
459 else:
460 func(file, args, env)
461 except:
462 _exit(127)
463 else:
464 # Parent
465 if mode == P_NOWAIT:
466 return pid # Caller is responsible for waiting!
467 while 1:
468 wpid, sts = waitpid(pid, 0)
469 if WIFSTOPPED(sts):
470 continue
471 elif WIFSIGNALED(sts):
472 return -WTERMSIG(sts)
473 elif WIFEXITED(sts):
474 return WEXITSTATUS(sts)
475 else:
476 raise error, "Not stopped, signaled or exited???"
478 def spawnv(mode, file, args):
479 """spawnv(mode, file, args) -> integer
481 Execute file with arguments from args in a subprocess.
482 If mode == P_NOWAIT return the pid of the process.
483 If mode == P_WAIT return the process's exit code if it exits normally;
484 otherwise return -SIG, where SIG is the signal that killed it. """
485 return _spawnvef(mode, file, args, None, execv)
487 def spawnve(mode, file, args, env):
488 """spawnve(mode, file, args, env) -> integer
490 Execute file with arguments from args in a subprocess with the
491 specified environment.
492 If mode == P_NOWAIT return the pid of the process.
493 If mode == P_WAIT return the process's exit code if it exits normally;
494 otherwise return -SIG, where SIG is the signal that killed it. """
495 return _spawnvef(mode, file, args, env, execve)
497 # Note: spawnvp[e] is't currently supported on Windows
499 def spawnvp(mode, file, args):
500 """spawnvp(mode, file, args) -> integer
502 Execute file (which is looked for along $PATH) with arguments from
503 args in a subprocess.
504 If mode == P_NOWAIT return the pid of the process.
505 If mode == P_WAIT return the process's exit code if it exits normally;
506 otherwise return -SIG, where SIG is the signal that killed it. """
507 return _spawnvef(mode, file, args, None, execvp)
509 def spawnvpe(mode, file, args, env):
510 """spawnvpe(mode, file, args, env) -> integer
512 Execute file (which is looked for along $PATH) with arguments from
513 args in a subprocess with the supplied environment.
514 If mode == P_NOWAIT return the pid of the process.
515 If mode == P_WAIT return the process's exit code if it exits normally;
516 otherwise return -SIG, where SIG is the signal that killed it. """
517 return _spawnvef(mode, file, args, env, execvpe)
519 if _exists("spawnv"):
520 # These aren't supplied by the basic Windows code
521 # but can be easily implemented in Python
523 def spawnl(mode, file, *args):
524 """spawnl(mode, file, *args) -> integer
526 Execute file with arguments from args in a subprocess.
527 If mode == P_NOWAIT return the pid of the process.
528 If mode == P_WAIT return the process's exit code if it exits normally;
529 otherwise return -SIG, where SIG is the signal that killed it. """
530 return spawnv(mode, file, args)
532 def spawnle(mode, file, *args):
533 """spawnle(mode, file, *args, env) -> integer
535 Execute file with arguments from args in a subprocess with the
536 supplied environment.
537 If mode == P_NOWAIT return the pid of the process.
538 If mode == P_WAIT return the process's exit code if it exits normally;
539 otherwise return -SIG, where SIG is the signal that killed it. """
540 env = args[-1]
541 return spawnve(mode, file, args[:-1], env)
543 if _exists("spawnvp"):
544 # At the moment, Windows doesn't implement spawnvp[e],
545 # so it won't have spawnlp[e] either.
546 def spawnlp(mode, file, *args):
547 """spawnlp(mode, file, *args, env) -> integer
549 Execute file (which is looked for along $PATH) with arguments from
550 args in a subprocess with the supplied environment.
551 If mode == P_NOWAIT return the pid of the process.
552 If mode == P_WAIT return the process's exit code if it exits normally;
553 otherwise return -SIG, where SIG is the signal that killed it. """
554 return spawnvp(mode, file, args)
556 def spawnlpe(mode, file, *args):
557 """spawnlpe(mode, file, *args, env) -> integer
559 Execute file (which is looked for along $PATH) with arguments from
560 args in a subprocess with the supplied environment.
561 If mode == P_NOWAIT return the pid of the process.
562 If mode == P_WAIT return the process's exit code if it exits normally;
563 otherwise return -SIG, where SIG is the signal that killed it. """
564 env = args[-1]
565 return spawnvpe(mode, file, args[:-1], env)
568 __all__.extend(["spawnlp","spawnlpe","spawnv", "spawnve","spawnvp",
569 "spawnvpe","spawnl","spawnle",])
572 # Supply popen2 etc. (for Unix)
573 if _exists("fork"):
574 if not _exists("popen2"):
575 def popen2(cmd, mode="t", bufsize=-1):
576 import popen2
577 stdout, stdin = popen2.popen2(cmd, bufsize)
578 return stdin, stdout
579 __all__.append("popen2")
581 if not _exists("popen3"):
582 def popen3(cmd, mode="t", bufsize=-1):
583 import popen2
584 stdout, stdin, stderr = popen2.popen3(cmd, bufsize)
585 return stdin, stdout, stderr
586 __all__.append("popen3")
588 if not _exists("popen4"):
589 def popen4(cmd, mode="t", bufsize=-1):
590 import popen2
591 stdout, stdin = popen2.popen4(cmd, bufsize)
592 return stdin, stdout
593 __all__.append("popen4")