diff --git a/Lib/os.py b/Lib/os.py index bb90f2eed59..dda32135669 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -7,6 +7,8 @@ # - os.curdir is a string representing the current directory ('.' or ':') # - os.pardir is a string representing the parent directory ('..' or '::') # - os.sep is the (or a most common) pathname separator ('/' or ':') +# - os.pathsep is the component separator used in $PATH etc +# - os.defpath is the default search path for executables # Programs that import and use 'os' stand a better chance of being # portable between different platforms. Of course, they must then @@ -14,40 +16,29 @@ # and opendir), and leave all pathname manipulation to os.path # (e.g., split and join). -# XXX This is incorrect if the import *path fails... +_osindex = { + 'posix': ('.', '..', '/', ':', ':/bin:/usr/bin'), + 'dos': ('.', '..', '\\', ';', '.;C:\\bin'), + 'nt': ('.', '..', '\\', ';', '.;C:\\bin'), + 'mac': (':', '::', ':', ' ', ':'), +} -try: - from posix import * - try: - from posix import _exit - except ImportError: - pass - name = 'posix' - curdir = '.' - pardir = '..' - sep = '/' - import posixpath - path = posixpath - del posixpath -except ImportError: - try: - from mac import * - name = 'mac' - curdir = ':' - pardir = '::' - sep = ':' - import macpath - path = macpath - del macpath - except ImportError: - from dos import * - name = 'dos' - curdir = '.' # XXX doesn't always work - pardir = '..' # XXX doesn't always work - sep = '/' # XXX or '\\' ??? - import dospath - path = dospath - del dospath +import sys +for name in _osindex.keys(): + if name in sys.builtin_module_names: + curdir, pardir, sep, pathsep, defpath = _osindex[name] + exec 'from %s import *' % name + exec 'import %spath' % name + exec 'path = %spath' % name + exec 'del %spath' % name + try: + exec 'from %s import _exit' % name + except ImportError: + pass + break +else: + del name + raise ImportError, 'no os specific module found' def execl(file, *args): execv(file, args) @@ -59,22 +50,49 @@ def execle(file, *args): def execlp(file, *args): execvp(file, args) +_notfound = None def execvp(file, args): - if '/' in file: + global _notfound + head, tail = path.split(file) + if head: execv(file, args) return ENOENT = 2 if environ.has_key('PATH'): - import string - PATH = string.splitfields(environ['PATH'], ':') + envpath = environ['PATH'] else: - PATH = ['', '/bin', '/usr/bin'] - exc, arg = (ENOENT, 'No such file or directory') + envpath = defpath + import string + PATH = string.splitfields(envpath, pathsep) + if not _notfound: + import tempfile + # Exec a file that is guaranteed not to exist + try: execv(tempfile.mktemp(), ()) + except error, _notfound: pass + exc, arg = error, _notfound for dir in PATH: fullname = path.join(dir, file) try: execv(fullname, args) except error, (errno, msg): - if errno != ENOENT: + if errno != arg[0]: exc, arg = error, (errno, msg) raise exc, arg + +# Provide listdir for Windows NT that doesn't have it built in +if name == 'nt': + try: + _tmp = listdir + del _tmp + except NameError: + def listdir(name): + if path.ismount(name): + list = ['.'] + else: + list = ['.', '..'] + f = popen('dir/l/b ' + name, 'r') + line = f.readline() + while line: + list.append(line[:-1]) + line = f.readline() + return list