| 1 | r"""OS routines for NT or Posix depending on what system we're on.
 | 
| 2 | 
 | 
| 3 | This exports:
 | 
| 4 |   - all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.
 | 
| 5 |   - os.path is one of the modules posixpath, or ntpath
 | 
| 6 |   - os.name is 'posix', 'nt', 'os2', '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 | 
 | 
| 17 | Programs that import and use 'os' stand a better chance of being
 | 
| 18 | portable between different platforms.  Of course, they must then
 | 
| 19 | only use functions that are defined by all platforms (e.g., unlink
 | 
| 20 | and opendir), and leave all pathname manipulation to os.path
 | 
| 21 | (e.g., split and join).
 | 
| 22 | """
 | 
| 23 | 
 | 
| 24 | #'
 | 
| 25 | 
 | 
| 26 | import sys, errno
 | 
| 27 | 
 | 
| 28 | _names = sys.builtin_module_names
 | 
| 29 | 
 | 
| 30 | # Note:  more names are added to __all__ later.
 | 
| 31 | __all__ = ["altsep", "curdir", "pardir", "sep", "extsep", "pathsep", "linesep",
 | 
| 32 |            "defpath", "name", "path", "devnull",
 | 
| 33 |            "SEEK_SET", "SEEK_CUR", "SEEK_END"]
 | 
| 34 | 
 | 
| 35 | def _get_exports_list(module):
 | 
| 36 |     try:
 | 
| 37 |         return list(module.__all__)
 | 
| 38 |     except AttributeError:
 | 
| 39 |         return [n for n in dir(module) if n[0] != '_']
 | 
| 40 | 
 | 
| 41 | if 'posix' in _names:
 | 
| 42 |     name = 'posix'
 | 
| 43 |     linesep = '\n'
 | 
| 44 |     from posix import *
 | 
| 45 |     try:
 | 
| 46 |         from posix import _exit
 | 
| 47 |     except ImportError:
 | 
| 48 |         pass
 | 
| 49 |     import posixpath as path
 | 
| 50 | 
 | 
| 51 |     import posix
 | 
| 52 |     __all__.extend(_get_exports_list(posix))
 | 
| 53 |     del posix
 | 
| 54 | 
 | 
| 55 | elif 'nt' in _names:
 | 
| 56 |     name = 'nt'
 | 
| 57 |     linesep = '\r\n'
 | 
| 58 |     from nt import *
 | 
| 59 |     try:
 | 
| 60 |         from nt import _exit
 | 
| 61 |     except ImportError:
 | 
| 62 |         pass
 | 
| 63 |     import ntpath as path
 | 
| 64 | 
 | 
| 65 |     import nt
 | 
| 66 |     __all__.extend(_get_exports_list(nt))
 | 
| 67 |     del nt
 | 
| 68 | 
 | 
| 69 | elif 'os2' in _names:
 | 
| 70 |     name = 'os2'
 | 
| 71 |     linesep = '\r\n'
 | 
| 72 |     from os2 import *
 | 
| 73 |     try:
 | 
| 74 |         from os2 import _exit
 | 
| 75 |     except ImportError:
 | 
| 76 |         pass
 | 
| 77 |     if sys.version.find('EMX GCC') == -1:
 | 
| 78 |         import ntpath as path
 | 
| 79 |     else:
 | 
| 80 |         import os2emxpath as path
 | 
| 81 |         from _emx_link import link
 | 
| 82 | 
 | 
| 83 |     import os2
 | 
| 84 |     __all__.extend(_get_exports_list(os2))
 | 
| 85 |     del os2
 | 
| 86 | 
 | 
| 87 | elif 'ce' in _names:
 | 
| 88 |     name = 'ce'
 | 
| 89 |     linesep = '\r\n'
 | 
| 90 |     from ce import *
 | 
| 91 |     try:
 | 
| 92 |         from ce import _exit
 | 
| 93 |     except ImportError:
 | 
| 94 |         pass
 | 
| 95 |     # We can use the standard Windows path.
 | 
| 96 |     import ntpath as path
 | 
| 97 | 
 | 
| 98 |     import ce
 | 
| 99 |     __all__.extend(_get_exports_list(ce))
 | 
| 100 |     del ce
 | 
| 101 | 
 | 
| 102 | elif 'riscos' in _names:
 | 
| 103 |     name = 'riscos'
 | 
