Home | History | Annotate | Download | only in Lib
      1 
      2 # Module 'os' -- OS routines for NT, Posix, or UEFI depending on what system we're on.

      3 #

      4 # Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>

      5 # Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>

      6 # This program and the accompanying materials are licensed and made available under

      7 # the terms and conditions of the BSD License that accompanies this distribution.

      8 # The full text of the license may be found at

      9 # http://opensource.org/licenses/bsd-license.

     10 #

     11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     13 
     14 r"""OS routines for NT, Posix, or UEFI depending on what system we're on.
     15 
     16 This exports:
     17   - all functions from edk2, posix, nt, os2, or ce, e.g. unlink, stat, etc.
     18   - os.path is one of the modules uefipath, posixpath, or ntpath
     19   - os.name is 'edk2', 'posix', 'nt', 'os2', 'ce' or 'riscos'
     20   - os.curdir is a string representing the current directory ('.' or ':')
     21   - os.pardir is a string representing the parent directory ('..' or '::')
     22   - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
     23   - os.extsep is the extension separator ('.' or '/')
     24   - os.altsep is the alternate pathname separator (None or '/')
     25   - os.pathsep is the component separator used in $PATH etc
     26   - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
     27   - os.defpath is the default search path for executables
     28   - os.devnull is the file path of the null device ('/dev/null', etc.)
     29 
     30 Programs that import and use 'os' stand a better chance of being
     31 portable between different platforms.  Of course, they must then
     32 only use functions that are defined by all platforms (e.g., unlink
     33 and opendir), and leave all pathname manipulation to os.path
     34 (e.g., split and join).
     35 """
     36 
     37 #'

     38 
     39 import sys, errno
     40 
     41 _names = sys.builtin_module_names
     42 
     43 # Note:  more names are added to __all__ later.

     44 __all__ = ["altsep", "curdir", "pardir", "sep", "extsep", "pathsep", "linesep",
     45            "defpath", "name", "path", "devnull",
     46            "SEEK_SET", "SEEK_CUR", "SEEK_END"]
     47 
     48 def _get_exports_list(module):
     49     try:
     50         return list(module.__all__)
     51     except AttributeError:
     52         return [n for n in dir(module) if n[0] != '_']
     53 
     54 if 'posix' in _names:
     55     name = 'posix'
     56     linesep = '\n'
     57     from posix import *
     58     try:
     59         from posix import _exit
     60     except ImportError:
     61         pass
     62     import posixpath as path
     63 
     64     import posix
     65     __all__.extend(_get_exports_list(posix))
     66     del posix
     67 
     68 elif 'nt' in _names:
     69     name = 'nt'
     70     linesep = '\r\n'
     71     from nt import *
     72     try:
     73         from nt import _exit
     74     except ImportError:
     75         pass
     76     import ntpath as path
     77 
     78     import nt
     79     __all__.extend(_get_exports_list(nt))
     80     del nt
     81 
     82 elif 'os2' in _names:
     83     name = 'os2'
     84     linesep = '\r\n'
     85     from os2 import *
     86     try:
     87         from os2 import _exit
     88     except ImportError:
     89         pass
     90     if sys.version.find('EMX GCC') == -1:
     91         import ntpath as path
     92     else:
     93         import os2emxpath as path
     94         from _emx_link import link
     95 
     96     import os2
     97     __all__.extend(_get_exports_list(os2))
     98     del os2
     99 
    100 elif '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 
    115 elif '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 
    129 elif 'edk2' in _names:
    130     name = 'edk2'
    131     linesep = '\n'
    132     from edk2 import *
    133     try:
    134         from edk2 import _exit
    135     except ImportError:
    136         pass
    137     import ntpath as path
    138 
    139     import edk2
    140     __all__.extend(_get_exports_list(edk2))
    141     del edk2
    142 
    143 else:
    144     raise ImportError, 'no os specific module found'
    145 
    146 sys.modules['os.path'] = path
    147 from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
    148     devnull)
    149 
    150 del _names
    151 
    152 # Python uses fixed values for the SEEK_ constants; they are mapped

    153 # to native constants if necessary in posixmodule.c

    154 SEEK_SET = 0
    155 SEEK_CUR = 1
    156 SEEK_END = 2
    157 
    158 #'

    159 
    160 # Super directory utilities.

    161 # (Inspired by Eric Raymond; the doc strings are mostly his)

    162 
    163 def makedirs(name, mode=0777):
    164     """makedirs(path [, mode=0777])
    165 
    166     Super-mkdir; create a leaf directory and all intermediate ones.
    167     Works like mkdir, except that any intermediate path segment (not
    168     just the rightmost) will be created if it does not exist.  This is
    169     recursive.
    170 
    171     """
    172     head, tail = path.split(name)
    173     if not tail:
    174         head, tail = path.split(head)
    175     if head and tail and not path.exists(head):
    176         try:
    177             makedirs(head, mode)
    178         except OSError, e:
    179             # be happy if someone already created the path

    180             if e.errno != errno.EEXIST:
    181                 raise
    182         if tail == curdir:           # xxx/newdir/. exists if xxx/newdir exists

    183             return
    184     mkdir(name, mode)
    185 
    186 def removedirs(name):
    187     """removedirs(path)
    188 
    189     Super-rmdir; remove a leaf directory and all empty intermediate
    190     ones.  Works like rmdir except that, if the leaf directory is
    191     successfully removed, directories corresponding to rightmost path
    192     segments will be pruned away until either the whole path is
    193     consumed or an error occurs.  Errors during this latter phase are
    194     ignored -- they generally mean that a directory was not empty.
    195 
    196     """
    197     rmdir(name)
    198     head, tail = path.split(name)
    199     if not tail:
    200         head, tail = path.split(head)
    201     while head and tail:
    202         try:
    203             rmdir(head)
    204         except error:
    205             break
    206         head, tail = path.split(head)
    207 
    208 def renames(old, new):
    209     """renames(old, new)
    210 
    211     Super-rename; create directories as necessary and delete any left
    212     empty.  Works like rename, except creation of any intermediate
    213     directories needed to make the new pathname good is attempted
    214     first.  After the rename, directories corresponding to rightmost
    215     path segments of the old name will be pruned until either the
    216     whole path is consumed or a nonempty directory is found.
    217 
    218     Note: this function can fail with the new directory structure made
    219     if you lack permissions needed to unlink the leaf directory or
    220     file.
    221 
    222     """
    223     head, tail = path.split(new)
    224     if head and tail and not path.exists(head):
    225         makedirs(head)
    226     rename(old, new)
    227     head, tail = path.split(old)
    228     if head and tail:
    229         try:
    230             removedirs(head)
    231         except error:
    232             pass
    233 
    234 __all__.extend(["makedirs", "removedirs", "renames"])
    235 
    236 def walk(top, topdown=True, onerror=None, followlinks=False):
    237     """Directory tree generator.
    238 
    239     For each directory in the directory tree rooted at top (including top
    240     itself, but excluding '.' and '..'), yields a 3-tuple
    241 
    242         dirpath, dirnames, filenames
    243 
    244     dirpath is a string, the path to the directory.  dirnames is a list of
    245     the names of the subdirectories in dirpath (excluding '.' and '..').
    246     filenames is a list of the names of the non-directory files in dirpath.
    247     Note that the names in the lists are just names, with no path components.
    248     To get a full path (which begins with top) to a file or directory in
    249     dirpath, do os.path.join(dirpath, name).
    250 
    251     If optional arg 'topdown' is true or not specified, the triple for a
    252     directory is generated before the triples for any of its subdirectories
    253     (directories are generated top down).  If topdown is false, the triple
    254     for a directory is generated after the triples for all of its
    255     subdirectories (directories are generated bottom up).
    256 
    257     When topdown is true, the caller can modify the dirnames list in-place
    258     (e.g., via del or slice assignment), and walk will only recurse into the
    259     subdirectories whose names remain in dirnames; this can be used to prune the
    260     search, or to impose a specific order of visiting.  Modifying dirnames when
    261     topdown is false is ineffective, since the directories in dirnames have
    262     already been generated by the time dirnames itself is generated. No matter
    263     the value of topdown, the list of subdirectories is retrieved before the
    264     tuples for the directory and its subdirectories are generated.
    265 
    266     By default errors from the os.listdir() call are ignored.  If
    267     optional arg 'onerror' is specified, it should be a function; it
    268     will be called with one argument, an os.error instance.  It can
    269     report the error to continue with the walk, or raise the exception
    270     to abort the walk.  Note that the filename is available as the
    271     filename attribute of the exception object.
    272 
    273     By default, os.walk does not follow symbolic links to subdirectories on
    274     systems that support them.  In order to get this functionality, set the
    275     optional argument 'followlinks' to true.
    276 
    277     Caution:  if you pass a relative pathname for top, don't change the
    278     current working directory between resumptions of walk.  walk never
    279     changes the current directory, and assumes that the client doesn't
    280     either.
    281 
    282     Example:
    283 
    284     import os
    285     from os.path import join, getsize
    286     for root, dirs, files in os.walk('python/Lib/email'):
    287         print root, "consumes",
    288         print sum([getsize(join(root, name)) for name in files]),
    289         print "bytes in", len(files), "non-directory files"
    290         if 'CVS' in dirs:
    291             dirs.remove('CVS')  # don't visit CVS directories
    292 
    293     """
    294 
    295     islink, join, isdir = path.islink, path.join, path.isdir
    296 
    297     # We may not have read permission for top, in which case we can't

    298     # get a list of the files the directory contains.  os.path.walk

    299     # always suppressed the exception then, rather than blow up for a

    300     # minor reason when (say) a thousand readable directories are still

    301     # left to visit.  That logic is copied here.

    302     try:
    303         # Note that listdir and error are globals in this module due

    304         # to earlier import-*.

    305         names = listdir(top)
    306     except error, err:
    307         if onerror is not None:
    308             onerror(err)
    309         return
    310 
    311     dirs, nondirs = [], []
    312     for name in names:
    313         if isdir(join(top, name)):
    314             dirs.append(name)
    315         else:
    316             nondirs.append(name)
    317 
    318     if topdown:
    319         yield top, dirs, nondirs
    320     for name in dirs:
    321         new_path = join(top, name)
    322         if followlinks or not islink(new_path):
    323             for x in walk(new_path, topdown, onerror, followlinks):
    324                 yield x
    325     if not topdown:
    326         yield top, dirs, nondirs
    327 
    328 __all__.append("walk")
    329 
    330 # Make sure os.environ exists, at least

    331 try:
    332     environ
    333 except NameError:
    334     environ = {}
    335 
    336 def execl(file, *args):
    337     """execl(file, *args)
    338 
    339     Execute the executable file with argument list args, replacing the
    340     current process. """
    341     execv(file, args)
    342 
    343 def execle(file, *args):
    344     """execle(file, *args, env)
    345 
    346     Execute the executable file with argument list args and
    347     environment env, replacing the current process. """
    348     env = args[-1]
    349     execve(file, args[:-1], env)
    350 
    351 def execlp(file, *args):
    352     """execlp(file, *args)
    353 
    354     Execute the executable file (which is searched for along $PATH)
    355     with argument list args, replacing the current process. """
    356     execvp(file, args)
    357 
    358 def execlpe(file, *args):
    359     """execlpe(file, *args, env)
    360 
    361     Execute the executable file (which is searched for along $PATH)
    362     with argument list args and environment env, replacing the current
    363     process. """
    364     env = args[-1]
    365     execvpe(file, args[:-1], env)
    366 
    367 def execvp(file, args):
    368     """execvp(file, args)
    369 
    370     Execute the executable file (which is searched for along $PATH)
    371     with argument list args, replacing the current process.
    372     args may be a list or tuple of strings. """
    373     _execvpe(file, args)
    374 
    375 def execvpe(file, args, env):
    376     """execvpe(file, args, env)
    377 
    378     Execute the executable file (which is searched for along $PATH)
    379     with argument list args and environment env , replacing the
    380     current process.
    381     args may be a list or tuple of strings. """
    382     _execvpe(file, args, env)
    383 
    384 __all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
    385 
    386 def _execvpe(file, args, env=None):
    387     if env is not None:
    388         func = execve
    389         argrest = (args, env)
    390     else:
    391         func = execv
    392         argrest = (args,)
    393         env = environ
    394 
    395     head, tail = path.split(file)
    396     if head:
    397         func(file, *argrest)
    398         return
    399     if 'PATH' in env:
    400         envpath = env['PATH']
    401     else:
    402         envpath = defpath
    403     PATH = envpath.split(pathsep)
    404     saved_exc = None
    405     saved_tb = None
    406     for dir in PATH:
    407         fullname = path.join(dir, file)
    408         try:
    409             func(fullname, *argrest)
    410         except error, e:
    411             tb = sys.exc_info()[2]
    412             if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
    413                 and saved_exc is None):
    414                 saved_exc = e
    415                 saved_tb = tb
    416     if saved_exc:
    417         raise error, saved_exc, saved_tb
    418     raise error, e, tb
    419 
    420 # Change environ to automatically call putenv() if it exists

    421 try:
    422     # This will fail if there's no putenv

    423     putenv
    424 except NameError:
    425     pass
    426 else:
    427     import UserDict
    428 
    429     # Fake unsetenv() for Windows

    430     # not sure about os2 here but

    431     # I'm guessing they are the same.

    432 
    433     if name in ('os2', 'nt'):
    434         def unsetenv(key):
    435             putenv(key, "")
    436 
    437     if name == "riscos":
    438         # On RISC OS, all env access goes through getenv and putenv

    439         from riscosenviron import _Environ
    440     elif name in ('os2', 'nt'):  # Where Env Var Names Must Be UPPERCASE

    441         # But we store them as upper case

    442         class _Environ(UserDict.IterableUserDict):
    443             def __init__(self, environ):
    444                 UserDict.UserDict.__init__(self)
    445                 data = self.data
    446                 for k, v in environ.items():
    447                     data[k.upper()] = v
    448             def __setitem__(self, key, item):
    449                 putenv(key, item)
    450                 self.data[key.upper()] = item
    451             def __getitem__(self, key):
    452                 return self.data[key.upper()]
    453             try:
    454                 unsetenv
    455             except NameError:
    456                 def __delitem__(self, key):
    457                     del self.data[key.upper()]
    458             else:
    459                 def __delitem__(self, key):
    460                     unsetenv(key)
    461                     del self.data[key.upper()]
    462                 def clear(self):
    463                     for key in self.data.keys():
    464                         unsetenv(key)
    465                         del self.data[key]
    466                 def pop(self, key, *args):
    467                     unsetenv(key)
    468                     return self.data.pop(key.upper(), *args)
    469             def has_key(self, key):
    470                 return key.upper() in self.data
    471             def __contains__(self, key):
    472                 return key.upper() in self.data
    473             def get(self, key, failobj=None):
    474                 return self.data.get(key.upper(), failobj)
    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             def copy(self):
    492                 return dict(self)
    493 
    494     else:  # Where Env Var Names Can Be Mixed Case

    495         class _Environ(UserDict.IterableUserDict):
    496             def __init__(self, environ):
    497                 UserDict.UserDict.__init__(self)
    498                 self.data = environ
    499             def __setitem__(self, key, item):
    500                 putenv(key, item)
    501                 self.data[key] = item
    502             def update(self,  dict=None, **kwargs):
    503                 if dict:
    504                     try:
    505                         keys = dict.keys()
    506                     except AttributeError:
    507                         # List of (key, value)

    508                         for k, v in dict:
    509                             self[k] = v
    510                     else:
    511                         # got keys

    512                         # cannot use items(), since mappings

    513                         # may not have them.

    514                         for k in keys:
    515                             self[k] = dict[k]
    516                 if kwargs:
    517                     self.update(kwargs)
    518             try:
    519                 unsetenv
    520             except NameError:
    521                 pass
    522             else:
    523                 def __delitem__(self, key):
    524                     unsetenv(key)
    525                     del self.data[key]
    526                 def clear(self):
    527                     for key in self.data.keys():
    528                         unsetenv(key)
    529                         del self.data[key]
    530                 def pop(self, key, *args):
    531                     unsetenv(key)
    532                     return self.data.pop(key, *args)
    533             def copy(self):
    534                 return dict(self)
    535 
    536 
    537     environ = _Environ(environ)
    538 
    539 def getenv(key, default=None):
    540     """Get an environment variable, return None if it doesn't exist.
    541     The optional second argument can specify an alternate default."""
    542     return environ.get(key, default)
    543 __all__.append("getenv")
    544 
    545 def _exists(name):
    546     return name in globals()
    547 
    548 # Supply spawn*() (probably only for Unix)

    549 if _exists("fork") and not _exists("spawnv") and _exists("execv"):
    550 
    551     P_WAIT = 0
    552     P_NOWAIT = P_NOWAITO = 1
    553 
    554     # XXX Should we support P_DETACH?  I suppose it could fork()**2

    555     # and close the std I/O streams.  Also, P_OVERLAY is the same

    556     # as execv*()?

    557 
    558     def _spawnvef(mode, file, args, env, func):
    559         # Internal helper; func is the exec*() function to use

    560         pid = fork()
    561         if not pid:
    562             # Child

    563             try:
    564                 if env is None:
    565                     func(file, args)
    566                 else:
    567                     func(file, args, env)
    568             except:
    569                 _exit(127)
    570         else:
    571             # Parent

    572             if mode == P_NOWAIT:
    573                 return pid # Caller is responsible for waiting!

    574             while 1:
    575                 wpid, sts = waitpid(pid, 0)
    576                 if WIFSTOPPED(sts):
    577                     continue
    578                 elif WIFSIGNALED(sts):
    579                     return -WTERMSIG(sts)
    580                 elif WIFEXITED(sts):
    581                     return WEXITSTATUS(sts)
    582                 else:
    583                     raise error, "Not stopped, signaled or exited???"
    584 
    585     def spawnv(mode, file, args):
    586         """spawnv(mode, file, args) -> integer
    587 
    588 Execute file with arguments from args in a subprocess.
    589 If mode == P_NOWAIT return the pid of the process.
    590 If mode == P_WAIT return the process's exit code if it exits normally;
    591 otherwise return -SIG, where SIG is the signal that killed it. """
    592         return _spawnvef(mode, file, args, None, execv)
    593 
    594     def spawnve(mode, file, args, env):
    595         """spawnve(mode, file, args, env) -> integer
    596 
    597 Execute file with arguments from args in a subprocess with the
    598 specified environment.
    599 If mode == P_NOWAIT return the pid of the process.
    600 If mode == P_WAIT return the process's exit code if it exits normally;
    601 otherwise return -SIG, where SIG is the signal that killed it. """
    602         return _spawnvef(mode, file, args, env, execve)
    603 
    604     # Note: spawnvp[e] is't currently supported on Windows

    605 
    606     def spawnvp(mode, file, args):
    607         """spawnvp(mode, file, args) -> integer
    608 
    609 Execute file (which is looked for along $PATH) with arguments from
    610 args in a subprocess.
    611 If mode == P_NOWAIT return the pid of the process.
    612 If mode == P_WAIT return the process's exit code if it exits normally;
    613 otherwise return -SIG, where SIG is the signal that killed it. """
    614         return _spawnvef(mode, file, args, None, execvp)
    615 
    616     def spawnvpe(mode, file, args, env):
    617         """spawnvpe(mode, file, args, env) -> integer
    618 
    619 Execute file (which is looked for along $PATH) with arguments from
    620 args in a subprocess with the supplied environment.
    621 If mode == P_NOWAIT return the pid of the process.
    622 If mode == P_WAIT return the process's exit code if it exits normally;
    623 otherwise return -SIG, where SIG is the signal that killed it. """
    624         return _spawnvef(mode, file, args, env, execvpe)
    625 
    626 if _exists("spawnv"):
    627     # These aren't supplied by the basic Windows code

    628     # but can be easily implemented in Python

    629 
    630     def spawnl(mode, file, *args):
    631         """spawnl(mode, file, *args) -> integer
    632 
    633 Execute file with arguments from args in a subprocess.
    634 If mode == P_NOWAIT return the pid of the process.
    635 If mode == P_WAIT return the process's exit code if it exits normally;
    636 otherwise return -SIG, where SIG is the signal that killed it. """
    637         return spawnv(mode, file, args)
    638 
    639     def spawnle(mode, file, *args):
    640         """spawnle(mode, file, *args, env) -> integer
    641 
    642 Execute file with arguments from args in a subprocess with the
    643 supplied environment.
    644 If mode == P_NOWAIT return the pid of the process.
    645 If mode == P_WAIT return the process's exit code if it exits normally;
    646 otherwise return -SIG, where SIG is the signal that killed it. """
    647         env = args[-1]
    648         return spawnve(mode, file, args[:-1], env)
    649 
    650 
    651     __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
    652 
    653 
    654 if _exists("spawnvp"):
    655     # At the moment, Windows doesn't implement spawnvp[e],

    656     # so it won't have spawnlp[e] either.

    657     def spawnlp(mode, file, *args):
    658         """spawnlp(mode, file, *args) -> integer
    659 
    660 Execute file (which is looked for along $PATH) with arguments from
    661 args in a subprocess with the supplied environment.
    662 If mode == P_NOWAIT return the pid of the process.
    663 If mode == P_WAIT return the process's exit code if it exits normally;
    664 otherwise return -SIG, where SIG is the signal that killed it. """
    665         return spawnvp(mode, file, args)
    666 
    667     def spawnlpe(mode, file, *args):
    668         """spawnlpe(mode, file, *args, env) -> integer
    669 
    670 Execute file (which is looked for along $PATH) with arguments from
    671 args in a subprocess with the supplied environment.
    672 If mode == P_NOWAIT return the pid of the process.
    673 If mode == P_WAIT return the process's exit code if it exits normally;
    674 otherwise return -SIG, where SIG is the signal that killed it. """
    675         env = args[-1]
    676         return spawnvpe(mode, file, args[:-1], env)
    677 
    678 
    679     __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
    680 
    681 
    682 # Supply popen2 etc. (for Unix)

    683 if _exists("fork"):
    684     if not _exists("popen2"):
    685         def popen2(cmd, mode="t", bufsize=-1):
    686             """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
    687             may be a sequence, in which case arguments will be passed directly to
    688             the program without shell intervention (as with os.spawnv()).  If 'cmd'
    689             is a string it will be passed to the shell (as with os.system()). If
    690             'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
    691             file objects (child_stdin, child_stdout) are returned."""
    692             import warnings
    693             msg = "os.popen2 is deprecated.  Use the subprocess module."
    694             warnings.warn(msg, DeprecationWarning, stacklevel=2)
    695 
    696             import subprocess
    697             PIPE = subprocess.PIPE
    698             p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
    699                                  bufsize=bufsize, stdin=PIPE, stdout=PIPE,
    700                                  close_fds=True)
    701             return p.stdin, p.stdout
    702         __all__.append("popen2")
    703 
    704     if not _exists("popen3"):
    705         def popen3(cmd, mode="t", bufsize=-1):
    706             """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
    707             may be a sequence, in which case arguments will be passed directly to
    708             the program without shell intervention (as with os.spawnv()).  If 'cmd'
    709             is a string it will be passed to the shell (as with os.system()). If
    710             'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
    711             file objects (child_stdin, child_stdout, child_stderr) are returned."""
    712             import warnings
    713             msg = "os.popen3 is deprecated.  Use the subprocess module."
    714             warnings.warn(msg, DeprecationWarning, stacklevel=2)
    715 
    716             import subprocess
    717             PIPE = subprocess.PIPE
    718             p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
    719                                  bufsize=bufsize, stdin=PIPE, stdout=PIPE,
    720                                  stderr=PIPE, close_fds=True)
    721             return p.stdin, p.stdout, p.stderr
    722         __all__.append("popen3")
    723 
    724     if not _exists("popen4"):
    725         def popen4(cmd, mode="t", bufsize=-1):
    726             """Execute the shell command 'cmd' in a sub-process.  On UNIX, 'cmd'
    727             may be a sequence, in which case arguments will be passed directly to
    728             the program without shell intervention (as with os.spawnv()).  If 'cmd'
    729             is a string it will be passed to the shell (as with os.system()). If
    730             'bufsize' is specified, it sets the buffer size for the I/O pipes.  The
    731             file objects (child_stdin, child_stdout_stderr) are returned."""
    732             import warnings
    733             msg = "os.popen4 is deprecated.  Use the subprocess module."
    734             warnings.warn(msg, DeprecationWarning, stacklevel=2)
    735 
    736             import subprocess
    737             PIPE = subprocess.PIPE
    738             p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
    739                                  bufsize=bufsize, stdin=PIPE, stdout=PIPE,
    740                                  stderr=subprocess.STDOUT, close_fds=True)
    741             return p.stdin, p.stdout
    742         __all__.append("popen4")
    743 
    744 import copy_reg as _copy_reg
    745 
    746 def _make_stat_result(tup, dict):
    747     return stat_result(tup, dict)
    748 
    749 def _pickle_stat_result(sr):
    750     (type, args) = sr.__reduce__()
    751     return (_make_stat_result, args)
    752 
    753 try:
    754     _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
    755 except NameError: # stat_result may not exist

    756     pass
    757 
    758 def _make_statvfs_result(tup, dict):
    759     return statvfs_result(tup, dict)
    760 
    761 def _pickle_statvfs_result(sr):
    762     (type, args) = sr.__reduce__()
    763     return (_make_statvfs_result, args)
    764 
    765 try:
    766     _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
    767                      _make_statvfs_result)
    768 except NameError: # statvfs_result may not exist

    769     pass
    770