77# - os.curdir is a string representing the current directory ('.' or ':')
88# - os.pardir is a string representing the parent directory ('..' or '::')
99# - os.sep is the (or a most common) pathname separator ('/' or ':')
10+ # - os.pathsep is the component separator used in $PATH etc
11+ # - os.defpath is the default search path for executables
1012
1113# Programs that import and use 'os' stand a better chance of being
1214# portable between different platforms. Of course, they must then
1315# only use functions that are defined by all platforms (e.g., unlink
1416# and opendir), and leave all pathname manipulation to os.path
1517# (e.g., split and join).
1618
17- # XXX This is incorrect if the import *path fails...
19+ _osindex = {
20+ 'posix' : ('.' , '..' , '/' , ':' , ':/bin:/usr/bin' ),
21+ 'dos' : ('.' , '..' , '\\ ' , ';' , '.;C:\\ bin' ),
22+ 'nt' : ('.' , '..' , '\\ ' , ';' , '.;C:\\ bin' ),
23+ 'mac' : (':' , '::' , ':' , ' ' , ':' ),
24+ }
1825
19- try :
20- from posix import *
21- try :
22- from posix import _exit
23- except ImportError :
24- pass
25- name = 'posix'
26- curdir = '.'
27- pardir = '..'
28- sep = '/'
29- import posixpath
30- path = posixpath
31- del posixpath
32- except ImportError :
33- try :
34- from mac import *
35- name = 'mac'
36- curdir = ':'
37- pardir = '::'
38- sep = ':'
39- import macpath
40- path = macpath
41- del macpath
42- except ImportError :
43- from dos import *
44- name = 'dos'
45- curdir = '.' # XXX doesn't always work
46- pardir = '..' # XXX doesn't always work
47- sep = '/' # XXX or '\\' ???
48- import dospath
49- path = dospath
50- del dospath
26+ import sys
27+ for name in _osindex .keys ():
28+ if name in sys .builtin_module_names :
29+ curdir , pardir , sep , pathsep , defpath = _osindex [name ]
30+ exec 'from %s import *' % name
31+ exec 'import %spath' % name
32+ exec 'path = %spath' % name
33+ exec 'del %spath' % name
34+ try :
35+ exec 'from %s import _exit' % name
36+ except ImportError :
37+ pass
38+ break
39+ else :
40+ del name
41+ raise ImportError , 'no os specific module found'
5142
5243def execl (file , * args ):
5344 execv (file , args )
@@ -59,22 +50,49 @@ def execle(file, *args):
5950def execlp (file , * args ):
6051 execvp (file , args )
6152
53+ _notfound = None
6254def execvp (file , args ):
63- if '/' in file :
55+ global _notfound
56+ head , tail = path .split (file )
57+ if head :
6458 execv (file , args )
6559 return
6660 ENOENT = 2
6761 if environ .has_key ('PATH' ):
68- import string
69- PATH = string .splitfields (environ ['PATH' ], ':' )
62+ envpath = environ ['PATH' ]
7063 else :
71- PATH = ['' , '/bin' , '/usr/bin' ]
72- exc , arg = (ENOENT , 'No such file or directory' )
64+ envpath = defpath
65+ import string
66+ PATH = string .splitfields (envpath , pathsep )
67+ if not _notfound :
68+ import tempfile
69+ # Exec a file that is guaranteed not to exist
70+ try : execv (tempfile .mktemp (), ())
71+ except error , _notfound : pass
72+ exc , arg = error , _notfound
7373 for dir in PATH :
7474 fullname = path .join (dir , file )
7575 try :
7676 execv (fullname , args )
7777 except error , (errno , msg ):
78- if errno != ENOENT :
78+ if errno != arg [ 0 ] :
7979 exc , arg = error , (errno , msg )
8080 raise exc , arg
81+
82+ # Provide listdir for Windows NT that doesn't have it built in
83+ if name == 'nt' :
84+ try :
85+ _tmp = listdir
86+ del _tmp
87+ except NameError :
88+ def listdir (name ):
89+ if path .ismount (name ):
90+ list = ['.' ]
91+ else :
92+ list = ['.' , '..' ]
93+ f = popen ('dir/l/b ' + name , 'r' )
94+ line = f .readline ()
95+ while line :
96+ list .append (line [:- 1 ])
97+ line = f .readline ()
98+ return list
0 commit comments