| 104 |     linesep = '\n'
 | 
| 105 |     from riscos import *
 | 
| 106 |     try:
 | 
| 107 |         from riscos import _exit
 | 
| 108 |     except ImportError:
 | 
| 109 |         pass
 | 
| 110 |     import riscospath as path
 | 
| 111 | 
 | 
| 112 |     import riscos
 | 
| 113 |     __all__.extend(_get_exports_list(riscos))
 | 
| 114 |     del riscos
 | 
| 115 | 
 | 
| 116 | else:
 | 
| 117 |     raise ImportError, 'no os specific module found'
 | 
| 118 | 
 | 
| 119 | sys.modules['os.path'] = path
 | 
| 120 | from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
 | 
| 121 |     devnull)
 | 
| 122 | 
 | 
| 123 | del _names
 | 
| 124 | 
 | 
| 125 | # Python uses fixed values for the SEEK_ constants; they are mapped
 | 
| 126 | # to native constants if necessary in posixmodule.c
 | 
| 127 | SEEK_SET = 0
 | 
| 128 | SEEK_CUR = 1
 | 
| 129 | SEEK_END = 2
 | 
| 130 | 
 | 
| 131 | #'
 | 
| 132 | 
 | 
| 133 | # Super directory utilities.
 | 
| 134 | # (Inspired by Eric Raymond; the doc strings are mostly his)
 | 
| 135 | 
 | 
| 136 | def makedirs(name, mode=0777):
 | 
| 137 |     """makedirs(path [, mode=0777])
 | 
| 138 | 
 | 
| 139 |     Super-mkdir; create a leaf directory and all intermediate ones.
 | 
| 140 |     Works like mkdir, except that any intermediate path segment (not
 | 
| 141 |     just the rightmost) will be created if it does not exist.  This is
 | 
| 142 |     recursive.
 | 
| 143 | 
 | 
| 144 |     """
 | 
| 145 |     head, tail = path.split(name)
 | 
| 146 |     if not tail:
 | 
| 147 |         head, tail = path.split(head)
 | 
| 148 |     if head and tail and not path.exists(head):
 | 
| 149 |         try:
 | 
| 150 |             makedirs(head, mode)
 | 
| 151 |         except OSError, e:
 | 
| 152 |             # be happy if someone already created the path
 | 
| 153 |             if e.errno != errno.EEXIST:
 | 
| 154 |                 raise
 | 
| 155 |         if tail == curdir:           # xxx/newdir/. exists if xxx/newdir exists
 | 
| 156 |             return
 | 
| 157 |     mkdir(name, mode)
 | 
| 158 | 
 | 
| 159 | def removedirs(name):
 | 
| 160 |     """removedirs(path)
 | 
| 161 | 
 | 
| 162 |     Super-rmdir; remove a leaf directory and all empty 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 | 
 | 
| 181 | def 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 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 | 
 | 
| 209 | def walk(top, topdown=True, onerror=None, followlinks=False):
 | 
| 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 the
 | 
| 233 |     search, or to impose a specific order of visiting.  Modifying dirnames when
 | 
| 234 |     topdown is false is ineffective, since the directories in dirnames have
 | 
| 235 |     already been generated by the time dirnames itself is generated. No matter
 | 
| 236 |     the value of topdown, the list of subdirectories is retrieved before the
 | 
| 237 |     tuples for the directory and its subdirectories are generated.
 | 
| 238 | 
 | 
| 239 |     By default errors from the os.listdir() call are ignored.  If
 | 
| 240 |     optional arg 'onerror' is specified, it should be a function; it
 | 
| 241 |     will be called with one argument, an os.error instance.  It can
 | 
| 242 |     report the error to continue with the walk, or raise the exception
 | 
| 243 |     to abort the walk.  Note that the filename is available as the
 | 
| 244 |     filename attribute of the exception object.
 | 
| 245 | 
 | 
| 246 |     By default, os.walk does not follow symbolic links to subdirectories on
 | 
| 247 |     systems that support them.  In order to get this functionality, set the
 | 
| 248 |     optional argument 'followlinks' to true.
 | 
| 249 | 
 | 
| 250 |     Caution:  if you pass a relative pathname for top, don't change the
 | 
| 251 |     current working directory between resumptions of walk.  walk never
 | 
| 252 |     changes the current directory, and assumes that the client doesn't
 | 
| 253 |     either.
 | 
| 254 | 
 | 
| 255 |     Example:
 | 
| 256 | 
 | 
| 257 |     import os
 | 
| 258 |     from os.path import join, getsize
 | 
| 259 |     for root, dirs, files in os.walk('python/Lib/email'):
 | 
| 260 |         print root, "consumes",
 | 
| 261 |         print sum([getsize(join(root, name)) for name in files]),
 | 
| 262 |         print "bytes in", len(files), "non-directory files"
 | 
| 263 |         if 'CVS' in dirs:
 | 
| 264 |             dirs.remove('CVS')  # don't visit CVS directories
 | 
| 265 | 
 | 
| 266 |     """
 | 
