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