blob: 057c101095c889dd2cf8728dc702d1373f775a1e [file] [log] [blame]
Guido van Rossumdd8cb441993-12-29 15:33:08 +00001# os.py -- either mac, dos or posix depending on what system we're on.
Guido van Rossum31104f41992-01-14 18:28:36 +00002
3# This exports:
4# - all functions from either posix or mac, e.g., os.unlink, os.stat, etc.
Guido van Rossum1a76ef21992-03-31 18:57:28 +00005# - os.path is either module posixpath or macpath
Guido van Rossum31104f41992-01-14 18:28:36 +00006# - os.name is either 'posix' or 'mac'
7# - os.curdir is a string representing the current directory ('.' or ':')
Guido van Rossum1a76ef21992-03-31 18:57:28 +00008# - os.pardir is a string representing the parent directory ('..' or '::')
Guido van Rossuma28dab51997-08-29 22:36:47 +00009# - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
10# - os.altsep is the alternatte pathname separator (None or '/')
Guido van Rossum2979b011994-08-01 11:18:30 +000011# - 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
14# Programs that import and use 'os' stand a better chance of being
15# portable between different platforms. Of course, they must then
16# only use functions that are defined by all platforms (e.g., unlink
17# and opendir), and leave all pathname manipulation to os.path
18# (e.g., split and join).
19
Guido van Rossum2979b011994-08-01 11:18:30 +000020import sys
Guido van Rossuma28dab51997-08-29 22:36:47 +000021
22_names = sys.builtin_module_names
23
24altsep = None
25
26if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000027 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000028 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000029 curdir = '.'; pardir = '..'; sep = '/'; pathsep = ':'
30 defpath = ':/bin:/usr/bin'
31 from posix import *
32 try:
33 from posix import _exit
34 except ImportError:
35 pass
36 import posixpath
37 path = posixpath
38 del posixpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000039elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000040 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000041 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000042 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
43 defpath = '.;C:\\bin'
44 from nt import *
Guido van Rossumfb801e71999-02-22 15:40:34 +000045 for i in ['_exit']:
Guido van Rossum67c65b21999-02-01 23:52:29 +000046 try:
47 exec "from nt import " + i
48 except ImportError:
49 pass
Guido van Rossum61de0ac1997-12-05 21:24:30 +000050 import ntpath
51 path = ntpath
52 del ntpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000053elif 'dos' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000054 name = 'dos'
Guido van Rossume9387ea1998-05-22 15:26:04 +000055 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000056 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
57 defpath = '.;C:\\bin'
58 from dos import *
59 try:
60 from dos import _exit
61 except ImportError:
62 pass
63 import dospath
64 path = dospath
65 del dospath
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000066elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000067 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000068 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000069 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
70 defpath = '.;C:\\bin'
71 from os2 import *
72 try:
73 from os2 import _exit
74 except ImportError:
75 pass
76 import ntpath
77 path = ntpath
78 del ntpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000079elif 'mac' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000080 name = 'mac'
Guido van Rossume9387ea1998-05-22 15:26:04 +000081 linesep = '\r'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000082 curdir = ':'; pardir = '::'; sep = ':'; pathsep = '\n'
83 defpath = ':'
84 from mac import *
85 try:
86 from mac import _exit
87 except ImportError:
88 pass
89 import macpath
90 path = macpath
91 del macpath
Guido van Rossum18df5d41999-06-11 01:37:27 +000092elif 'ce' in _names:
93 name = 'ce'
94 linesep = '\r\n'
95 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
96 defpath = '\\Windows'
97 from ce import *
98 for i in ['_exit']:
99 try:
100 exec "from ce import " + i
101 except ImportError:
102 pass
103 # We can use the standard Windows path.
104 import ntpath
105 path = ntpath
106 del ntpath
Guido van Rossum2979b011994-08-01 11:18:30 +0000107else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000108 raise ImportError, 'no os specific module found'
Guido van Rossume65cce51993-11-08 15:05:21 +0000109
Guido van Rossuma28dab51997-08-29 22:36:47 +0000110del _names
111
Fred Drake02379091999-01-19 16:05:13 +0000112sys.modules['os.path'] = path
113
Guido van Rossum4def7de1998-07-24 20:48:03 +0000114# Super directory utilities.
115# (Inspired by Eric Raymond; the doc strings are mostly his)
116
117def makedirs(name, mode=0777):
118 """makedirs(path [, mode=0777]) -> None
119
120 Super-mkdir; create a leaf directory and all intermediate ones.
121 Works like mkdir, except that any intermediate path segment (not
122 just the rightmost) will be created if it does not exist. This is
123 recursive.
124
125 """
126 head, tail = path.split(name)
127 if head and tail and not path.exists(head):
128 makedirs(head, mode)
129 mkdir(name, mode)
130
131def removedirs(name):
132 """removedirs(path) -> None
133
134 Super-rmdir; remove a leaf directory and empty all intermediate
135 ones. Works like rmdir except that, if the leaf directory is
136 successfully removed, directories corresponding to rightmost path
137 segments will be pruned way until either the whole path is
138 consumed or an error occurs. Errors during this latter phase are
139 ignored -- they generally mean that a directory was not empty.
140
141 """
142 rmdir(name)
143 head, tail = path.split(name)
144 while head and tail:
145 try:
146 rmdir(head)
147 except error:
148 break
149 head, tail = path.split(head)
150
151def renames(old, new):
152 """renames(old, new) -> None
153
154 Super-rename; create directories as necessary and delete any left
155 empty. Works like rename, except creation of any intermediate
156 directories needed to make the new pathname good is attempted
157 first. After the rename, directories corresponding to rightmost
158 path segments of the old name will be pruned way until either the
159 whole path is consumed or a nonempty directory is found.
160
161 Note: this function can fail with the new directory structure made
162 if you lack permissions needed to unlink the leaf directory or
163 file.
164
165 """
166 head, tail = path.split(new)
167 if head and tail and not path.exists(head):
168 makedirs(head)
169 rename(old, new)
170 head, tail = path.split(old)
171 if head and tail:
172 try:
173 removedirs(head)
174 except error:
175 pass
176
Guido van Rossuma28dab51997-08-29 22:36:47 +0000177# Make sure os.environ exists, at least
178try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000179 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000180except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000181 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000182
Guido van Rossume65cce51993-11-08 15:05:21 +0000183def execl(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000184 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000185
186def execle(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000187 env = args[-1]
188 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000189
190def execlp(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000191 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000192
Guido van Rossum030afb11995-03-14 17:27:18 +0000193def execlpe(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000194 env = args[-1]
195 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000196
Guido van Rossume65cce51993-11-08 15:05:21 +0000197def execvp(file, args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000198 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000199
200def execvpe(file, args, env):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000201 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000202
203_notfound = None
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000204def _execvpe(file, args, env=None):
205 if env is not None:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000206 func = execve
207 argrest = (args, env)
208 else:
209 func = execv
210 argrest = (args,)
211 env = environ
212 global _notfound
213 head, tail = path.split(file)
214 if head:
215 apply(func, (file,) + argrest)
216 return
217 if env.has_key('PATH'):
218 envpath = env['PATH']
219 else:
220 envpath = defpath
221 import string
222 PATH = string.splitfields(envpath, pathsep)
223 if not _notfound:
224 import tempfile
225 # Exec a file that is guaranteed not to exist
226 try: execv(tempfile.mktemp(), ())
227 except error, _notfound: pass
228 exc, arg = error, _notfound
229 for dir in PATH:
230 fullname = path.join(dir, file)
231 try:
232 apply(func, (fullname,) + argrest)
233 except error, (errno, msg):
234 if errno != arg[0]:
235 exc, arg = error, (errno, msg)
236 raise exc, arg
Guido van Rossum2979b011994-08-01 11:18:30 +0000237
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000238# Change environ to automatically call putenv() if it exists
239try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000240 # This will fail if there's no putenv
241 putenv
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000242except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000243 pass
Guido van Rossuma28dab51997-08-29 22:36:47 +0000244else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000245 import UserDict
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000246
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000247 if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE
248 # But we store them as upper case
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000249 import string
250 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
254 upper = string.upper
255 for k, v in environ.items():
256 data[upper(k)] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000257 def __setitem__(self, key, item):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000258 putenv(key, item)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000259 key = string.upper(key)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000260 self.data[key] = item
261 def __getitem__(self, key):
262 return self.data[string.upper(key)]
Guido van Rossumb46413f1999-05-03 15:23:24 +0000263 def has_key(self, key):
264 return self.data.has_key(string.upper(key))
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000265
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000266 else: # Where Env Var Names Can Be Mixed Case
267 class _Environ(UserDict.UserDict):
268 def __init__(self, environ):
269 UserDict.UserDict.__init__(self)
270 self.data = environ
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000271 def __setitem__(self, key, item):
272 putenv(key, item)
273 self.data[key] = item
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000274
275 environ = _Environ(environ)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000276
277def getenv(key, default=None):
278 """Get an environment variable, return None if it doesn't exist.
279
280 The optional second argument can specify an alternative default."""
281 return environ.get(key, default)
282
283def _exists(name):
284 try:
285 eval(name)
286 return 1
287 except NameError:
288 return 0
289
290# Supply spawn*() (probably only for Unix)
291if _exists("fork") and not _exists("spawnv") and _exists("execv"):
292
293 P_WAIT = 0
294 P_NOWAIT = P_NOWAITO = 1
295
296 # XXX Should we support P_DETACH? I suppose it could fork()**2
297 # and close the std I/O streams. Also, P_OVERLAY is the same
298 # as execv*()?
299
300 def _spawnvef(mode, file, args, env, func):
301 # Internal helper; func is the exec*() function to use
302 pid = fork()
303 if not pid:
304 # Child
305 try:
306 if env is None:
307 func(file, args)
308 else:
309 func(file, args, env)
310 except:
311 _exit(127)
312 else:
313 # Parent
314 if mode == P_NOWAIT:
315 return pid # Caller is responsible for waiting!
316 while 1:
317 wpid, sts = waitpid(pid, 0)
318 if WIFSTOPPED(sts):
319 continue
320 elif WIFSIGNALED(sts):
321 return -WTERMSIG(sts)
322 elif WIFEXITED(sts):
323 return WEXITSTATUS(sts)
324 else:
325 raise error, "Not stopped, signaled or exited???"
326
327 def spawnv(mode, file, args):
328 return _spawnvef(mode, file, args, None, execv)
329
330 def spawnve(mode, file, args, env):
331 return _spawnvef(mode, file, args, env, execve)
332
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000333 # Note: spawnvp[e] is't currently supported on Windows
334
335 def spawnvp(mode, file, args):
336 return _spawnvef(mode, file, args, None, execvp)
337
338 def spawnvpe(mode, file, args, env):
339 return _spawnvef(mode, file, args, env, execvpe)
340
341if _exists("spawnv"):
342 # These aren't supplied by the basic Windows code
343 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000344
345 def spawnl(mode, file, *args):
346 return spawnv(mode, file, args)
347
348 def spawnle(mode, file, *args):
349 env = args[-1]
350 return spawnve(mode, file, args[:-1], env)
351
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000352if _exists("spawnvp"):
353 # At the moment, Windows doesn't implement spawnvp[e],
354 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000355 def spawnlp(mode, file, *args):
356 return spawnvp(mode, file, args)
357
358 def spawnlpe(mode, file, *args):
359 env = args[-1]
360 return spawnvpe(mode, file, args[:-1], env)