| 267 | 
 | 
| 268 |     islink, join, isdir = path.islink, path.join, path.isdir
 | 
| 269 | 
 | 
| 270 |     # We may not have read permission for top, in which case we can't
 | 
| 271 |     # get a list of the files the directory contains.  os.path.walk
 | 
| 272 |     # always suppressed the exception then, rather than blow up for a
 | 
| 273 |     # minor reason when (say) a thousand readable directories are still
 | 
| 274 |     # left to visit.  That logic is copied here.
 | 
| 275 |     try:
 | 
| 276 |         # Note that listdir and error are globals in this module due
 | 
| 277 |         # to earlier import-*.
 | 
| 278 |         names = listdir(top)
 | 
| 279 |     except error, err:
 | 
| 280 |         if onerror is not None:
 | 
| 281 |             onerror(err)
 | 
| 282 |         return
 | 
| 283 | 
 | 
| 284 |     dirs, nondirs = [], []
 | 
| 285 |     for name in names:
 | 
| 286 |         if isdir(join(top, name)):
 | 
| 287 |             dirs.append(name)
 | 
| 288 |         else:
 | 
| 289 |             nondirs.append(name)
 | 
| 290 | 
 | 
| 291 |     if topdown:
 | 
| 292 |         yield top, dirs, nondirs
 | 
| 293 |     for name in dirs:
 | 
| 294 |         new_path = join(top, name)
 | 
| 295 |         if followlinks or not islink(new_path):
 | 
| 296 |             for x in walk(new_path, topdown, onerror, followlinks):
 | 
| 297 |                 yield x
 | 
| 298 |     if not topdown:
 | 
| 299 |         yield top, dirs, nondirs
 | 
| 300 | 
 | 
| 301 | __all__.append("walk")
 | 
| 302 | 
 | 
| 303 | # Make sure os.environ exists, at least
 | 
| 304 | try:
 | 
| 305 |     environ
 | 
| 306 | except NameError:
 | 
| 307 |     environ = {}
 | 
| 308 | 
 | 
| 309 | def execl(file, *args):
 | 
| 310 |     """execl(file, *args)
 | 
| 311 | 
 | 
| 312 |     Execute the executable file with argument list args, replacing the
 | 
| 313 |     current process. """
 | 
| 314 |     execv(file, args)
 | 
| 315 | 
 | 
| 316 | def execle(file, *args):
 | 
| 317 |     """execle(file, *args, env)
 | 
| 318 | 
 | 
| 319 |     Execute the executable file with argument list args and
 | 
| 320 |     environment env, replacing the current process. """
 | 
| 321 |     env = args[-1]
 | 
| 322 |     execve(file, args[:-1], env)
 | 
| 323 | 
 | 
| 324 | def execlp(file, *args):
 | 
| 325 |     """execlp(file, *args)
 | 
| 326 | 
 | 
| 327 |     Execute the executable file (which is searched for along $PATH)
 | 
| 328 |     with argument list args, replacing the current process. """
 | 
| 329 |     execvp(file, args)
 | 
| 330 | 
 | 
| 331 | def execlpe(file, *args):
 | 
| 332 |     """execlpe(file, *args, env)
 | 
| 333 | 
 | 
| 334 |     Execute the executable file (which is searched for along $PATH)
 | 
| 335 |     with argument list args and environment env, replacing the current
 | 
| 336 |     process. """
 | 
| 337 |     env = args[-1]
 | 
| 338 |     execvpe(file, args[:-1], env)
 | 
| 339 | 
 | 
| 340 | def execvp(file, args):
 | 
