os.py revision 31017aed36a5c5b0e4b16ca58bea09c9ce360134
1r"""OS routines for Mac, DOS, NT, or Posix depending on what system we're on. 2 3This exports: 4 - all functions from posix, nt, os2, mac, or ce, e.g. unlink, stat, etc. 5 - os.path is one of the modules posixpath, ntpath, or macpath 6 - os.name is 'posix', 'nt', 'os2', 'mac', 'ce' or 'riscos' 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.extsep is the extension separator ('.' or '/') 11 - os.altsep is the alternate pathname separator (None or '/') 12 - os.pathsep is the component separator used in $PATH etc 13 - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n') 14 - os.defpath is the default search path for executables 15 16Programs that import and use 'os' stand a better chance of being 17portable between different platforms. Of course, they must then 18only use functions that are defined by all platforms (e.g., unlink 19and opendir), and leave all pathname manipulation to os.path 20(e.g., split and join). 21""" 22 23#' 24 25import sys 26 27_names = sys.builtin_module_names 28 29# Note: more names are added to __all__ later. 30__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", 31 "defpath", "name", "path"] 32 33def _get_exports_list(module): 34 try: 35 return list(module.__all__) 36 except AttributeError: 37 return [n for n in dir(module) if n[0] != '_'] 38 39if 'posix' in _names: 40 name = 'posix' 41 linesep = '\n' 42 from posix import * 43 try: 44 from posix import _exit 45 except ImportError: 46 pass 47 import posixpath as path 48 49 import posix 50 __all__.extend(_get_exports_list(posix)) 51 del posix 52 53elif 'nt' in _names: 54 name = 'nt' 55 linesep = '\r\n' 56 from nt import * 57 try: 58 from nt import _exit 59 except ImportError: 60 pass 61 import ntpath as path 62 63 import nt 64 __all__.extend(_get_exports_list(nt)) 65 del nt 66 67elif 'os2' in _names: 68 name = 'os2' 69 linesep = '\r\n' 70 from os2 import * 71 try: 72 from os2 import _exit 73 except ImportError: 74 pass 75 if sys.version.find('EMX GCC') == -1: 76 import ntpath as path 77 else: 78 import os2emxpath as path 79 from _emx_link import link 80 81 import os2 82 __all__.extend(_get_exports_list(os2)) 83 del os2 84 85elif 'mac' in _names: 86 name = 'mac' 87 linesep = '\r' 88 from mac import * 89 try: 90 from mac import _exit 91 except ImportError: 92 pass 93 import macpath as path 94 95 import mac 96 __all__.extend(_get_exports_list(mac)) 97 del mac 98 99elif 'ce' in _names: 100 name = 'ce' 101 linesep = '\r\n' 102 from ce import * 103 try: 104 from ce import _exit 105 except ImportError: 106 pass 107 # We can use the standard Windows path. 108 import ntpath as path 109 110 import ce 111 __all__.extend(_get_exports_list(ce)) 112 del ce 113 114elif 'riscos' in _names: 115 name = 'riscos' 116 linesep = '\n' 117 from riscos import * 118 try: 119 from riscos import _exit 120 except ImportError: 121 pass 122 import riscospath as path 123 124 import riscos 125 __all__.extend(_get_exports_list(riscos)) 126 del riscos 127 128else: 129 raise ImportError, 'no os specific module found' 130 131sys.modules['os.path'] = path 132from os.path import curdir, pardir, sep, pathsep, defpath, extsep, altsep 133 134del _names 135 136#' 137 138# Super directory utilities. 139# (Inspired by Eric Raymond; the doc strings are mostly his) 140 141def makedirs(name, mode=0777): 142 """makedirs(path [, mode=0777]) 143 144 Super-mkdir; create a leaf directory and all intermediate ones. 145 Works like mkdir, except that any intermediate path segment (not 146 just the rightmost) will be created if it does not exist. This is 147 recursive. 148 149 """ 150 head, tail = path.split(name) 151 if not tail: 152 head, tail = path.split(head) 153 if head and tail and not path.exists(head): 154 makedirs(head, mode) 155 if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists 156 return 157 mkdir(name, mode) 158 159def removedirs(name): 160 """removedirs(path) 161 162 Super-rmdir; remove a leaf directory and empty all intermediate 163 ones. Works like rmdir except that, if the leaf directory is 164 successfully removed, directories corresponding to rightmost path 165 segments will be pruned away until either the whole path is 166 consumed or an error occurs. Errors during this latter phase are 167 ignored -- they generally mean that a directory was not empty. 168 169 """ 170 rmdir(name) 171 head, tail = path.split(name) 172 if not tail: 173 head, tail = path.split(head) 174 while head and tail: 175 try: 176 rmdir(head) 177 except error: 178 break 179 head, tail = path.split(head) 180 181def renames(old, new): 182 """renames(old, new) 183 184 Super-rename; create directories as necessary and delete any left 185 empty. Works like rename, except creation of any intermediate 186 directories needed to make the new pathname good is attempted 187 first. After the rename, directories corresponding to rightmost 188 path segments of the old name will be pruned way until either the 189 whole path is consumed or a nonempty directory is found. 190 191 Note: this function can fail with the new directory structure made 192 if you lack permissions needed to unlink the leaf directory or 193 file. 194 195 """ 196 head, tail = path.split(new) 197 if head and tail and not path.exists(head): 198 makedirs(head) 199 rename(old, new) 200 head, tail = path.split(old) 201 if head and tail: 202 try: 203 removedirs(head) 204 except error: 205 pass 206 207__all__.extend(["makedirs", "removedirs", "renames"]) 208 209def walk(top, topdown=True, onerror=None): 210 """Directory tree generator. 211 212 For each directory in the directory tree rooted at top (including top 213 itself, but excluding '.' and '..'), yields a 3-tuple 214 215 dirpath, dirnames, filenames 216 217 dirpath is a string, the path to the directory. dirnames is a list of 218 the names of the subdirectories in dirpath (excluding '.' and '..'). 219 filenames is a list of the names of the non-directory files in dirpath. 220 Note that the names in the lists are just names, with no path components. 221 To get a full path (which begins with top) to a file or directory in 222 dirpath, do os.path.join(dirpath, name). 223 224 If optional arg 'topdown' is true or not specified, the triple for a 225 directory is generated before the triples for any of its subdirectories 226 (directories are generated top down). If topdown is false, the triple 227 for a directory is generated after the triples for all of its 228 subdirectories (directories are generated bottom up). 229 230 When topdown is true, the caller can modify the dirnames list in-place 231 (e.g., via del or slice assignment), and walk will only recurse into the 232 subdirectories whose names remain in dirnames; this can be used to prune 233 the search, or to impose a specific order of visiting. Modifying 234 dirnames when topdown is false is ineffective, since the directories in 235 dirnames have already been generated by the time dirnames itself is 236 generated. 237 238 By default errors from the os.listdir() call are ignored. If 239 optional arg 'onerror' is specified, it should be a function; it 240 will be called with one argument, an os.error instance. It can 241 report the error to continue with the walk, or raise the exception 242 to abort the walk. Note that the filename is available as the 243 filename attribute of the exception object. 244 245 Caution: if you pass a relative pathname for top, don't change the 246 current working directory between resumptions of walk. walk never 247 changes the current directory, and assumes that the client doesn't 248 either. 249 250 Example: 251 252 from os.path import join, getsize 253 for root, dirs, files in walk('python/Lib/email'): 254 print root, "consumes", 255 print sum([getsize(join(root, name)) for name in files]), 256 print "bytes in", len(files), "non-directory files" 257 if 'CVS' in dirs: 258 dirs.remove('CVS') # don't visit CVS directories 259 """ 260 261 from os.path import join, isdir, islink 262 263 # We may not have read permission for top, in which case we can't 264 # get a list of the files the directory contains. os.path.walk 265 # always suppressed the exception then, rather than blow up for a 266 # minor reason when (say) a thousand readable directories are still 267 # left to visit. That logic is copied here. 268 try: 269 # Note that listdir and error are globals in this module due 270 # to earlier import-*. 271 names = listdir(top) 272 except error, err: 273 if onerror is not None: 274 onerror(err) 275 return 276 277 dirs, nondirs = [], [] 278 for name in names: 279 if isdir(join(top, name)): 280 dirs.append(name) 281 else: 282 nondirs.append(name) 283 284 if topdown: 285 yield top, dirs, nondirs 286 for name in dirs: 287 path = join(top, name) 288 if not islink(path): 289 for x in walk(path, topdown, onerror): 290 yield x 291 if not topdown: 292 yield top, dirs, nondirs 293 294__all__.append("walk") 295 296# Make sure os.environ exists, at least 297try: 298 environ 299except NameError: 300 environ = {} 301 302def execl(file, *args): 303 """execl(file, *args) 304 305 Execute the executable file with argument list args, replacing the 306 current process. """ 307 execv(file, args) 308 309def execle(file, *args): 310 """execle(file, *args, env) 311 312 Execute the executable file with argument list args and 313 environment env, replacing the current process. """ 314 env = args[-1] 315 execve(file, args[:-1], env) 316 317def execlp(file, *args): 318 """execlp(file, *args) 319 320 Execute the executable file (which is searched for along $PATH) 321 with argument list args, replacing the current process. """ 322 execvp(file, args) 323 324def execlpe(file, *args): 325 """execlpe(file, *args, env) 326 327 Execute the executable file (which is searched for along $PATH) 328 with argument list args and environment env, replacing the current 329 process. """ 330 env = args[-1] 331 execvpe(file, args[:-1], env) 332 333def execvp(file, args): 334 """execp(file, args) 335 336 Execute the executable file (which is searched for along $PATH) 337 with argument list args, replacing the current process. 338 args may be a list or tuple of strings. """ 339 _execvpe(file, args) 340 341def execvpe(file, args, env): 342 """execvpe(file, args, env) 343 344 Execute the executable file (which is searched for along $PATH) 345 with argument list args and environment env , replacing the 346 current process. 347 args may be a list or tuple of strings. """ 348 _execvpe(file, args, env) 349 350__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"]) 351 352def _execvpe(file, args, env=None): 353 from errno import ENOENT, ENOTDIR 354 355 if env is not None: 356 func = execve 357 argrest = (args, env) 358 else: 359 func = execv 360 argrest = (args,) 361 env = environ 362 363 head, tail = path.split(file) 364 if head: 365 func(file, *argrest) 366 return 367 if 'PATH' in env: 368 envpath = env['PATH'] 369 else: 370 envpath = defpath 371 PATH = envpath.split(pathsep) 372 saved_exc = None 373 saved_tb = None 374 for dir in PATH: 375 fullname = path.join(dir, file) 376 try: 377 func(fullname, *argrest) 378 except error, e: 379 tb = sys.exc_info()[2] 380 if (e.errno != ENOENT and e.errno != ENOTDIR 381 and saved_exc is None): 382 saved_exc = e 383 saved_tb = tb 384 if saved_exc: 385 raise error, saved_exc, saved_tb 386 raise error, e, tb 387 388# Change environ to automatically call putenv() if it exists 389try: 390 # This will fail if there's no putenv 391 putenv 392except NameError: 393 pass 394else: 395 import UserDict 396 397 # Fake unsetenv() for Windows 398 # not sure about os2 here but 399 # I'm guessing they are the same. 400 401 if name in ('os2', 'nt'): 402 def unsetenv(key): 403 putenv(key, "") 404 405 if name == "riscos": 406 # On RISC OS, all env access goes through getenv and putenv 407 from riscosenviron import _Environ 408 elif name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE 409 # But we store them as upper case 410 class _Environ(UserDict.IterableUserDict): 411 def __init__(self, environ): 412 UserDict.UserDict.__init__(self) 413 data = self.data 414 for k, v in environ.items(): 415 data[k.upper()] = v 416 def __setitem__(self, key, item): 417 putenv(key, item) 418 self.data[key.upper()] = item 419 def __getitem__(self, key): 420 return self.data[key.upper()] 421 try: 422 unsetenv 423 except NameError: 424 def __delitem__(self, key): 425 del self.data[key.upper()] 426 else: 427 def __delitem__(self, key): 428 unsetenv(key) 429 del self.data[key.upper()] 430 def has_key(self, key): 431 return key.upper() in self.data 432 def __contains__(self, key): 433 return key.upper() in self.data 434 def get(self, key, failobj=None): 435 return self.data.get(key.upper(), failobj) 436 def copy(self): 437 return dict(self) 438 439 else: # Where Env Var Names Can Be Mixed Case 440 class _Environ(UserDict.IterableUserDict): 441 def __init__(self, environ): 442 UserDict.UserDict.__init__(self) 443 self.data = environ 444 def __setitem__(self, key, item): 445 putenv(key, item) 446 self.data[key] = item 447 try: 448 unsetenv 449 except NameError: 450 pass 451 else: 452 def __delitem__(self, key): 453 unsetenv(key) 454 del self.data[key] 455 def copy(self): 456 return dict(self) 457 458 459 environ = _Environ(environ) 460 461def getenv(key, default=None): 462 """Get an environment variable, return None if it doesn't exist. 463 The optional second argument can specify an alternate default.""" 464 return environ.get(key, default) 465__all__.append("getenv") 466 467def _exists(name): 468 try: 469 eval(name) 470 return True 471 except NameError: 472 return False 473 474# Supply spawn*() (probably only for Unix) 475if _exists("fork") and not _exists("spawnv") and _exists("execv"): 476 477 P_WAIT = 0 478 P_NOWAIT = P_NOWAITO = 1 479 480 # XXX Should we support P_DETACH? I suppose it could fork()**2 481 # and close the std I/O streams. Also, P_OVERLAY is the same 482 # as execv*()? 483 484 def _spawnvef(mode, file, args, env, func): 485 # Internal helper; func is the exec*() function to use 486 pid = fork() 487 if not pid: 488 # Child 489 try: 490 if env is None: 491 func(file, args) 492 else: 493 func(file, args, env) 494 except: 495 _exit(127) 496 else: 497 # Parent 498 if mode == P_NOWAIT: 499 return pid # Caller is responsible for waiting! 500 while 1: 501 wpid, sts = waitpid(pid, 0) 502 if WIFSTOPPED(sts): 503 continue 504 elif WIFSIGNALED(sts): 505 return -WTERMSIG(sts) 506 elif WIFEXITED(sts): 507 return WEXITSTATUS(sts) 508 else: 509 raise error, "Not stopped, signaled or exited???" 510 511 def spawnv(mode, file, args): 512 """spawnv(mode, file, args) -> integer 513 514Execute file with arguments from args in a subprocess. 515If mode == P_NOWAIT return the pid of the process. 516If mode == P_WAIT return the process's exit code if it exits normally; 517otherwise return -SIG, where SIG is the signal that killed it. """ 518 return _spawnvef(mode, file, args, None, execv) 519 520 def spawnve(mode, file, args, env): 521 """spawnve(mode, file, args, env) -> integer 522 523Execute file with arguments from args in a subprocess with the 524specified environment. 525If mode == P_NOWAIT return the pid of the process. 526If mode == P_WAIT return the process's exit code if it exits normally; 527otherwise return -SIG, where SIG is the signal that killed it. """ 528 return _spawnvef(mode, file, args, env, execve) 529 530 # Note: spawnvp[e] is't currently supported on Windows 531 532 def spawnvp(mode, file, args): 533 """spawnvp(mode, file, args) -> integer 534 535Execute file (which is looked for along $PATH) with arguments from 536args in a subprocess. 537If mode == P_NOWAIT return the pid of the process. 538If mode == P_WAIT return the process's exit code if it exits normally; 539otherwise return -SIG, where SIG is the signal that killed it. """ 540 return _spawnvef(mode, file, args, None, execvp) 541 542 def spawnvpe(mode, file, args, env): 543 """spawnvpe(mode, file, args, env) -> integer 544 545Execute file (which is looked for along $PATH) with arguments from 546args in a subprocess with the supplied environment. 547If mode == P_NOWAIT return the pid of the process. 548If mode == P_WAIT return the process's exit code if it exits normally; 549otherwise return -SIG, where SIG is the signal that killed it. """ 550 return _spawnvef(mode, file, args, env, execvpe) 551 552if _exists("spawnv"): 553 # These aren't supplied by the basic Windows code 554 # but can be easily implemented in Python 555 556 def spawnl(mode, file, *args): 557 """spawnl(mode, file, *args) -> integer 558 559Execute file with arguments from args in a subprocess. 560If mode == P_NOWAIT return the pid of the process. 561If mode == P_WAIT return the process's exit code if it exits normally; 562otherwise return -SIG, where SIG is the signal that killed it. """ 563 return spawnv(mode, file, args) 564 565 def spawnle(mode, file, *args): 566 """spawnle(mode, file, *args, env) -> integer 567 568Execute file with arguments from args in a subprocess with the 569supplied environment. 570If mode == P_NOWAIT return the pid of the process. 571If mode == P_WAIT return the process's exit code if it exits normally; 572otherwise return -SIG, where SIG is the signal that killed it. """ 573 env = args[-1] 574 return spawnve(mode, file, args[:-1], env) 575 576if _exists("spawnvp"): 577 # At the moment, Windows doesn't implement spawnvp[e], 578 # so it won't have spawnlp[e] either. 579 def spawnlp(mode, file, *args): 580 """spawnlp(mode, file, *args) -> integer 581 582Execute file (which is looked for along $PATH) with arguments from 583args in a subprocess with the supplied environment. 584If mode == P_NOWAIT return the pid of the process. 585If mode == P_WAIT return the process's exit code if it exits normally; 586otherwise return -SIG, where SIG is the signal that killed it. """ 587 return spawnvp(mode, file, args) 588 589 def spawnlpe(mode, file, *args): 590 """spawnlpe(mode, file, *args, env) -> integer 591 592Execute file (which is looked for along $PATH) with arguments from 593args in a subprocess with the supplied environment. 594If mode == P_NOWAIT return the pid of the process. 595If mode == P_WAIT return the process's exit code if it exits normally; 596otherwise return -SIG, where SIG is the signal that killed it. """ 597 env = args[-1] 598 return spawnvpe(mode, file, args[:-1], env) 599 600 601 __all__.extend(["spawnlp","spawnlpe","spawnv", "spawnve","spawnvp", 602 "spawnvpe","spawnl","spawnle",]) 603 604 605# Supply popen2 etc. (for Unix) 606if _exists("fork"): 607 if not _exists("popen2"): 608 def popen2(cmd, mode="t", bufsize=-1): 609 import popen2 610 stdout, stdin = popen2.popen2(cmd, bufsize) 611 return stdin, stdout 612 __all__.append("popen2") 613 614 if not _exists("popen3"): 615 def popen3(cmd, mode="t", bufsize=-1): 616 import popen2 617 stdout, stdin, stderr = popen2.popen3(cmd, bufsize) 618 return stdin, stdout, stderr 619 __all__.append("popen3") 620 621 if not _exists("popen4"): 622 def popen4(cmd, mode="t", bufsize=-1): 623 import popen2 624 stdout, stdin = popen2.popen4(cmd, bufsize) 625 return stdin, stdout 626 __all__.append("popen4") 627 628import copy_reg as _copy_reg 629 630def _make_stat_result(tup, dict): 631 return stat_result(tup, dict) 632 633def _pickle_stat_result(sr): 634 (type, args) = sr.__reduce__() 635 return (_make_stat_result, args) 636 637try: 638 _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result) 639except NameError: # stat_result may not exist 640 pass 641 642def _make_statvfs_result(tup, dict): 643 return statvfs_result(tup, dict) 644 645def _pickle_statvfs_result(sr): 646 (type, args) = sr.__reduce__() 647 return (_make_statvfs_result, args) 648 649try: 650 _copy_reg.pickle(statvfs_result, _pickle_statvfs_result, 651 _make_statvfs_result) 652except NameError: # statvfs_result may not exist 653 pass 654