blob: 70af0a9406cc31cca0f3951b7e4d8558a28ad5a1 [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)
Fred Drake9f2550f2000-07-25 15:16:40 +0000129 if not tail:
130 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000131 if head and tail and not path.exists(head):
132 makedirs(head, mode)
133 mkdir(name, mode)
134
135def removedirs(name):
136 """removedirs(path) -> None
137
138 Super-rmdir; remove a leaf directory and empty all intermediate
139 ones. Works like rmdir except that, if the leaf directory is
140 successfully removed, directories corresponding to rightmost path
141 segments will be pruned way until either the whole path is
142 consumed or an error occurs. Errors during this latter phase are
143 ignored -- they generally mean that a directory was not empty.
144
145 """
146 rmdir(name)
147 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000148 if not tail:
149 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000150 while head and tail:
151 try:
152 rmdir(head)
153 except error:
154 break
155 head, tail = path.split(head)
156
157def renames(old, new):
158 """renames(old, new) -> None
159
160 Super-rename; create directories as necessary and delete any left
161 empty. Works like rename, except creation of any intermediate
162 directories needed to make the new pathname good is attempted
163 first. After the rename, directories corresponding to rightmost
164 path segments of the old name will be pruned way until either the
165 whole path is consumed or a nonempty directory is found.
166
167 Note: this function can fail with the new directory structure made
168 if you lack permissions needed to unlink the leaf directory or
169 file.
170
171 """
172 head, tail = path.split(new)
173 if head and tail and not path.exists(head):
174 makedirs(head)
175 rename(old, new)
176 head, tail = path.split(old)
177 if head and tail:
178 try:
179 removedirs(head)
180 except error:
181 pass
182
Guido van Rossuma28dab51997-08-29 22:36:47 +0000183# Make sure os.environ exists, at least
184try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000185 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000186except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000187 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000188
Guido van Rossume65cce51993-11-08 15:05:21 +0000189def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000190 """execl(file, *args)
191
192 Execute the executable file with argument list args, replacing the
193 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000194 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000195
196def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000197 """execle(file, *args, env)
198
199 Execute the executable file with argument list args and
200 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000201 env = args[-1]
202 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000203
204def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000205 """execlp(file, *args)
206
207 Execute the executable file (which is searched for along $PATH)
208 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000209 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000210
Guido van Rossum030afb11995-03-14 17:27:18 +0000211def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000212 """execlpe(file, *args, env)
213
214 Execute the executable file (which is searched for along $PATH)
215 with argument list args and environment env, replacing the current
216 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000217 env = args[-1]
218 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000219
Guido van Rossume65cce51993-11-08 15:05:21 +0000220def execvp(file, args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000221 """execp(file, args)
222
223 Execute the executable file (which is searched for along $PATH)
224 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000225 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000226 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000227
228def execvpe(file, args, env):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000229 """execv(file, args, env)
230
231 Execute the executable file (which is searched for along $PATH)
232 with argument list args and environment env , replacing the
233 current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000234 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000235 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000236
237_notfound = None
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000238def _execvpe(file, args, env=None):
239 if env is not None:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000240 func = execve
241 argrest = (args, env)
242 else:
243 func = execv
244 argrest = (args,)
245 env = environ
246 global _notfound
247 head, tail = path.split(file)
248 if head:
249 apply(func, (file,) + argrest)
250 return
251 if env.has_key('PATH'):
252 envpath = env['PATH']
253 else:
254 envpath = defpath
Guido van Rossum965fdae2000-04-04 19:50:04 +0000255 PATH = envpath.split(pathsep)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000256 if not _notfound:
257 import tempfile
258 # Exec a file that is guaranteed not to exist
Guido van Rossum868b50a2000-04-26 20:32:08 +0000259 try: execv(tempfile.mktemp(), ('blah',))
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000260 except error, _notfound: pass
261 exc, arg = error, _notfound
262 for dir in PATH:
263 fullname = path.join(dir, file)
264 try:
265 apply(func, (fullname,) + argrest)
266 except error, (errno, msg):
267 if errno != arg[0]:
268 exc, arg = error, (errno, msg)
269 raise exc, arg
Guido van Rossum2979b011994-08-01 11:18:30 +0000270
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000271# Change environ to automatically call putenv() if it exists
272try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000273 # This will fail if there's no putenv
274 putenv
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000275except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000276 pass
Guido van Rossuma28dab51997-08-29 22:36:47 +0000277else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000278 import UserDict
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000279
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000280 if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE
281 # But we store them as upper case
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000282 class _Environ(UserDict.UserDict):
283 def __init__(self, environ):
284 UserDict.UserDict.__init__(self)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000285 data = self.data
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000286 for k, v in environ.items():
Guido van Rossum965fdae2000-04-04 19:50:04 +0000287 data[k.upper()] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000288 def __setitem__(self, key, item):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000289 putenv(key, item)
Guido van Rossum965fdae2000-04-04 19:50:04 +0000290 self.data[key.upper()] = item
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000291 def __getitem__(self, key):
Guido van Rossum965fdae2000-04-04 19:50:04 +0000292 return self.data[key.upper()]
293 def __delitem__(self, key):
294 del self.data[key.upper()]
Guido van Rossumb46413f1999-05-03 15:23:24 +0000295 def has_key(self, key):
Guido van Rossum965fdae2000-04-04 19:50:04 +0000296 return self.data.has_key(key.upper())
297 def get(self, key, failobj=None):
298 return self.data.get(key.upper(), failobj)
299 def update(self, dict):
300 for k, v in dict.items():
301 self[k] = v
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000302
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000303 else: # Where Env Var Names Can Be Mixed Case
304 class _Environ(UserDict.UserDict):
305 def __init__(self, environ):
306 UserDict.UserDict.__init__(self)
307 self.data = environ
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000308 def __setitem__(self, key, item):
309 putenv(key, item)
310 self.data[key] = item
Guido van Rossum965fdae2000-04-04 19:50:04 +0000311 def update(self, dict):
312 for k, v in dict.items():
313 self[k] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000314
315 environ = _Environ(environ)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000316
317def getenv(key, default=None):
318 """Get an environment variable, return None if it doesn't exist.
319
320 The optional second argument can specify an alternative default."""
321 return environ.get(key, default)
322
323def _exists(name):
324 try:
325 eval(name)
326 return 1
327 except NameError:
328 return 0
329
330# Supply spawn*() (probably only for Unix)
331if _exists("fork") and not _exists("spawnv") and _exists("execv"):
332
333 P_WAIT = 0
334 P_NOWAIT = P_NOWAITO = 1
335
336 # XXX Should we support P_DETACH? I suppose it could fork()**2
337 # and close the std I/O streams. Also, P_OVERLAY is the same
338 # as execv*()?
339
340 def _spawnvef(mode, file, args, env, func):
341 # Internal helper; func is the exec*() function to use
342 pid = fork()
343 if not pid:
344 # Child
345 try:
346 if env is None:
347 func(file, args)
348 else:
349 func(file, args, env)
350 except:
351 _exit(127)
352 else:
353 # Parent
354 if mode == P_NOWAIT:
355 return pid # Caller is responsible for waiting!
356 while 1:
357 wpid, sts = waitpid(pid, 0)
358 if WIFSTOPPED(sts):
359 continue
360 elif WIFSIGNALED(sts):
361 return -WTERMSIG(sts)
362 elif WIFEXITED(sts):
363 return WEXITSTATUS(sts)
364 else:
365 raise error, "Not stopped, signaled or exited???"
366
367 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000368 """spawnv(mode, file, args) -> integer
369
370Execute file with arguments from args in a subprocess.
371If mode == P_NOWAIT return the pid of the process.
372If mode == P_WAIT return the process's exit code if it exits normally;
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000373otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000374 return _spawnvef(mode, file, args, None, execv)
375
376 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000377 """spawnve(mode, file, args, env) -> integer
378
379Execute file with arguments from args in a subprocess with the
380specified environment.
381If mode == P_NOWAIT return the pid of the process.
382If mode == P_WAIT return the process's exit code if it exits normally;
383otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000384 return _spawnvef(mode, file, args, env, execve)
385
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000386 # Note: spawnvp[e] is't currently supported on Windows
387
388 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000389 """spawnvp(mode, file, args) -> integer
390
391Execute file (which is looked for along $PATH) with arguments from
392args in a subprocess.
393If mode == P_NOWAIT return the pid of the process.
394If mode == P_WAIT return the process's exit code if it exits normally;
395otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000396 return _spawnvef(mode, file, args, None, execvp)
397
398 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000399 """spawnvpe(mode, file, args, env) -> integer
400
401Execute file (which is looked for along $PATH) with arguments from
402args in a subprocess with the supplied environment.
403If mode == P_NOWAIT return the pid of the process.
404If mode == P_WAIT return the process's exit code if it exits normally;
405otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000406 return _spawnvef(mode, file, args, env, execvpe)
407
408if _exists("spawnv"):
409 # These aren't supplied by the basic Windows code
410 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000411
412 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000413 """spawnl(mode, file, *args) -> integer
414
415Execute file with arguments from args in a subprocess.
416If mode == P_NOWAIT return the pid of the process.
417If mode == P_WAIT return the process's exit code if it exits normally;
418otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000419 return spawnv(mode, file, args)
420
421 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000422 """spawnle(mode, file, *args, env) -> integer
423
424Execute file with arguments from args in a subprocess with the
425supplied environment.
426If mode == P_NOWAIT return the pid of the process.
427If mode == P_WAIT return the process's exit code if it exits normally;
428otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000429 env = args[-1]
430 return spawnve(mode, file, args[:-1], env)
431
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000432if _exists("spawnvp"):
433 # At the moment, Windows doesn't implement spawnvp[e],
434 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000435 def spawnlp(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000436 """spawnlp(mode, file, *args, env) -> integer
437
438Execute file (which is looked for along $PATH) with arguments from
439args in a subprocess with the supplied environment.
440If mode == P_NOWAIT return the pid of the process.
441If mode == P_WAIT return the process's exit code if it exits normally;
442otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000443 return spawnvp(mode, file, args)
444
445 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000446 """spawnlpe(mode, file, *args, env) -> integer
447
448Execute file (which is looked for along $PATH) with arguments from
449args in a subprocess with the supplied environment.
450If mode == P_NOWAIT return the pid of the process.
451If mode == P_WAIT return the process's exit code if it exits normally;
452otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000453 env = args[-1]
454 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000455
456
Guido van Rossumd9a8e962000-09-19 03:04:52 +0000457# Supply popen2 etc. (for Unix)
458if _exists("fork"):
459 if not _exists("popen2"):
460 def popen2(cmd, mode="t", bufsize=-1):
461 assert mode[:1] in ("b", "t")
462 import popen2
463 stdout, stdin = popen2.popen2(cmd, bufsize)
464 return stdin, stdout
Fred Drake31f182e2000-08-28 17:20:05 +0000465
Guido van Rossumd9a8e962000-09-19 03:04:52 +0000466 if not _exists("popen3"):
467 def popen3(cmd, mode="t", bufsize=-1):
468 assert mode[:1] in ("b", "t")
469 import popen2
470 stdout, stdin, stderr = popen2.popen3(cmd, bufsize)
471 return stdin, stdout, stderr