| 341 |     """execvp(file, args)
 | 
| 342 | 
 | 
| 343 |     Execute the executable file (which is searched for along $PATH)
 | 
| 344 |     with argument list args, replacing the current process.
 | 
| 345 |     args may be a list or tuple of strings. """
 | 
| 346 |     _execvpe(file, args)
 | 
| 347 | 
 | 
| 348 | def execvpe(file, args, env):
 | 
| 349 |     """execvpe(file, args, env)
 | 
| 350 | 
 | 
| 351 |     Execute the executable file (which is searched for along $PATH)
 | 
| 352 |     with argument list args and environment env , replacing the
 | 
| 353 |     current process.
 | 
| 354 |     args may be a list or tuple of strings. """
 | 
| 355 |     _execvpe(file, args, env)
 | 
| 356 | 
 | 
| 357 | __all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
 | 
| 358 | 
 | 
| 359 | def _execvpe(file, args, env=None):
 | 
| 360 |     if env is not None:
 | 
| 361 |         func = execve
 | 
| 362 |         argrest = (args, env)
 | 
| 363 |     else:
 | 
| 364 |         func = execv
 | 
| 365 |         argrest = (args,)
 | 
| 366 |         env = environ
 | 
| 367 | 
 | 
| 368 |     head, tail = path.split(file)
 | 
| 369 |     if head:
 | 
| 370 |         func(file, *argrest)
 | 
| 371 |         return
 | 
| 372 |     if 'PATH' in env:
 | 
| 373 |         envpath = env['PATH']
 | 
| 374 |     else:
 | 
| 375 |         envpath = defpath
 | 
| 376 |     PATH = envpath.split(pathsep)
 | 
| 377 |     saved_exc = None
 | 
| 378 |     saved_tb = None
 | 
| 379 |     for dir in PATH:
 | 
| 380 |         fullname = path.join(dir, file)
 | 
| 381 |         try:
 | 
| 382 |             func(fullname, *argrest)
 | 
| 383 |         except error, e:
 | 
| 384 |             tb = sys.exc_info()[2]
 | 
| 385 |             if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
 | 
| 386 |                 and saved_exc is None):
 | 
| 387 |                 saved_exc = e
 | 
| 388 |                 saved_tb = tb
 | 
| 389 |     if saved_exc:
 | 
| 390 |         raise error, saved_exc, saved_tb
 | 
| 391 |     raise error, e, tb
 | 
| 392 | 
 | 
| 393 | # Change environ to automatically call putenv() if it exists
 | 
| 394 | try:
 | 
| 395 |     # This will fail if there's no putenv
 | 
| 396 |     putenv
 | 
| 397 | except NameError:
 | 
| 398 |     pass
 | 
| 399 | else:
 | 
| 400 |     import UserDict
 | 
| 401 | 
 | 
| 402 |     # Fake unsetenv() for Windows
 | 
| 403 |     # not sure about os2 here but
 | 
| 404 |     # I'm guessing they are the same.
 | 
| 405 | 
 | 
| 406 |     if name in ('os2', 'nt'):
 | 
| 407 |         def unsetenv(key):
 | 
| 408 |             putenv(key, "")
 | 
| 409 | 
 | 
| 410 |     if name == "riscos":
 | 
| 411 |         # On RISC OS, all env access goes through getenv and putenv
 | 
| 412 |         from riscosenviron import _Environ
 | 
| 413 |     elif name in ('os2', 'nt'):  # Where Env Var Names Must Be UPPERCASE
 | 
| 414 |         # But we store them as upper case
 | 
| 415 |         class _Environ(UserDict.IterableUserDict):
 | 
| 416 |             def __init__(self, environ):
 | 
| 417 |                 UserDict.UserDict.__init__(self)
 | 
| 418 |                 data = self.data
 | 
| 419 |                 for k, v in environ.items():
 | 
| 420 |                     data[k.upper()] = v
 | 
| 421 |             def __setitem__(self, key, item):
 | 
| 422 |                 putenv(key, item)
 | 
| 423 |                 self.data[key.upper()] = item
 | 
| 424 |             def __getitem__(self, key):
 | 
| 425 |                 return self.data[key.upper()]
 | 
| 426 |             try:
 | 
| 427 |                 unsetenv
 | 
| 428 |             except NameError:
 | 
| 429 |                 def __delitem__(self, key):
 | 
| 430 |                     del self.data[key.upper()]
 | 
| 431 |             else:
 | 
