blob: 118b6198bfa201089c234ff1c74a41ca4cec2f35 [file] [log] [blame]
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +00001"""OS routines for Mac, DOS, NT, or Posix depending on what system we're on.
Guido van Rossum31104f41992-01-14 18:28:36 +00002
Guido van Rossum54f22ed2000-02-04 15:10:34 +00003This exports:
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +00004 - 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', or 'ce'
Guido van Rossum54f22ed2000-02-04 15:10:34 +00007 - 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 '\\')
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +000010 - os.altsep is the alternate pathname separator (None or '/')
Guido van Rossum54f22ed2000-02-04 15:10:34 +000011 - os.pathsep is the component separator used in $PATH etc
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +000012 - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
Guido van Rossum54f22ed2000-02-04 15:10:34 +000013 - os.defpath is the default search path for executables
Guido van Rossum31104f41992-01-14 18:28:36 +000014
Guido van Rossum54f22ed2000-02-04 15:10:34 +000015Programs that import and use 'os' stand a better chance of being
16portable between different platforms. Of course, they must then
17only use functions that are defined by all platforms (e.g., unlink
18and opendir), and leave all pathname manipulation to os.path
19(e.g., split and join).
20"""
Guido van Rossum31104f41992-01-14 18:28:36 +000021
Guido van Rossum2979b011994-08-01 11:18:30 +000022import sys
Guido van Rossuma28dab51997-08-29 22:36:47 +000023
24_names = sys.builtin_module_names
25
26altsep = None
27
28if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000029 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000030 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000031 curdir = '.'; pardir = '..'; sep = '/'; pathsep = ':'
32 defpath = ':/bin:/usr/bin'
33 from posix import *
34 try:
35 from posix import _exit
36 except ImportError:
37 pass
38 import posixpath
39 path = posixpath
40 del posixpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000041elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000042 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000043 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000044 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
45 defpath = '.;C:\\bin'
46 from nt import *
Guido van Rossumfb801e71999-02-22 15:40:34 +000047 for i in ['_exit']:
Guido van Rossum67c65b21999-02-01 23:52:29 +000048 try:
49 exec "from nt import " + i
50 except ImportError:
51 pass
Guido van Rossum61de0ac1997-12-05 21:24:30 +000052 import ntpath
53 path = ntpath
54 del ntpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000055elif 'dos' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000056 name = 'dos'
Guido van Rossume9387ea1998-05-22 15:26:04 +000057 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000058 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
59 defpath = '.;C:\\bin'
60 from dos import *
61 try:
62 from dos import _exit
63 except ImportError:
64 pass
65 import dospath
66 path = dospath
67 del dospath
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000068elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000069 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000070 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000071 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
72 defpath = '.;C:\\bin'
73 from os2 import *
74 try:
75 from os2 import _exit
76 except ImportError:
77 pass
78 import ntpath
79 path = ntpath
80 del ntpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000081elif 'mac' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000082 name = 'mac'
Guido van Rossume9387ea1998-05-22 15:26:04 +000083 linesep = '\r'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000084 curdir = ':'; pardir = '::'; sep = ':'; pathsep = '\n'
85 defpath = ':'
86 from mac import *
87 try:
88 from mac import _exit
89 except ImportError:
90 pass
91 import macpath
92 path = macpath
93 del macpath
Guido van Rossum18df5d41999-06-11 01:37:27 +000094elif 'ce' in _names:
95 name = 'ce'
96 linesep = '\r\n'
97 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
98 defpath = '\\Windows'
99 from ce import *
100 for i in ['_exit']:
101 try:
102 exec "from ce import " + i
103 except ImportError:
104 pass
105 # We can use the standard Windows path.
106 import ntpath
107 path = ntpath
108 del ntpath
Guido van Rossum2979b011994-08-01 11:18:30 +0000109else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000110 raise ImportError, 'no os specific module found'
Guido van Rossume65cce51993-11-08 15:05:21 +0000111
Guido van Rossuma28dab51997-08-29 22:36:47 +0000112del _names
113
Fred Drake02379091999-01-19 16:05:13 +0000114sys.modules['os.path'] = path
115
Guido van Rossum4def7de1998-07-24 20:48:03 +0000116# Super directory utilities.
117# (Inspired by Eric Raymond; the doc strings are mostly his)
118
119def makedirs(name, mode=0777):
120 """makedirs(path [, mode=0777]) -> None
121
122 Super-mkdir; create a leaf directory and all intermediate ones.
123 Works like mkdir, except that any intermediate path segment (not
124 just the rightmost) will be created if it does not exist. This is
125 recursive.
126
127 """
128 head, tail = path.split(name)
129 if head and tail and not path.exists(head):
130 makedirs(head, mode)
131 mkdir(name, mode)
132
133def removedirs(name):
134 """removedirs(path) -> None
135
136 Super-rmdir; remove a leaf directory and empty all intermediate
137 ones. Works like rmdir except that, if the leaf directory is
138 successfully removed, directories corresponding to rightmost path
139 segments will be pruned way until either the whole path is
140 consumed or an error occurs. Errors during this latter phase are
141 ignored -- they generally mean that a directory was not empty.
142
143 """
144 rmdir(name)
145 head, tail = path.split(name)
146 while head and tail:
147 try:
148 rmdir(head)
149 except error:
150 break
151 head, tail = path.split(head)
152
153def renames(old, new):
154 """renames(old, new) -> None
155
156 Super-rename; create directories as necessary and delete any left
157 empty. Works like rename, except creation of any intermediate
158 directories needed to make the new pathname good is attempted
159 first. After the rename, directories corresponding to rightmost
160 path segments of the old name will be pruned way until either the
161 whole path is consumed or a nonempty directory is found.
162
163 Note: this function can fail with the new directory structure made
164 if you lack permissions needed to unlink the leaf directory or
165 file.
166
167 """
168 head, tail = path.split(new)
169 if head and tail and not path.exists(head):
170 makedirs(head)
171 rename(old, new)
172 head, tail = path.split(old)
173 if head and tail:
174 try:
175 removedirs(head)
176 except error:
177 pass
178
Guido van Rossuma28dab51997-08-29 22:36:47 +0000179# Make sure os.environ exists, at least
180try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000181 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000182except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000183 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000184
Guido van Rossume65cce51993-11-08 15:05:21 +0000185def execl(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000186 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000187
188def execle(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000189 env = args[-1]
190 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000191
192def execlp(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000193 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000194
Guido van Rossum030afb11995-03-14 17:27:18 +0000195def execlpe(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000196 env = args[-1]
197 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000198
Guido van Rossume65cce51993-11-08 15:05:21 +0000199def execvp(file, args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000200 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000201
202def execvpe(file, args, env):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000203 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000204
205_notfound = None
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000206def _execvpe(file, args, env=None):
207 if env is not None:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000208 func = execve
209 argrest = (args, env)
210 else:
211 func = execv
212 argrest = (args,)
213 env = environ
214 global _notfound
215 head, tail = path.split(file)
216 if head:
217 apply(func, (file,) + argrest)
218 return
219 if env.has_key('PATH'):
220 envpath = env['PATH']
221 else:
222 envpath = defpath
223 import string
224 PATH = string.splitfields(envpath, pathsep)
225 if not _notfound:
226 import tempfile
227 # Exec a file that is guaranteed not to exist
228 try: execv(tempfile.mktemp(), ())
229 except error, _notfound: pass
230 exc, arg = error, _notfound
231 for dir in PATH:
232 fullname = path.join(dir, file)
233 try:
234 apply(func, (fullname,) + argrest)
235 except error, (errno, msg):
236 if errno != arg[0]:
237 exc, arg = error, (errno, msg)
238 raise exc, arg
Guido van Rossum2979b011994-08-01 11:18:30 +0000239
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000240# Change environ to automatically call putenv() if it exists
241try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000242 # This will fail if there's no putenv
243 putenv
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000244except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000245 pass
Guido van Rossuma28dab51997-08-29 22:36:47 +0000246else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000247 import UserDict
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000248
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000249 if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE
250 # But we store them as upper case
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000251 import string
252 class _Environ(UserDict.UserDict):
253 def __init__(self, environ):
254 UserDict.UserDict.__init__(self)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000255 data = self.data
256 upper = string.upper
257 for k, v in environ.items():
258 data[upper(k)] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000259 def __setitem__(self, key, item):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000260 putenv(key, item)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000261 key = string.upper(key)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000262 self.data[key] = item
263 def __getitem__(self, key):
264 return self.data[string.upper(key)]
Guido van Rossumb46413f1999-05-03 15:23:24 +0000265 def has_key(self, key):
266 return self.data.has_key(string.upper(key))
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000267
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000268 else: # Where Env Var Names Can Be Mixed Case
269 class _Environ(UserDict.UserDict):
270 def __init__(self, environ):
271 UserDict.UserDict.__init__(self)
272 self.data = environ
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000273 def __setitem__(self, key, item):
274 putenv(key, item)
275 self.data[key] = item
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000276
277 environ = _Environ(environ)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000278
279def getenv(key, default=None):
280 """Get an environment variable, return None if it doesn't exist.
281
282 The optional second argument can specify an alternative default."""
283 return environ.get(key, default)
284
285def _exists(name):
286 try:
287 eval(name)
288 return 1
289 except NameError:
290 return 0
291
292# Supply spawn*() (probably only for Unix)
293if _exists("fork") and not _exists("spawnv") and _exists("execv"):
294
295 P_WAIT = 0
296 P_NOWAIT = P_NOWAITO = 1
297
298 # XXX Should we support P_DETACH? I suppose it could fork()**2
299 # and close the std I/O streams. Also, P_OVERLAY is the same
300 # as execv*()?
301
302 def _spawnvef(mode, file, args, env, func):
303 # Internal helper; func is the exec*() function to use
304 pid = fork()
305 if not pid:
306 # Child
307 try:
308 if env is None:
309 func(file, args)
310 else:
311 func(file, args, env)
312 except:
313 _exit(127)
314 else:
315 # Parent
316 if mode == P_NOWAIT:
317 return pid # Caller is responsible for waiting!
318 while 1:
319 wpid, sts = waitpid(pid, 0)
320 if WIFSTOPPED(sts):
321 continue
322 elif WIFSIGNALED(sts):
323 return -WTERMSIG(sts)
324 elif WIFEXITED(sts):
325 return WEXITSTATUS(sts)
326 else:
327 raise error, "Not stopped, signaled or exited???"
328
329 def spawnv(mode, file, args):
330 return _spawnvef(mode, file, args, None, execv)
331
332 def spawnve(mode, file, args, env):
333 return _spawnvef(mode, file, args, env, execve)
334
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000335 # Note: spawnvp[e] is't currently supported on Windows
336
337 def spawnvp(mode, file, args):
338 return _spawnvef(mode, file, args, None, execvp)
339
340 def spawnvpe(mode, file, args, env):
341 return _spawnvef(mode, file, args, env, execvpe)
342
343if _exists("spawnv"):
344 # These aren't supplied by the basic Windows code
345 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000346
347 def spawnl(mode, file, *args):
348 return spawnv(mode, file, args)
349
350 def spawnle(mode, file, *args):
351 env = args[-1]
352 return spawnve(mode, file, args[:-1], env)
353
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000354if _exists("spawnvp"):
355 # At the moment, Windows doesn't implement spawnvp[e],
356 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000357 def spawnlp(mode, file, *args):
358 return spawnvp(mode, file, args)
359
360 def spawnlpe(mode, file, *args):
361 env = args[-1]
362 return spawnvpe(mode, file, args[:-1], env)