blob: eed95c5d2260b14eda76f3dc13756405a70fc202 [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
Guido van Rossum965fdae2000-04-04 19:50:04 +0000223 PATH = envpath.split(pathsep)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000224 if not _notfound:
225 import tempfile
226 # Exec a file that is guaranteed not to exist
227 try: execv(tempfile.mktemp(), ())
228 except error, _notfound: pass
229 exc, arg = error, _notfound
230 for dir in PATH:
231 fullname = path.join(dir, file)
232 try:
233 apply(func, (fullname,) + argrest)
234 except error, (errno, msg):
235 if errno != arg[0]:
236 exc, arg = error, (errno, msg)
237 raise exc, arg
Guido van Rossum2979b011994-08-01 11:18:30 +0000238
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000239# Change environ to automatically call putenv() if it exists
240try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000241 # This will fail if there's no putenv
242 putenv
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000243except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000244 pass
Guido van Rossuma28dab51997-08-29 22:36:47 +0000245else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000246 import UserDict
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000247
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000248 if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE
249 # But we store them as upper case
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000250 class _Environ(UserDict.UserDict):
251 def __init__(self, environ):
252 UserDict.UserDict.__init__(self)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000253 data = self.data
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000254 for k, v in environ.items():
Guido van Rossum965fdae2000-04-04 19:50:04 +0000255 data[k.upper()] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000256 def __setitem__(self, key, item):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000257 putenv(key, item)
Guido van Rossum965fdae2000-04-04 19:50:04 +0000258 self.data[key.upper()] = item
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000259 def __getitem__(self, key):
Guido van Rossum965fdae2000-04-04 19:50:04 +0000260 return self.data[key.upper()]
261 def __delitem__(self, key):
262 del self.data[key.upper()]
Guido van Rossumb46413f1999-05-03 15:23:24 +0000263 def has_key(self, key):
Guido van Rossum965fdae2000-04-04 19:50:04 +0000264 return self.data.has_key(key.upper())
265 def get(self, key, failobj=None):
266 return self.data.get(key.upper(), failobj)
267 def update(self, dict):
268 for k, v in dict.items():
269 self[k] = v
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000270
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000271 else: # Where Env Var Names Can Be Mixed Case
272 class _Environ(UserDict.UserDict):
273 def __init__(self, environ):
274 UserDict.UserDict.__init__(self)
275 self.data = environ
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000276 def __setitem__(self, key, item):
277 putenv(key, item)
278 self.data[key] = item
Guido van Rossum965fdae2000-04-04 19:50:04 +0000279 def update(self, dict):
280 for k, v in dict.items():
281 self[k] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000282
283 environ = _Environ(environ)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000284
285def getenv(key, default=None):
286 """Get an environment variable, return None if it doesn't exist.
287
288 The optional second argument can specify an alternative default."""
289 return environ.get(key, default)
290
291def _exists(name):
292 try:
293 eval(name)
294 return 1
295 except NameError:
296 return 0
297
298# Supply spawn*() (probably only for Unix)
299if _exists("fork") and not _exists("spawnv") and _exists("execv"):
300
301 P_WAIT = 0
302 P_NOWAIT = P_NOWAITO = 1
303
304 # XXX Should we support P_DETACH? I suppose it could fork()**2
305 # and close the std I/O streams. Also, P_OVERLAY is the same
306 # as execv*()?
307
308 def _spawnvef(mode, file, args, env, func):
309 # Internal helper; func is the exec*() function to use
310 pid = fork()
311 if not pid:
312 # Child
313 try:
314 if env is None:
315 func(file, args)
316 else:
317 func(file, args, env)
318 except:
319 _exit(127)
320 else:
321 # Parent
322 if mode == P_NOWAIT:
323 return pid # Caller is responsible for waiting!
324 while 1:
325 wpid, sts = waitpid(pid, 0)
326 if WIFSTOPPED(sts):
327 continue
328 elif WIFSIGNALED(sts):
329 return -WTERMSIG(sts)
330 elif WIFEXITED(sts):
331 return WEXITSTATUS(sts)
332 else:
333 raise error, "Not stopped, signaled or exited???"
334
335 def spawnv(mode, file, args):
336 return _spawnvef(mode, file, args, None, execv)
337
338 def spawnve(mode, file, args, env):
339 return _spawnvef(mode, file, args, env, execve)
340
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000341 # Note: spawnvp[e] is't currently supported on Windows
342
343 def spawnvp(mode, file, args):
344 return _spawnvef(mode, file, args, None, execvp)
345
346 def spawnvpe(mode, file, args, env):
347 return _spawnvef(mode, file, args, env, execvpe)
348
349if _exists("spawnv"):
350 # These aren't supplied by the basic Windows code
351 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000352
353 def spawnl(mode, file, *args):
354 return spawnv(mode, file, args)
355
356 def spawnle(mode, file, *args):
357 env = args[-1]
358 return spawnve(mode, file, args[:-1], env)
359
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000360if _exists("spawnvp"):
361 # At the moment, Windows doesn't implement spawnvp[e],
362 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000363 def spawnlp(mode, file, *args):
364 return spawnvp(mode, file, args)
365
366 def spawnlpe(mode, file, *args):
367 env = args[-1]
368 return spawnvpe(mode, file, args[:-1], env)