blob: 15230c165401cb52f630395f239bbe1b3ff34d9f [file] [log] [blame]
Guido van Rossumdd8cb441993-12-29 15:33:08 +00001# os.py -- either mac, dos or posix depending on what system we're on.
Guido van Rossum31104f41992-01-14 18:28:36 +00002
3# This exports:
4# - all functions from either posix or mac, e.g., os.unlink, os.stat, etc.
Guido van Rossum1a76ef21992-03-31 18:57:28 +00005# - os.path is either module posixpath or macpath
Guido van Rossum31104f41992-01-14 18:28:36 +00006# - os.name is either 'posix' or 'mac'
7# - os.curdir is a string representing the current directory ('.' or ':')
Guido van Rossum1a76ef21992-03-31 18:57:28 +00008# - os.pardir is a string representing the parent directory ('..' or '::')
Guido van Rossuma28dab51997-08-29 22:36:47 +00009# - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
10# - os.altsep is the alternatte pathname separator (None or '/')
Guido van Rossum2979b011994-08-01 11:18:30 +000011# - os.pathsep is the component separator used in $PATH etc
12# - os.defpath is the default search path for executables
Guido van Rossum31104f41992-01-14 18:28:36 +000013
14# Programs that import and use 'os' stand a better chance of being
15# portable between different platforms. Of course, they must then
16# only use functions that are defined by all platforms (e.g., unlink
17# and opendir), and leave all pathname manipulation to os.path
18# (e.g., split and join).
19
Guido van Rossum2979b011994-08-01 11:18:30 +000020import sys
Guido van Rossuma28dab51997-08-29 22:36:47 +000021
22_names = sys.builtin_module_names
23
24altsep = None
25
26if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000027 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000028 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000029 curdir = '.'; pardir = '..'; sep = '/'; pathsep = ':'
30 defpath = ':/bin:/usr/bin'
31 from posix import *
32 try:
33 from posix import _exit
34 except ImportError:
35 pass
36 import posixpath
37 path = posixpath
38 del posixpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000039elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000040 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000041 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000042 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
43 defpath = '.;C:\\bin'
44 from nt import *
45 try:
46 from nt import _exit
47 except ImportError:
48 pass
49 import ntpath
50 path = ntpath
51 del ntpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000052elif 'dos' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000053 name = 'dos'
Guido van Rossume9387ea1998-05-22 15:26:04 +000054 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000055 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
56 defpath = '.;C:\\bin'
57 from dos import *
58 try:
59 from dos import _exit
60 except ImportError:
61 pass
62 import dospath
63 path = dospath
64 del dospath
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000065elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000066 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000067 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000068 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
69 defpath = '.;C:\\bin'
70 from os2 import *
71 try:
72 from os2 import _exit
73 except ImportError:
74 pass
75 import ntpath
76 path = ntpath
77 del ntpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000078elif 'mac' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000079 name = 'mac'
Guido van Rossume9387ea1998-05-22 15:26:04 +000080 linesep = '\r'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000081 curdir = ':'; pardir = '::'; sep = ':'; pathsep = '\n'
82 defpath = ':'
83 from mac import *
84 try:
85 from mac import _exit
86 except ImportError:
87 pass
88 import macpath
89 path = macpath
90 del macpath
Guido van Rossum2979b011994-08-01 11:18:30 +000091else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000092 raise ImportError, 'no os specific module found'
Guido van Rossume65cce51993-11-08 15:05:21 +000093
Guido van Rossuma28dab51997-08-29 22:36:47 +000094del _names
95
Fred Drake02379091999-01-19 16:05:13 +000096sys.modules['os.path'] = path
97
Guido van Rossum4def7de1998-07-24 20:48:03 +000098# Super directory utilities.
99# (Inspired by Eric Raymond; the doc strings are mostly his)
100
101def makedirs(name, mode=0777):
102 """makedirs(path [, mode=0777]) -> None
103
104 Super-mkdir; create a leaf directory and all intermediate ones.
105 Works like mkdir, except that any intermediate path segment (not
106 just the rightmost) will be created if it does not exist. This is
107 recursive.
108
109 """
110 head, tail = path.split(name)
111 if head and tail and not path.exists(head):
112 makedirs(head, mode)
113 mkdir(name, mode)
114
115def removedirs(name):
116 """removedirs(path) -> None
117
118 Super-rmdir; remove a leaf directory and empty all intermediate
119 ones. Works like rmdir except that, if the leaf directory is
120 successfully removed, directories corresponding to rightmost path
121 segments will be pruned way until either the whole path is
122 consumed or an error occurs. Errors during this latter phase are
123 ignored -- they generally mean that a directory was not empty.
124
125 """
126 rmdir(name)
127 head, tail = path.split(name)
128 while head and tail:
129 try:
130 rmdir(head)
131 except error:
132 break
133 head, tail = path.split(head)
134
135def renames(old, new):
136 """renames(old, new) -> None
137
138 Super-rename; create directories as necessary and delete any left
139 empty. Works like rename, except creation of any intermediate
140 directories needed to make the new pathname good is attempted
141 first. After the rename, directories corresponding to rightmost
142 path segments of the old name will be pruned way until either the
143 whole path is consumed or a nonempty directory is found.
144
145 Note: this function can fail with the new directory structure made
146 if you lack permissions needed to unlink the leaf directory or
147 file.
148
149 """
150 head, tail = path.split(new)
151 if head and tail and not path.exists(head):
152 makedirs(head)
153 rename(old, new)
154 head, tail = path.split(old)
155 if head and tail:
156 try:
157 removedirs(head)
158 except error:
159 pass
160
Guido van Rossuma28dab51997-08-29 22:36:47 +0000161# Make sure os.environ exists, at least
162try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000163 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000164except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000165 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000166
Guido van Rossume65cce51993-11-08 15:05:21 +0000167def execl(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000168 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000169
170def execle(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000171 env = args[-1]
172 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000173
174def execlp(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000175 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000176
Guido van Rossum030afb11995-03-14 17:27:18 +0000177def execlpe(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000178 env = args[-1]
179 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000180
Guido van Rossume65cce51993-11-08 15:05:21 +0000181def execvp(file, args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000182 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000183
184def execvpe(file, args, env):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000185 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000186
187_notfound = None
188def _execvpe(file, args, env = None):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000189 if env:
190 func = execve
191 argrest = (args, env)
192 else:
193 func = execv
194 argrest = (args,)
195 env = environ
196 global _notfound
197 head, tail = path.split(file)
198 if head:
199 apply(func, (file,) + argrest)
200 return
201 if env.has_key('PATH'):
202 envpath = env['PATH']
203 else:
204 envpath = defpath
205 import string
206 PATH = string.splitfields(envpath, pathsep)
207 if not _notfound:
208 import tempfile
209 # Exec a file that is guaranteed not to exist
210 try: execv(tempfile.mktemp(), ())
211 except error, _notfound: pass
212 exc, arg = error, _notfound
213 for dir in PATH:
214 fullname = path.join(dir, file)
215 try:
216 apply(func, (fullname,) + argrest)
217 except error, (errno, msg):
218 if errno != arg[0]:
219 exc, arg = error, (errno, msg)
220 raise exc, arg
Guido van Rossum2979b011994-08-01 11:18:30 +0000221
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000222# Change environ to automatically call putenv() if it exists
223try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000224 # This will fail if there's no putenv
225 putenv
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000226except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000227 pass
Guido van Rossuma28dab51997-08-29 22:36:47 +0000228else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000229 import UserDict
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000230
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000231 if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE
232 # But we store them as upper case
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000233 import string
234 class _Environ(UserDict.UserDict):
235 def __init__(self, environ):
236 UserDict.UserDict.__init__(self)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000237 data = self.data
238 upper = string.upper
239 for k, v in environ.items():
240 data[upper(k)] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000241 def __setitem__(self, key, item):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000242 putenv(key, item)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000243 key = string.upper(key)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000244 self.data[key] = item
245 def __getitem__(self, key):
246 return self.data[string.upper(key)]
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000247
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000248 else: # Where Env Var Names Can Be Mixed Case
249 class _Environ(UserDict.UserDict):
250 def __init__(self, environ):
251 UserDict.UserDict.__init__(self)
252 self.data = environ
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000253 def __setitem__(self, key, item):
254 putenv(key, item)
255 self.data[key] = item
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000256
257 environ = _Environ(environ)