| 432 |                 def __delitem__(self, key):
 | 
| 433 |                     unsetenv(key)
 | 
| 434 |                     del self.data[key.upper()]
 | 
| 435 |                 def clear(self):
 | 
| 436 |                     for key in self.data.keys():
 | 
| 437 |                         unsetenv(key)
 | 
| 438 |                         del self.data[key]
 | 
| 439 |                 def pop(self, key, *args):
 | 
| 440 |                     unsetenv(key)
 | 
| 441 |                     return self.data.pop(key.upper(), *args)
 | 
| 442 |             def has_key(self, key):
 | 
| 443 |                 return key.upper() in self.data
 | 
| 444 |             def __contains__(self, key):
 | 
| 445 |                 return key.upper() in self.data
 | 
| 446 |             def get(self, key, failobj=None):
 | 
| 447 |                 return self.data.get(key.upper(), failobj)
 | 
| 448 |             def update(self, dict=None, **kwargs):
 | 
| 449 |                 if dict:
 | 
| 450 |                     try:
 | 
| 451 |                         keys = dict.keys()
 | 
| 452 |                     except AttributeError:
 | 
| 453 |                         # List of (key, value)
 | 
| 454 |                         for k, v in dict:
 | 
| 455 |                             self[k] = v
 | 
| 456 |                     else:
 | 
| 457 |                         # got keys
 | 
| 458 |                         # cannot use items(), since mappings
 | 
| 459 |                         # may not have them.
 | 
| 460 |                         for k in keys:
 | 
| 461 |                             self[k] = dict[k]
 | 
| 462 |                 if kwargs:
 | 
| 463 |                     self.update(kwargs)
 | 
| 464 |             def copy(self):
 | 
| 465 |                 return dict(self)
 | 
| 466 | 
 | 
| 467 |     else:  # Where Env Var Names Can Be Mixed Case
 | 
| 468 |         class _Environ(UserDict.IterableUserDict):
 | 
| 469 |             def __init__(self, environ):
 | 
| 470 |                 UserDict.UserDict.__init__(self)
 | 
| 471 |                 self.data = environ
 | 
| 472 |             def __setitem__(self, key, item):
 | 
| 473 |                 putenv(key, item)
 | 
| 474 |                 self.data[key] = item
 | 
| 475 |             def update(self,  dict=None, **kwargs):
 | 
| 476 |                 if dict:
 | 
| 477 |                     try:
 | 
| 478 |                         keys = dict.keys()
 | 
| 479 |                     except AttributeError:
 | 
| 480 |                         # List of (key, value)
 | 
| 481 |                         for k, v in dict:
 | 
| 482 |                             self[k] = v
 | 
| 483 |                     else:
 | 
| 484 |                         # got keys
 | 
| 485 |                         # cannot use items(), since mappings
 | 
| 486 |                         # may not have them.
 | 
| 487 |                         for k in keys:
 | 
| 488 |                             self[k] = dict[k]
 | 
| 489 |                 if kwargs:
 | 
| 490 |                     self.update(kwargs)
 | 
| 491 |             try:
 | 
| 492 |                 unsetenv
 | 
| 493 |             except NameError:
 | 
| 494 |                 pass
 | 
| 495 |             else:
 | 
| 496 |                 def __delitem__(self, key):
 | 
| 497 |                     unsetenv(key)
 | 
| 498 |                     del self.data[key]
 | 
| 499 |                 def clear(self):
 | 
| 500 |                     for key in self.data.keys():
 | 
| 501 |                         unsetenv(key)
 | 
| 502 |                         del self.data[key]
 | 
| 503 |                 def pop(self, key, *args):
 | 
| 504 |                     unsetenv(key)
 | 
| 505 |                     return self.data.pop(key, *args)
 | 
| 506 |             def copy(self):
 | 
| 507 |                 return dict(self)
 | 
| 508 | 
 | 
| 509 | 
 | 
| 510 |     environ = _Environ(environ)
 | 
| 511 | 
 | 
| 512 | def getenv(key, default=None):
 | 
| 513 |     """Get an environment variable, return None if it doesn't exist.
 | 
| 514 |     The optional second argument can specify an alternate default."""
 | 
| 515 |     return environ.get(key, default)
 | 
| 516 | __all__.append("getenv")
 | 
| 517 | 
 | 
| 518 | def _exists(name):
 | 
