blob: 129d4b29980b019766eb03367e6d14f36bccc456 [file] [log] [blame]
Guido van Rossum54f22ed2000-02-04 15:10:34 +00001"""os.py -- either mac, dos 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:
4 - all functions from either posix or mac, e.g., os.unlink, os.stat, etc.
5 - os.path is either module posixpath or macpath
6 - os.name is either 'posix' or 'mac'
7 - 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 '\\')
10 - os.altsep is the alternatte pathname separator (None or '/')
11 - os.pathsep is the component separator used in $PATH etc
12 - os.defpath is the default search path for executables
Guido van Rossum31104f41992-01-14 18:28:36 +000013
Guido van Rossum54f22ed2000-02-04 15:10:34 +000014Programs that import and use 'os' stand a better chance of being
15portable between different platforms. Of course, they must then
16only use functions that are defined by all platforms (e.g., unlink
17and opendir), and leave all pathname manipulation to os.path
18(e.g., split and join).
19"""
Guido van Rossum31104f41992-01-14 18:28:36 +000020
Guido van Rossum2979b011994-08-01 11:18:30 +000021import sys
Guido van Rossuma28dab51997-08-29 22:36:47 +000022
23_names = sys.builtin_module_names
24
25altsep = None
26
27if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000028 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000029 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000030 curdir = '.'; pardir = '..'; sep = '/'; pathsep = ':'
31 defpath = ':/bin:/usr/bin'
32 from posix import *
33 try:
34 from posix import _exit
35 except ImportError:
36 pass
37 import posixpath
38 path = posixpath
39 del posixpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000040elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000041 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000042 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000043 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
44 defpath = '.;C:\\bin'
45 from nt import *
Guido van Rossumfb801e71999-02-22 15:40:34 +000046 for i in ['_exit']:
Guido van Rossum67c65b21999-02-01 23:52:29 +000047 try:
48 exec "from nt import " + i
49 except ImportError:
50 pass
Guido van Rossum61de0ac1997-12-05 21:24:30 +000051 import ntpath
52 path = ntpath
53 del ntpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000054elif 'dos' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000055 name = 'dos'
Guido van Rossume9387ea1998-05-22 15:26:04 +000056 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000057 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
58 defpath = '.;C:\\bin'
59 from dos import *
60 try:
61 from dos import _exit
62 except ImportError:
63 pass
64 import dospath
65 path = dospath
66 del dospath
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000067elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000068 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000069 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000070 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
71 defpath = '.;C:\\bin'
72 from os2 import *
73 try:
74 from os2 import _exit
75 except ImportError:
76 pass
77 import ntpath
78 path = ntpath
79 del ntpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000080elif 'mac' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000081 name = 'mac'
Guido van Rossume9387ea1998-05-22 15:26:04 +000082 linesep = '\r'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000083 curdir = ':'; pardir = '::'; sep = ':'; pathsep = '\n'
84 defpath = ':'
85 from mac import *
86 try:
87 from mac import _exit
88 except ImportError:
89 pass
90 import macpath
91 path = macpath
92 del macpath
Guido van Rossum18df5d41999-06-11 01:37:27 +000093elif 'ce' in _names:
94 name = 'ce'
95 linesep = '\r\n'
96 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
97 defpath = '\\Windows'
98 from ce import *
99 for i in ['_exit']:
100 try:
101 exec "from ce import " + i
102 except ImportError:
103 pass
104 # We can use the standard Windows path.
105 import ntpath
106 path = ntpath
107 del ntpath
Guido van Rossum2979b011994-08-01 11:18:30 +0000108else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000109 raise ImportError, 'no os specific module found'
Guido van Rossume65cce51993-11-08 15:05:21 +0000110
Guido van Rossuma28dab51997-08-29 22:36:47 +0000111del _names
112
Fred Drake02379091999-01-19 16:05:13 +0000113sys.modules['os.path'] = path
114
Guido van Rossum4def7de1998-07-24 20:48:03 +0000115# Super directory utilities.
116# (Inspired by Eric Raymond; the doc strings are mostly his)
117
118def makedirs(name, mode=0777):
119 """makedirs(path [, mode=0777]) -> None
120
121 Super-mkdir; create a leaf directory and all intermediate ones.
122 Works like mkdir, except that any intermediate path segment (not
123 just the rightmost) will be created if it does not exist. This is
124 recursive.
125
126 """
127 head, tail = path.split(name)
128 if head and tail and not path.exists(head):
129 makedirs(head, mode)
130 mkdir(name, mode)
131
132def removedirs(name):
133 """removedirs(path) -> None
134
135 Super-rmdir; remove a leaf directory and empty all intermediate
136 ones. Works like rmdir except that, if the leaf directory is
137 successfully removed, directories corresponding to rightmost path
138 segments will be pruned way until either the whole path is
139 consumed or an error occurs. Errors during this latter phase are
140 ignored -- they generally mean that a directory was not empty.
141
142 """
143 rmdir(name)
144 head, tail = path.split(name)
145 while head and tail:
146 try:
147 rmdir(head)
148 except error:
149 break
150 head, tail = path.split(head)
151
152def renames(old, new):
153 """renames(old, new) -> None
154
155 Super-rename; create directories as necessary and delete any left
156 empty. Works like rename, except creation of any intermediate
157 directories needed to make the new pathname good is attempted
158 first. After the rename, directories corresponding to rightmost
159 path segments of the old name will be pruned way until either the
160 whole path is consumed or a nonempty directory is found.
161
162 Note: this function can fail with the new directory structure made
163 if you lack permissions needed to unlink the leaf directory or
164 file.
165
166 """
167 head, tail = path.split(new)
168 if head and tail and not path.exists(head):
169 makedirs(head)
170 rename(old, new)
171 head, tail = path.split(old)
172 if head and tail:
173 try:
174 removedirs(head)
175 except error:
176 pass
177
Guido van Rossuma28dab51997-08-29 22:36:47 +0000178# Make sure os.environ exists, at least
179try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000180 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000181except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000182 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000183
Guido van Rossume65cce51993-11-08 15:05:21 +0000184def execl(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000185 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000186
187def execle(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000188 env = args[-1]
189 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000190
191def execlp(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000192 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000193
Guido van Rossum030afb11995-03-14 17:27:18 +0000194def execlpe(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000195 env = args[-1]
196 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000197
Guido van Rossume65cce51993-11-08 15:05:21 +0000198def execvp(file, args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000199 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000200
201def execvpe(file, args, env):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000202 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000203
204_notfound = None
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000205def _execvpe(file, args, env=None):
206 if env is not None:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000207 func = execve
208 argrest = (args, env)
209 else:
210 func = execv
211 argrest = (args,)
212 env = environ
213 global _notfound
214 head, tail = path.split(file)
215 if head:
216 apply(func, (file,) + argrest)
217 return
218 if env.has_key('PATH'):
219 envpath = env['PATH']
220 else:
221 envpath = defpath
222 import string
223 PATH = string.splitfields(envpath, pathsep)
224 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 import string
251 class _Environ(UserDict.UserDict):
252 def __init__(self, environ):
253 UserDict.UserDict.__init__(self)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000254 data = self.data
255 upper = string.upper
256 for k, v in environ.items():
257 data[upper(k)] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000258 def __setitem__(self, key, item):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000259 putenv(key, item)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000260 key = string.upper(key)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000261 self.data[key] = item
262 def __getitem__(self, key):
263 return self.data[string.upper(key)]
Guido van Rossumb46413f1999-05-03 15:23:24 +0000264 def has_key(self, key):
265 return self.data.has_key(string.upper(key))
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000266
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000267 else: # Where Env Var Names Can Be Mixed Case
268 class _Environ(UserDict.UserDict):
269 def __init__(self, environ):
270 UserDict.UserDict.__init__(self)
271 self.data = environ
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000272 def __setitem__(self, key, item):
273 putenv(key, item)
274 self.data[key] = item
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000275
276 environ = _Environ(environ)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000277
278def getenv(key, default=None):
279 """Get an environment variable, return None if it doesn't exist.
280
281 The optional second argument can specify an alternative default."""
282 return environ.get(key, default)
283
284def _exists(name):
285 try:
286 eval(name)
287 return 1
288 except NameError:
289 return 0
290
291# Supply spawn*() (probably only for Unix)
292if _exists("fork") and not _exists("spawnv") and _exists("execv"):
293
294 P_WAIT = 0
295 P_NOWAIT = P_NOWAITO = 1
296
297 # XXX Should we support P_DETACH? I suppose it could fork()**2
298 # and close the std I/O streams. Also, P_OVERLAY is the same
299 # as execv*()?
300
301 def _spawnvef(mode, file, args, env, func):
302 # Internal helper; func is the exec*() function to use
303 pid = fork()
304 if not pid:
305 # Child
306 try:
307 if env is None:
308 func(file, args)
309 else:
310 func(file, args, env)
311 except:
312 _exit(127)
313 else:
314 # Parent
315 if mode == P_NOWAIT:
316 return pid # Caller is responsible for waiting!
317 while 1:
318 wpid, sts = waitpid(pid, 0)
319 if WIFSTOPPED(sts):
320 continue
321 elif WIFSIGNALED(sts):
322 return -WTERMSIG(sts)
323 elif WIFEXITED(sts):
324 return WEXITSTATUS(sts)
325 else:
326 raise error, "Not stopped, signaled or exited???"
327
328 def spawnv(mode, file, args):
329 return _spawnvef(mode, file, args, None, execv)
330
331 def spawnve(mode, file, args, env):
332 return _spawnvef(mode, file, args, env, execve)
333
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000334 # Note: spawnvp[e] is't currently supported on Windows
335
336 def spawnvp(mode, file, args):
337 return _spawnvef(mode, file, args, None, execvp)
338
339 def spawnvpe(mode, file, args, env):
340 return _spawnvef(mode, file, args, env, execvpe)
341
342if _exists("spawnv"):
343 # These aren't supplied by the basic Windows code
344 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000345
346 def spawnl(mode, file, *args):
347 return spawnv(mode, file, args)
348
349 def spawnle(mode, file, *args):
350 env = args[-1]
351 return spawnve(mode, file, args[:-1], env)
352
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000353if _exists("spawnvp"):
354 # At the moment, Windows doesn't implement spawnvp[e],
355 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000356 def spawnlp(mode, file, *args):
357 return spawnvp(mode, file, args)
358
359 def spawnlpe(mode, file, *args):
360 env = args[-1]
361 return spawnvpe(mode, file, args[:-1], env)