blob: 9bc5bd4108f681b35ae234ee69ea9089315a2a75 [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):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000336 """spawnv(mode, file, args) -> integer
337
338Execute file with arguments from args in a subprocess.
339If mode == P_NOWAIT return the pid of the process.
340If mode == P_WAIT return the process's exit code if it exits normally;
341otherwise return - (the signal that killed it). """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000342 return _spawnvef(mode, file, args, None, execv)
343
344 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000345 """spawnve(mode, file, args, env) -> integer
346
347Execute file with arguments from args in a subprocess with the
348specified environment.
349If mode == P_NOWAIT return the pid of the process.
350If mode == P_WAIT return the process's exit code if it exits normally;
351otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000352 return _spawnvef(mode, file, args, env, execve)
353
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000354 # Note: spawnvp[e] is't currently supported on Windows
355
356 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000357 """spawnvp(mode, file, args) -> integer
358
359Execute file (which is looked for along $PATH) with arguments from
360args in a subprocess.
361If mode == P_NOWAIT return the pid of the process.
362If mode == P_WAIT return the process's exit code if it exits normally;
363otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000364 return _spawnvef(mode, file, args, None, execvp)
365
366 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000367 """spawnvpe(mode, file, args, env) -> integer
368
369Execute file (which is looked for along $PATH) with arguments from
370args in a subprocess with the supplied environment.
371If mode == P_NOWAIT return the pid of the process.
372If mode == P_WAIT return the process's exit code if it exits normally;
373otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000374 return _spawnvef(mode, file, args, env, execvpe)
375
376if _exists("spawnv"):
377 # These aren't supplied by the basic Windows code
378 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000379
380 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000381 """spawnl(mode, file, *args) -> integer
382
383Execute file with arguments from args in a subprocess.
384If mode == P_NOWAIT return the pid of the process.
385If mode == P_WAIT return the process's exit code if it exits normally;
386otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000387 return spawnv(mode, file, args)
388
389 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000390 """spawnle(mode, file, *args, env) -> integer
391
392Execute file with arguments from args in a subprocess with the
393supplied environment.
394If mode == P_NOWAIT return the pid of the process.
395If mode == P_WAIT return the process's exit code if it exits normally;
396otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000397 env = args[-1]
398 return spawnve(mode, file, args[:-1], env)
399
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000400if _exists("spawnvp"):
401 # At the moment, Windows doesn't implement spawnvp[e],
402 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000403 def spawnlp(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000404 """spawnlp(mode, file, *args, env) -> integer
405
406Execute file (which is looked for along $PATH) with arguments from
407args in a subprocess with the supplied environment.
408If mode == P_NOWAIT return the pid of the process.
409If mode == P_WAIT return the process's exit code if it exits normally;
410otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000411 return spawnvp(mode, file, args)
412
413 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000414 """spawnlpe(mode, file, *args, env) -> integer
415
416Execute file (which is looked for along $PATH) with arguments from
417args in a subprocess with the supplied environment.
418If mode == P_NOWAIT return the pid of the process.
419If mode == P_WAIT return the process's exit code if it exits normally;
420otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000421 env = args[-1]
422 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000423
424