blob: c7a3cc5a57b178a1c82d8eaf41169000ff6b67b5 [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 Rossum7da3cc52000-04-25 10:53:22 +0000186 """execl(file, *args)
187
188 Execute the executable file with argument list args, replacing the
189 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000190 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000191
192def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000193 """execle(file, *args, env)
194
195 Execute the executable file with argument list args and
196 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000197 env = args[-1]
198 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000199
200def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000201 """execlp(file, *args)
202
203 Execute the executable file (which is searched for along $PATH)
204 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000205 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000206
Guido van Rossum030afb11995-03-14 17:27:18 +0000207def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000208 """execlpe(file, *args, env)
209
210 Execute the executable file (which is searched for along $PATH)
211 with argument list args and environment env, replacing the current
212 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000213 env = args[-1]
214 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000215
Guido van Rossume65cce51993-11-08 15:05:21 +0000216def execvp(file, args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000217 """execp(file, args)
218
219 Execute the executable file (which is searched for along $PATH)
220 with argument list args, replacing the current process.
221 args may be a list or tupe of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000222 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000223
224def execvpe(file, args, env):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000225 """execv(file, args, env)
226
227 Execute the executable file (which is searched for along $PATH)
228 with argument list args and environment env , replacing the
229 current process.
230 args may be a list or tupe of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000231 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000232
233_notfound = None
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000234def _execvpe(file, args, env=None):
235 if env is not None:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000236 func = execve
237 argrest = (args, env)
238 else:
239 func = execv
240 argrest = (args,)
241 env = environ
242 global _notfound
243 head, tail = path.split(file)
244 if head:
245 apply(func, (file,) + argrest)
246 return
247 if env.has_key('PATH'):
248 envpath = env['PATH']
249 else:
250 envpath = defpath
Guido van Rossum965fdae2000-04-04 19:50:04 +0000251 PATH = envpath.split(pathsep)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000252 if not _notfound:
253 import tempfile
254 # Exec a file that is guaranteed not to exist
Guido van Rossum868b50a2000-04-26 20:32:08 +0000255 try: execv(tempfile.mktemp(), ('blah',))
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000256 except error, _notfound: pass
257 exc, arg = error, _notfound
258 for dir in PATH:
259 fullname = path.join(dir, file)
260 try:
261 apply(func, (fullname,) + argrest)
262 except error, (errno, msg):
263 if errno != arg[0]:
264 exc, arg = error, (errno, msg)
265 raise exc, arg
Guido van Rossum2979b011994-08-01 11:18:30 +0000266
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000267# Change environ to automatically call putenv() if it exists
268try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000269 # This will fail if there's no putenv
270 putenv
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000271except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000272 pass
Guido van Rossuma28dab51997-08-29 22:36:47 +0000273else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000274 import UserDict
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000275
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000276 if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE
277 # But we store them as upper case
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000278 class _Environ(UserDict.UserDict):
279 def __init__(self, environ):
280 UserDict.UserDict.__init__(self)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000281 data = self.data
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000282 for k, v in environ.items():
Guido van Rossum965fdae2000-04-04 19:50:04 +0000283 data[k.upper()] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000284 def __setitem__(self, key, item):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000285 putenv(key, item)
Guido van Rossum965fdae2000-04-04 19:50:04 +0000286 self.data[key.upper()] = item
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000287 def __getitem__(self, key):
Guido van Rossum965fdae2000-04-04 19:50:04 +0000288 return self.data[key.upper()]
289 def __delitem__(self, key):
290 del self.data[key.upper()]
Guido van Rossumb46413f1999-05-03 15:23:24 +0000291 def has_key(self, key):
Guido van Rossum965fdae2000-04-04 19:50:04 +0000292 return self.data.has_key(key.upper())
293 def get(self, key, failobj=None):
294 return self.data.get(key.upper(), failobj)
295 def update(self, dict):
296 for k, v in dict.items():
297 self[k] = v
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000298
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000299 else: # Where Env Var Names Can Be Mixed Case
300 class _Environ(UserDict.UserDict):
301 def __init__(self, environ):
302 UserDict.UserDict.__init__(self)
303 self.data = environ
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000304 def __setitem__(self, key, item):
305 putenv(key, item)
306 self.data[key] = item
Guido van Rossum965fdae2000-04-04 19:50:04 +0000307 def update(self, dict):
308 for k, v in dict.items():
309 self[k] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000310
311 environ = _Environ(environ)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000312
313def getenv(key, default=None):
314 """Get an environment variable, return None if it doesn't exist.
315
316 The optional second argument can specify an alternative default."""
317 return environ.get(key, default)
318
319def _exists(name):
320 try:
321 eval(name)
322 return 1
323 except NameError:
324 return 0
325
326# Supply spawn*() (probably only for Unix)
327if _exists("fork") and not _exists("spawnv") and _exists("execv"):
328
329 P_WAIT = 0
330 P_NOWAIT = P_NOWAITO = 1
331
332 # XXX Should we support P_DETACH? I suppose it could fork()**2
333 # and close the std I/O streams. Also, P_OVERLAY is the same
334 # as execv*()?
335
336 def _spawnvef(mode, file, args, env, func):
337 # Internal helper; func is the exec*() function to use
338 pid = fork()
339 if not pid:
340 # Child
341 try:
342 if env is None:
343 func(file, args)
344 else:
345 func(file, args, env)
346 except:
347 _exit(127)
348 else:
349 # Parent
350 if mode == P_NOWAIT:
351 return pid # Caller is responsible for waiting!
352 while 1:
353 wpid, sts = waitpid(pid, 0)
354 if WIFSTOPPED(sts):
355 continue
356 elif WIFSIGNALED(sts):
357 return -WTERMSIG(sts)
358 elif WIFEXITED(sts):
359 return WEXITSTATUS(sts)
360 else:
361 raise error, "Not stopped, signaled or exited???"
362
363 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000364 """spawnv(mode, file, args) -> integer
365
366Execute file with arguments from args in a subprocess.
367If mode == P_NOWAIT return the pid of the process.
368If mode == P_WAIT return the process's exit code if it exits normally;
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000369otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000370 return _spawnvef(mode, file, args, None, execv)
371
372 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000373 """spawnve(mode, file, args, env) -> integer
374
375Execute file with arguments from args in a subprocess with the
376specified environment.
377If mode == P_NOWAIT return the pid of the process.
378If mode == P_WAIT return the process's exit code if it exits normally;
379otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000380 return _spawnvef(mode, file, args, env, execve)
381
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000382 # Note: spawnvp[e] is't currently supported on Windows
383
384 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000385 """spawnvp(mode, file, args) -> integer
386
387Execute file (which is looked for along $PATH) with arguments from
388args in a subprocess.
389If mode == P_NOWAIT return the pid of the process.
390If mode == P_WAIT return the process's exit code if it exits normally;
391otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000392 return _spawnvef(mode, file, args, None, execvp)
393
394 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000395 """spawnvpe(mode, file, args, env) -> integer
396
397Execute file (which is looked for along $PATH) with arguments from
398args in a subprocess with the supplied environment.
399If mode == P_NOWAIT return the pid of the process.
400If mode == P_WAIT return the process's exit code if it exits normally;
401otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000402 return _spawnvef(mode, file, args, env, execvpe)
403
404if _exists("spawnv"):
405 # These aren't supplied by the basic Windows code
406 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000407
408 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000409 """spawnl(mode, file, *args) -> integer
410
411Execute file with arguments from args in a subprocess.
412If mode == P_NOWAIT return the pid of the process.
413If mode == P_WAIT return the process's exit code if it exits normally;
414otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000415 return spawnv(mode, file, args)
416
417 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000418 """spawnle(mode, file, *args, env) -> integer
419
420Execute file with arguments from args in a subprocess with the
421supplied environment.
422If mode == P_NOWAIT return the pid of the process.
423If mode == P_WAIT return the process's exit code if it exits normally;
424otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000425 env = args[-1]
426 return spawnve(mode, file, args[:-1], env)
427
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000428if _exists("spawnvp"):
429 # At the moment, Windows doesn't implement spawnvp[e],
430 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000431 def spawnlp(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000432 """spawnlp(mode, file, *args, env) -> integer
433
434Execute file (which is looked for along $PATH) with arguments from
435args in a subprocess with the supplied environment.
436If mode == P_NOWAIT return the pid of the process.
437If mode == P_WAIT return the process's exit code if it exits normally;
438otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000439 return spawnvp(mode, file, args)
440
441 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000442 """spawnlpe(mode, file, *args, env) -> integer
443
444Execute file (which is looked for along $PATH) with arguments from
445args in a subprocess with the supplied environment.
446If mode == P_NOWAIT return the pid of the process.
447If mode == P_WAIT return the process's exit code if it exits normally;
448otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000449 env = args[-1]
450 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000451
452