os.py revision e0cd291b8123859191cbef90316d55b39e4ce3a1
1"""OS routines for Mac, DOS, NT, or Posix depending on what system we're on. 2 3This 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 14 15Programs 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""" 21 22import sys 23 24_names = sys.builtin_module_names 25 26altsep = None 27 28if '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 41elif '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 55elif '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 68elif '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 81elif '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 94elif '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 109else: 110 raise ImportError, 'no os specific module found' 111 112del _names 113 114sys.modules['os.path'] = path 115 116# 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 179# Make sure os.environ exists, at least 180try: 181 environ 182except NameError: 183 environ = {} 184 185def execl(file, *args): 186 execv(file, args) 187 188def execle(file, *args): 189 env = args[-1] 190 execve(file, args[:-1], env) 191 192def execlp(file, *args): 193 execvp(file, args) 194 195def execlpe(file, *args): 196 env = args[-1] 197 execvpe(file, args[:-1], env) 198 199def execvp(file, args): 200 _execvpe(file, args) 201 202def execvpe(file, args, env): 203 _execvpe(file, args, env) 204 205_notfound = None 206def _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 PATH = envpath.split(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 238 239# Change environ to automatically call putenv() if it exists 240try: 241 # This will fail if there's no putenv 242 putenv 243except NameError: 244 pass 245else: 246 import UserDict 247 248 if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE 249 # But we store them as upper case 250 class _Environ(UserDict.UserDict): 251 def __init__(self, environ): 252 UserDict.UserDict.__init__(self) 253 data = self.data 254 for k, v in environ.items(): 255 data[k.upper()] = v 256 def __setitem__(self, key, item): 257 putenv(key, item) 258 self.data[key.upper()] = item 259 def __getitem__(self, key): 260 return self.data[key.upper()] 261 def __delitem__(self, key): 262 del self.data[key.upper()] 263 def has_key(self, key): 264 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 270 271 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 276 def __setitem__(self, key, item): 277 putenv(key, item) 278 self.data[key] = item 279 def update(self, dict): 280 for k, v in dict.items(): 281 self[k] = v 282 283 environ = _Environ(environ) 284 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): 336 """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). """ 342 return _spawnvef(mode, file, args, None, execv) 343 344 def spawnve(mode, file, args, env): 345 """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. """ 352 return _spawnvef(mode, file, args, env, execve) 353 354 # Note: spawnvp[e] is't currently supported on Windows 355 356 def spawnvp(mode, file, args): 357 """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. """ 364 return _spawnvef(mode, file, args, None, execvp) 365 366 def spawnvpe(mode, file, args, env): 367 """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. """ 374 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 379 380 def spawnl(mode, file, *args): 381 """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. """ 387 return spawnv(mode, file, args) 388 389 def spawnle(mode, file, *args): 390 """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. """ 397 env = args[-1] 398 return spawnve(mode, file, args[:-1], env) 399 400if _exists("spawnvp"): 401 # At the moment, Windows doesn't implement spawnvp[e], 402 # so it won't have spawnlp[e] either. 403 def spawnlp(mode, file, *args): 404 """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. """ 411 return spawnvp(mode, file, args) 412 413 def spawnlpe(mode, file, *args): 414 """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. """ 421 env = args[-1] 422 return spawnvpe(mode, file, args[:-1], env) 423 424 425