Quick update to the README file. For intros and books we now point to
[python/dscho.git] / Lib / os.py
blob118b6198bfa201089c234ff1c74a41ca4cec2f35
1 """OS routines for Mac, DOS, NT, or Posix depending on what system we're on.
3 This exports:
4 - 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'
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 alternate pathname separator (None or '/')
11 - os.pathsep is the component separator used in $PATH etc
12 - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
13 - os.defpath is the default search path for executables
15 Programs that import and use 'os' stand a better chance of being
16 portable between different platforms. Of course, they must then
17 only use functions that are defined by all platforms (e.g., unlink
18 and opendir), and leave all pathname manipulation to os.path
19 (e.g., split and join).
20 """
22 import sys
24 _names = sys.builtin_module_names
26 altsep = None
28 if 'posix' in _names:
29 name = 'posix'
30 linesep = '\n'
31 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
41 elif 'nt' in _names:
42 name = 'nt'
43 linesep = '\r\n'
44 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
45 defpath = '.;C:\\bin'
46 from nt import *
47 for i in ['_exit']:
48 try:
49 exec "from nt import " + i
50 except ImportError:
51 pass
52 import ntpath
53 path = ntpath
54 del ntpath
55 elif 'dos' in _names:
56 name = 'dos'
57 linesep = '\r\n'
58 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
68 elif 'os2' in _names:
69 name = 'os2'
70 linesep = '\r\n'
71 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
81 elif 'mac' in _names:
82 name = 'mac'
83 linesep = '\r'
84 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
94 elif '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
109 else:
110 raise ImportError, 'no os specific module found'
112 del _names
114 sys.modules['os.path'] = path
116 # Super directory utilities.
117 # (Inspired by Eric Raymond; the doc strings are mostly his)
119 def makedirs(name, mode=0777):
120 """makedirs(path [, mode=0777]) -> None
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.
128 head, tail = path.split(name)
129 if head and tail and not path.exists(head):
130 makedirs(head, mode)
131 mkdir(name, mode)
133 def removedirs(name):
134 """removedirs(path) -> None
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.
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)
153 def renames(old, new):
154 """renames(old, new) -> None
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.
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.
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
179 # Make sure os.environ exists, at least
180 try:
181 environ
182 except NameError:
183 environ = {}
185 def execl(file, *args):
186 execv(file, args)
188 def execle(file, *args):
189 env = args[-1]
190 execve(file, args[:-1], env)
192 def execlp(file, *args):
193 execvp(file, args)
195 def execlpe(file, *args):
196 env = args[-1]
197 execvpe(file, args[:-1], env)
199 def execvp(file, args):
200 _execvpe(file, args)
202 def execvpe(file, args, env):
203 _execvpe(file, args, env)
205 _notfound = None
206 def _execvpe(file, args, env=None):
207 if env is not None:
208 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
223 import string
224 PATH = string.splitfields(envpath, pathsep)
225 if not _notfound:
226 import tempfile
227 # Exec a file that is guaranteed not to exist
228 try: execv(tempfile.mktemp(), ())
229 except error, _notfound: pass
230 exc, arg = error, _notfound
231 for dir in PATH:
232 fullname = path.join(dir, file)
233 try:
234 apply(func, (fullname,) + argrest)
235 except error, (errno, msg):
236 if errno != arg[0]:
237 exc, arg = error, (errno, msg)
238 raise exc, arg
240 # Change environ to automatically call putenv() if it exists
241 try:
242 # This will fail if there's no putenv
243 putenv
244 except NameError:
245 pass
246 else:
247 import UserDict
249 if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE
250 # But we store them as upper case
251 import string
252 class _Environ(UserDict.UserDict):
253 def __init__(self, environ):
254 UserDict.UserDict.__init__(self)
255 data = self.data
256 upper = string.upper
257 for k, v in environ.items():
258 data[upper(k)] = v
259 def __setitem__(self, key, item):
260 putenv(key, item)
261 key = string.upper(key)
262 self.data[key] = item
263 def __getitem__(self, key):
264 return self.data[string.upper(key)]
265 def has_key(self, key):
266 return self.data.has_key(string.upper(key))
268 else: # Where Env Var Names Can Be Mixed Case
269 class _Environ(UserDict.UserDict):
270 def __init__(self, environ):
271 UserDict.UserDict.__init__(self)
272 self.data = environ
273 def __setitem__(self, key, item):
274 putenv(key, item)
275 self.data[key] = item
277 environ = _Environ(environ)
279 def getenv(key, default=None):
280 """Get an environment variable, return None if it doesn't exist.
282 The optional second argument can specify an alternative default."""
283 return environ.get(key, default)
285 def _exists(name):
286 try:
287 eval(name)
288 return 1
289 except NameError:
290 return 0
292 # Supply spawn*() (probably only for Unix)
293 if _exists("fork") and not _exists("spawnv") and _exists("execv"):
295 P_WAIT = 0
296 P_NOWAIT = P_NOWAITO = 1
298 # XXX Should we support P_DETACH? I suppose it could fork()**2
299 # and close the std I/O streams. Also, P_OVERLAY is the same
300 # as execv*()?
302 def _spawnvef(mode, file, args, env, func):
303 # Internal helper; func is the exec*() function to use
304 pid = fork()
305 if not pid:
306 # Child
307 try:
308 if env is None:
309 func(file, args)
310 else:
311 func(file, args, env)
312 except:
313 _exit(127)
314 else:
315 # Parent
316 if mode == P_NOWAIT:
317 return pid # Caller is responsible for waiting!
318 while 1:
319 wpid, sts = waitpid(pid, 0)
320 if WIFSTOPPED(sts):
321 continue
322 elif WIFSIGNALED(sts):
323 return -WTERMSIG(sts)
324 elif WIFEXITED(sts):
325 return WEXITSTATUS(sts)
326 else:
327 raise error, "Not stopped, signaled or exited???"
329 def spawnv(mode, file, args):
330 return _spawnvef(mode, file, args, None, execv)
332 def spawnve(mode, file, args, env):
333 return _spawnvef(mode, file, args, env, execve)
335 # Note: spawnvp[e] is't currently supported on Windows
337 def spawnvp(mode, file, args):
338 return _spawnvef(mode, file, args, None, execvp)
340 def spawnvpe(mode, file, args, env):
341 return _spawnvef(mode, file, args, env, execvpe)
343 if _exists("spawnv"):
344 # These aren't supplied by the basic Windows code
345 # but can be easily implemented in Python
347 def spawnl(mode, file, *args):
348 return spawnv(mode, file, args)
350 def spawnle(mode, file, *args):
351 env = args[-1]
352 return spawnve(mode, file, args[:-1], env)
354 if _exists("spawnvp"):
355 # At the moment, Windows doesn't implement spawnvp[e],
356 # so it won't have spawnlp[e] either.
357 def spawnlp(mode, file, *args):
358 return spawnvp(mode, file, args)
360 def spawnlpe(mode, file, *args):
361 env = args[-1]
362 return spawnvpe(mode, file, args[:-1], env)