| 519 |     return name in globals()
 | 
| 520 | 
 | 
| 521 | # Supply spawn*() (probably only for Unix)
 | 
| 522 | if _exists("fork") and not _exists("spawnv") and _exists("execv"):
 | 
| 523 | 
 | 
| 524 |     P_WAIT = 0
 | 
| 525 |     P_NOWAIT = P_NOWAITO = 1
 | 
| 526 | 
 | 
| 527 |     # XXX Should we support P_DETACH?  I suppose it could fork()**2
 | 
| 528 |     # and close the std I/O streams.  Also, P_OVERLAY is the same
 | 
| 529 |     # as execv*()?
 | 
| 530 | 
 | 
| 531 |     def _spawnvef(mode, file, args, env, func):
 | 
| 532 |         # Internal helper; func is the exec*() function to use
 | 
| 533 |         pid = fork()
 | 
| 534 |         if not pid:
 | 
| 535 |             # Child
 | 
| 536 |             try:
 | 
| 537 |                 if env is None:
 | 
| 538 |                     func(file, args)
 | 
| 539 |                 else:
 | 
| 540 |                     func(file, args, env)
 | 
| 541 |             except:
 | 
| 542 |                 _exit(127)
 | 
| 543 |         else:
 | 
| 544 |             # Parent
 | 
| 545 |             if mode == P_NOWAIT:
 | 
| 546 |                 return pid # Caller is responsible for waiting!
 | 
| 547 |             while 1:
 | 
| 548 |                 wpid, sts = waitpid(pid, 0)
 | 
| 549 |                 if WIFSTOPPED(sts):
 | 
| 550 |                     continue
 | 
| 551 |                 elif WIFSIGNALED(sts):
 | 
| 552 |                     return -WTERMSIG(sts)
 | 
| 553 |                 elif WIFEXITED(sts):
 | 
| 554 |                     return WEXITSTATUS(sts)
 | 
| 555 |                 else:
 | 
| 556 |                     raise error, "Not stopped, signaled or exited???"
 | 
| 557 | 
 | 
| 558 |     def spawnv(mode, file, args):
 | 
| 559 |         """spawnv(mode, file, args) -> integer
 | 
| 560 | 
 | 
| 561 | Execute file with arguments from args in a subprocess.
 | 
| 562 | If mode == P_NOWAIT return the pid of the process.
 | 
| 563 | If mode == P_WAIT return the process's exit code if it exits normally;
 | 
| 564 | otherwise return -SIG, where SIG is the signal that killed it. """
 | 
| 565 |         return _spawnvef(mode, file, args, None, execv)
 | 
| 566 | 
 | 
| 567 |     def spawnve(mode, file, args, env):
 | 
| 568 |         """spawnve(mode, file, args, env) -> integer
 | 
| 569 | 
 | 
| 570 | Execute file with arguments from args in a subprocess with the
 | 
| 571 | specified environment.
 | 
| 572 | If mode == P_NOWAIT return the pid of the process.
 | 
| 573 | If mode == P_WAIT return the process's exit code if it exits normally;
 | 
| 574 | otherwise return -SIG, where SIG is the signal that killed it. """
 | 
| 575 |         return _spawnvef(mode, file, args, env, execve)
 | 
| 576 | 
 | 
| 577 |     # Note: spawnvp[e] is't currently supported on Windows
 | 
| 578 | 
 | 
| 579 |     def spawnvp(mode, file, args):
 | 
| 580 |         """spawnvp(mode, file, args) -> integer
 | 
| 581 | 
 | 
| 582 | Execute file (which is looked for along $PATH) with arguments from
 | 
| 583 | args in a subprocess.
 | 
| 584 | If mode == P_NOWAIT return the pid of the process.
 | 
| 585 | If mode == P_WAIT return the process's exit code if it exits normally;
 | 
| 586 | otherwise return -SIG, where SIG is the signal that killed it. """
 | 
| 587 |         return _spawnvef(mode, file, args, None, execvp)
 | 
| 588 | 
 | 
| 589 |     def spawnvpe(mode, file, args, env):
 | 
| 590 |         """spawnvpe(mode, file, args, env) -> integer
 | 
| 591 | 
 | 
| 592 | Execute file (which is looked for along $PATH) with arguments from
 | 
| 593 | args in a subprocess with the supplied environment.
 | 
| 594 | If mode == P_NOWAIT return the pid of the process.
 | 
| 595 | If mode == P_WAIT return the process's exit code if it exits normally;
 | 
| 596 | otherwise return -SIG, where SIG is the signal that killed it. """
 | 
