blob: 28ed3cfff1e858c21fcf31d6d655224f957a7faf [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 *
45 try:
46 from nt import _exit
47 except ImportError:
48 pass
49 import ntpath
50 path = ntpath
51 del ntpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000052elif 'dos' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000053 name = 'dos'
Guido van Rossume9387ea1998-05-22 15:26:04 +000054 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000055 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
56 defpath = '.;C:\\bin'
57 from dos import *
58 try:
59 from dos import _exit
60 except ImportError:
61 pass
62 import dospath
63 path = dospath
64 del dospath
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000065elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000066 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000067 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000068 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
69 defpath = '.;C:\\bin'
70 from os2 import *
71 try:
72 from os2 import _exit
73 except ImportError:
74 pass
75 import ntpath
76 path = ntpath
77 del ntpath
Guido van Rossuma28dab51997-08-29 22:36:47 +000078elif 'mac' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000079 name = 'mac'
Guido van Rossume9387ea1998-05-22 15:26:04 +000080 linesep = '\r'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000081 curdir = ':'; pardir = '::'; sep = ':'; pathsep = '\n'
82 defpath = ':'
83 from mac import *
84 try:
85 from mac import _exit
86 except ImportError:
87 pass
88 import macpath
89 path = macpath
90 del macpath
Guido van Rossum2979b011994-08-01 11:18:30 +000091else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000092 raise ImportError, 'no os specific module found'
Guido van Rossume65cce51993-11-08 15:05:21 +000093
Guido van Rossuma28dab51997-08-29 22:36:47 +000094del _names
95
Guido van Rossum4def7de1998-07-24 20:48:03 +000096# Super directory utilities.
97# (Inspired by Eric Raymond; the doc strings are mostly his)
98
99def makedirs(name, mode=0777):
100 """makedirs(path [, mode=0777]) -> None
101
102 Super-mkdir; create a leaf directory and all intermediate ones.
103 Works like mkdir, except that any intermediate path segment (not
104 just the rightmost) will be created if it does not exist. This is
105 recursive.
106
107 """
108 head, tail = path.split(name)
109 if head and tail and not path.exists(head):
110 makedirs(head, mode)
111 mkdir(name, mode)
112
113def removedirs(name):
114 """removedirs(path) -> None
115
116 Super-rmdir; remove a leaf directory and empty all intermediate
117 ones. Works like rmdir except that, if the leaf directory is
118 successfully removed, directories corresponding to rightmost path
119 segments will be pruned way until either the whole path is
120 consumed or an error occurs. Errors during this latter phase are
121 ignored -- they generally mean that a directory was not empty.
122
123 """
124 rmdir(name)
125 head, tail = path.split(name)
126 while head and tail:
127 try:
128 rmdir(head)
129 except error:
130 break
131 head, tail = path.split(head)
132
133def renames(old, new):
134 """renames(old, new) -> None
135
136 Super-rename; create directories as necessary and delete any left
137 empty. Works like rename, except creation of any intermediate
138 directories needed to make the new pathname good is attempted
139 first. After the rename, directories corresponding to rightmost
140 path segments of the old name will be pruned way until either the
141 whole path is consumed or a nonempty directory is found.
142
143 Note: this function can fail with the new directory structure made
144 if you lack permissions needed to unlink the leaf directory or
145 file.
146
147 """
148 head, tail = path.split(new)
149 if head and tail and not path.exists(head):
150 makedirs(head)
151 rename(old, new)
152 head, tail = path.split(old)
153 if head and tail:
154 try:
155 removedirs(head)
156 except error:
157 pass
158
Guido van Rossuma28dab51997-08-29 22:36:47 +0000159# Make sure os.environ exists, at least
160try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000161 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000162except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000163 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000164
Guido van Rossume65cce51993-11-08 15:05:21 +0000165def execl(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000166 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000167
168def execle(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000169 env = args[-1]
170 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000171
172def execlp(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000173 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000174
Guido van Rossum030afb11995-03-14 17:27:18 +0000175def execlpe(file, *args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000176 env = args[-1]
177 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000178
Guido van Rossume65cce51993-11-08 15:05:21 +0000179def execvp(file, args):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000180 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000181
182def execvpe(file, args, env):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000183 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000184
185_notfound = None
186def _execvpe(file, args, env = None):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000187 if env:
188 func = execve
189 argrest = (args, env)
190 else:
191 func = execv
192 argrest = (args,)
193 env = environ
194 global _notfound
195 head, tail = path.split(file)
196 if head:
197 apply(func, (file,) + argrest)
198 return
199 if env.has_key('PATH'):
200 envpath = env['PATH']
201 else:
202 envpath = defpath
203 import string
204 PATH = string.splitfields(envpath, pathsep)
205 if not _notfound:
206 import tempfile
207 # Exec a file that is guaranteed not to exist
208 try: execv(tempfile.mktemp(), ())
209 except error, _notfound: pass
210 exc, arg = error, _notfound
211 for dir in PATH:
212 fullname = path.join(dir, file)
213 try:
214 apply(func, (fullname,) + argrest)
215 except error, (errno, msg):
216 if errno != arg[0]:
217 exc, arg = error, (errno, msg)
218 raise exc, arg
Guido van Rossum2979b011994-08-01 11:18:30 +0000219
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000220# Change environ to automatically call putenv() if it exists
221try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000222 # This will fail if there's no putenv
223 putenv
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000224except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000225 pass
Guido van Rossuma28dab51997-08-29 22:36:47 +0000226else:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000227 import UserDict
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000228
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000229 if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE
230 # But we store them as upper case
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000231 import string
232 class _Environ(UserDict.UserDict):
233 def __init__(self, environ):
234 UserDict.UserDict.__init__(self)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000235 data = self.data
236 upper = string.upper
237 for k, v in environ.items():
238 data[upper(k)] = v
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000239 def __setitem__(self, key, item):
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000240 putenv(key, item)
Guido van Rossumda4d6da1998-08-04 16:01:23 +0000241 key = string.upper(key)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000242 self.data[key] = item
243 def __getitem__(self, key):
244 return self.data[string.upper(key)]
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000245
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000246 else: # Where Env Var Names Can Be Mixed Case
247 class _Environ(UserDict.UserDict):
248 def __init__(self, environ):
249 UserDict.UserDict.__init__(self)
250 self.data = environ
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000251 def __setitem__(self, key, item):
252 putenv(key, item)
253 self.data[key] = item
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000254
255 environ = _Environ(environ)