| 597 |         return _spawnvef(mode, file, args, env, execvpe)
 | 
| 598 | 
 | 
| 599 | if _exists("spawnv"):
 | 
| 600 |     # These aren't supplied by the basic Windows code
 | 
| 601 |     # but can be easily implemented in Python
 | 
| 602 | 
 | 
| 603 |     def spawnl(mode, file, *args):
 | 
| 604 |         """spawnl(mode, file, *args) -> integer
 | 
| 605 | 
 | 
| 606 | Execute file with arguments from args in a subprocess.
 | 
| 607 | If mode == P_NOWAIT return the pid of the process.
 | 
| 608 | If mode == P_WAIT return the process's exit code if it exits normally;
 | 
| 609 | otherwise return -SIG, where SIG is the signal that killed it. """
 | 
| 610 |         return spawnv(mode, file, args)
 | 
| 611 | 
 | 
| 612 |     def spawnle(mode, file, *args):
 | 
| 613 |         """spawnle(mode, file, *args, env) -> integer
 | 
| 614 | 
 | 
| 615 | Execute file with arguments from args in a subprocess with the
 | 
| 616 | supplied environment.
 | 
| 617 | If mode == P_NOWAIT return the pid of the process.
 | 
| 618 | If mode == P_WAIT return the process's exit code if it exits normally;
 | 
| 619 | otherwise return -SIG, where SIG is the signal that killed it. """
 | 
| 620 |         env = args[-1]
 | 
| 621 |         return spawnve(mode, file, args[:-1], env)
 | 
| 622 | 
 | 
| 623 | 
 | 
| 624 |     __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
 | 
| 625 | 
 | 
| 626 | 
 | 
| 627 | if _exists("spawnvp"):
 | 
| 628 |     # At the moment, Windows doesn't implement spawnvp[e],
 | 
| 629 |     # so it won't have spawnlp[e] either.
 | 
| 630 |     def spawnlp(mode, file, *args):
 | 
| 631 |         """spawnlp(mode, file, *args) -> integer
 | 
| 632 | 
 | 
| 633 | Execute file (which is looked for along $PATH) with arguments from
 | 
| 634 | args in a subprocess with the supplied environment.
 | 
| 635 | If mode == P_NOWAIT return the pid of the process.
 | 
| 636 | If mode == P_WAIT return the process's exit code if it exits normally;
 | 
| 637 | otherwise return -SIG, where SIG is the signal that killed it. """
 | 
| 638 |         return spawnvp(mode, file, args)
 | 
| 639 | 
 | 
| 640 |     def spawnlpe(mode, file, *args):
 | 
| 641 |         """spawnlpe(mode, file, *args, env) -> integer
 | 
| 642 | 
 | 
| 643 | Execute file (which is looked for along $PATH) with arguments from
 | 
| 644 | args in a subprocess with the supplied environment.
 | 
| 645 | If mode == P_NOWAIT return the pid of the process.
 | 
| 646 | If mode == P_WAIT return the process's exit code if it exits normally;
 | 
| 647 | otherwise return -SIG, where SIG is the signal that killed it. """
 | 
| 648 |         env = args[-1]
 | 
| 649 |         return spawnvpe(mode, file, args[:-1], env)
 | 
| 650 | 
 | 
| 651 | 
 | 
| 652 |     __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
 | 
| 653 | 
 | 
| 654 | 
 | 
| 655 | # Supply popen2 etc. (for Unix)
 | 
| 656 | if _exists("fork"):
 | 
| 657 |     if not _exists("popen2"):
 | 
| 658 |         def popen2(cmd, mode="t", bufsize=-1):
 | 
| 659 |             """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
 | 
| 660 |             may be a sequence, in which case arguments will be passed directly to
 | 
| 661 |             the program without shell intervention (as with os.spawnv()).  If 'cmd'
 | 
| 662 |             is a string it will be passed to the shell (as with os.system()). If
 | 
| 663 |             'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
 | 
| 664 |             file objects (child_stdin, child_stdout) are returned."""
 | 
| 665 |             import warnings
 | 
| 666 |             msg = "os.popen2 is deprecated.  Use the subprocess module."
 | 
| 667 |             warnings.warn(msg, DeprecationWarning, stacklevel=2)
 | 
| 668 | 
 | 
| 669 |             import subprocess
 | 
| 670 |             PIPE = subprocess.PIPE
 | 
| 671 |             p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
 | 
| 672 |                                  bufsize=bufsize, stdin=PIPE, stdout=PIPE,
 | 
| 673 |                                  close_fds=True)
 | 
| 674 |             return p.stdin, p.stdout
 | 
| 675 |         __all__.append("popen2")
 | 
| 676 | 
 | 
| 677 |     if not _exists("popen3"):
 | 
| 678 |         def popen3(cmd, mode="t", bufsize=-1):
 | 
| 679 |             """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
 | 
| 680 |             may be a sequence, in which case arguments will be passed directly to
 | 
| 681 |             the program without shell intervention (as with os.spawnv()).  If 'cmd'
 | 
| 682 |             is a string it will be passed to the shell (as with os.system()). If
 | 
| 683 |             'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
 | 
| 684 |             file objects (child_stdin, child_stdout, child_stderr) are returned."""
 | 
| 685 |             import warnings
 | 
| 686 |             msg = "os.popen3 is deprecated.  Use the subprocess module."
 | 
| 687 |             warnings.warn(msg, DeprecationWarning, stacklevel=2)
 | 
| 688 | 
 | 
| 689 |             import subprocess
 | 
| 690 |             PIPE = subprocess.PIPE
 | 
| 691 |             p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
 | 
| 692 |                                  bufsize=bufsize, stdin=PIPE, stdout=PIPE,
 | 
| 693 |                                  stderr=PIPE, close_fds=True)
 | 
| 694 |             return p.stdin, p.stdout, p.stderr
 | 
| 695 |         __all__.append("popen3")
 | 
| 696 | 
 | 
| 697 |     if not _exists("popen4"):
 | 
| 698 |         def popen4(cmd, mode="t", bufsize=-1):
 | 
| 699 |             """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
 | 
| 700 |             may be a sequence, in which case arguments will be passed directly to
 | 
| 701 |             the program without shell intervention (as with os.spawnv()).  If 'cmd'
 | 
| 702 |             is a string it will be passed to the shell (as with os.system()). If
 | 
| 703 |             'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
 | 
| 704 |             file objects (child_stdin, child_stdout_stderr) are returned."""
 | 
| 705 |             import warnings
 | 
| 706 |             msg = "os.popen4 is deprecated.  Use the subprocess module."
 | 
| 707 |             warnings.warn(msg, DeprecationWarning, stacklevel=2)
 | 
| 708 | 
 | 
| 709 |             import subprocess
 | 
| 710 |             PIPE = subprocess.PIPE
 | 
| 711 |             p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
 | 
| 712 |                                  bufsize=bufsize, stdin=PIPE, stdout=PIPE,
 | 
| 713 |                                  stderr=subprocess.STDOUT, close_fds=True)
 | 
| 714 |             return p.stdin, p.stdout
 | 
| 715 |         __all__.append("popen4")
 | 
| 716 | 
 | 
| 717 | import copy_reg as _copy_reg
 | 
| 718 | 
 | 
| 719 | def _make_stat_result(tup, dict):
 | 
| 720 |     return stat_result(tup, dict)
 | 
| 721 | 
 | 
| 722 | def _pickle_stat_result(sr):
 | 
| 723 |     (type, args) = sr.__reduce__()
 | 
| 724 |     return (_make_stat_result, args)
 | 
| 725 | 
 | 
| 726 | try:
 | 
| 727 |     _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
 | 
| 728 | except NameError: # stat_result may not exist
 | 
| 729 |     pass
 | 
| 730 | 
 | 
| 731 | def _make_statvfs_result(tup, dict):
 | 
| 732 |     return statvfs_result(tup, dict)
 | 
| 733 | 
 | 
| 734 | def _pickle_statvfs_result(sr):
 | 
| 735 |     (type, args) = sr.__reduce__()
 | 
| 736 |     return (_make_statvfs_result, args)
 | 
| 737 | 
 | 
| 738 | try:
 | 
| 739 |     _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
 | 
| 740 |                      _make_statvfs_result)
 | 
| 741 | except NameError: # statvfs_result may not exist
 | 
| 742 |     pass
 |