Home | History | Annotate | Download | only in Lib
      1 """OS routines for Mac, NT, Posix, or UEFI depending on what system we're on.
      2 
      3 This exports:
      4   - all functions from edk2, posix, nt, os2, or ce, e.g. unlink, stat, etc.
      5   - os.path is one of the modules uefipath, posixpath, or ntpath
      6   - os.name is 'edk2', '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 elif 'edk2' in _names:
    117     name = 'edk2'
    118     linesep = '\n'
    119     from edk2 import *
    120     try:
    121         from edk2 import _exit
    122     except ImportError:
    123         pass
    124     import ntpath as path
    125 
    126     import edk2
    127     __all__.extend(_get_exports_list(edk2))
    128     del edk2
    129 
    130 else:
    131     raise ImportError, 'no os specific module found'
    132 
    133 sys.modules['os.path'] = path
    134 from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
    135     devnull)
    136 
    137 del _names
    138 
    139 # Python uses fixed values for the SEEK_ constants; they are mapped

    140 # to native constants if necessary in posixmodule.c

    141 SEEK_SET = 0
    142 SEEK_CUR = 1
    143 SEEK_END = 2
    144 
    145 #'

    146 
    147 # Super directory utilities.

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

    149 
    150 def makedirs(name, mode=0777):
    151     """makedirs(path [, mode=0777])
    152 
    153     Super-mkdir; create a leaf directory and all intermediate ones.
    154     Works like mkdir, except that any intermediate path segment (not
    155     just the rightmost) will be created if it does not exist.  This is
    156     recursive.
    157 
    158     """
    159     head, tail = path.split(name)
    160     if not tail:
    161         head, tail = path.split(head)
    162     if head and tail and not path.exists(head):
    163         try:
    164             makedirs(head, mode)
    165         except OSError, e:
    166             # be happy if someone already created the path

    167             if e.errno != errno.EEXIST:
    168                 raise
    169         if tail == curdir:           # xxx/newdir/. exists if xxx/newdir exists

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

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

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

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

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

    287     try:
    288         # Note that listdir and error are globals in this module due

    289         # to earlier import-*.

    290         names = listdir(top)
    291     except error, err:
    292         if onerror is not None:
    293             onerror(err)
    294         return
    295 
    296     dirs, nondirs = [], []
    297     for name in names:
    298         if isdir(join(top, name)):
    299             dirs.append(name)
    300         else:
    301             nondirs.append(name)
    302 
    303     if topdown:
    304         yield top, dirs, nondirs
    305     for name in dirs:
    306         new_path = join(top, name)
    307         if followlinks or not islink(new_path):
    308             for x in walk(new_path, topdown, onerror, followlinks):
    309                 yield x
    310     if not topdown:
    311         yield top, dirs, nondirs
    312 
    313 __all__.append("walk")
    314 
    315 # Make sure os.environ exists, at least

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

    406 try:
    407     # This will fail if there's no putenv

    408     putenv
    409 except NameError:
    410     pass
    411 else:
    412     import UserDict
    413 
    414     # Fake unsetenv() for Windows

    415     # not sure about os2 here but

    416     # I'm guessing they are the same.

    417 
    418     if name in ('os2', 'nt'):
    419         def unsetenv(key):
    420             putenv(key, "")
    421 
    422     if name == "riscos":
    423         # On RISC OS, all env access goes through getenv and putenv

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

    426         # But we store them as upper case

    427         class _Environ(UserDict.IterableUserDict):
    428             def __init__(self, environ):
    429                 UserDict.UserDict.__init__(self)
    430                 data = self.data
    431                 for k, v in environ.items():
    432                     data[k.upper()] = v
    433             def __setitem__(self, key, item):
    434                 putenv(key, item)
    435                 self.data[key.upper()] = item
    436             def __getitem__(self, key):
    437                 return self.data[key.upper()]
    438             try:
    439                 unsetenv
    440             except NameError:
    441                 def __delitem__(self, key):
    442                     del self.data[key.upper()]
    443             else:
    444                 def __delitem__(self, key):
    445                     unsetenv(key)
    446                     del self.data[key.upper()]
    447                 def clear(self):
    448                     for key in self.data.keys():
    449                         unsetenv(key)
    450                         del self.data[key]
    451                 def pop(self, key, *args):
    452                     unsetenv(key)
    453                     return self.data.pop(key.upper(), *args)
    454             def has_key(self, key):
    455                 return key.upper() in self.data
    456             def __contains__(self, key):
    457                 return key.upper() in self.data
    458             def get(self, key, failobj=None):
    459                 return self.data.get(key.upper(), failobj)
    460             def update(self, dict=None, **kwargs):
    461                 if dict:
    462                     try:
    463                         keys = dict.keys()
    464                     except AttributeError:
    465                         # List of (key, value)

    466                         for k, v in dict:
    467                             self[k] = v
    468                     else:
    469                         # got keys

    470                         # cannot use items(), since mappings

    471                         # may not have them.

    472                         for k in keys:
    473                             self[k] = dict[k]
    474                 if kwargs:
    475                     self.update(kwargs)
    476             def copy(self):
    477                 return dict(self)
    478 
    479     else:  # Where Env Var Names Can Be Mixed Case

    480         class _Environ(UserDict.IterableUserDict):
    481             def __init__(self, environ):
    482                 UserDict.UserDict.__init__(self)
    483                 self.data = environ
    484             def __setitem__(self, key, item):
    485                 putenv(key, item)
    486                 self.data[key] = item
    487             def update(self,  dict=None, **kwargs):
    488                 if dict:
    489                     try:
    490                         keys = dict.keys()
    491                     except AttributeError:
    492                         # List of (key, value)

    493                         for k, v in dict:
    494                             self[k] = v
    495                     else:
    496                         # got keys

    497                         # cannot use items(), since mappings

    498                         # may not have them.

    499                         for k in keys:
    500                             self[k] = dict[k]
    501                 if kwargs:
    502                     self.update(kwargs)
    503             try:
    504                 unsetenv
    505             except NameError:
    506                 pass
    507             else:
    508                 def __delitem__(self, key):
    509                     unsetenv(key)
    510                     del self.data[key]
    511                 def clear(self):
    512                     for key in self.data.keys():
    513                         unsetenv(key)
    514                         del self.data[key]
    515                 def pop(self, key, *args):
    516                     unsetenv(key)
    517                     return self.data.pop(key, *args)
    518             def copy(self):
    519                 return dict(self)
    520 
    521 
    522     environ = _Environ(environ)
    523 
    524 def getenv(key, default=None):
    525     """Get an environment variable, return None if it doesn't exist.
    526     The optional second argument can specify an alternate default."""
    527     return environ.get(key, default)
    528 __all__.append("getenv")
    529 
    530 def _exists(name):
    531     return name in globals()
    532 
    533 # Supply spawn*() (probably only for Unix)

    534 if _exists("fork") and not _exists("spawnv") and _exists("execv"):
    535 
    536     P_WAIT = 0
    537     P_NOWAIT = P_NOWAITO = 1
    538 
    539     # XXX Should we support P_DETACH?  I suppose it could fork()**2

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

    541     # as execv*()?

    542 
    543     def _spawnvef(mode, file, args, env, func):
    544         # Internal helper; func is the exec*() function to use

    545         pid = fork()
    546         if not pid:
    547             # Child

    548             try:
    549                 if env is None:
    550                     func(file, args)
    551                 else:
    552                     func(file, args, env)
    553             except:
    554                 _exit(127)
    555         else:
    556             # Parent

    557             if mode == P_NOWAIT:
    558                 return pid # Caller is responsible for waiting!

    559             while 1:
    560                 wpid, sts = waitpid(pid, 0)
    561                 if WIFSTOPPED(sts):
    562                     continue
    563                 elif WIFSIGNALED(sts):
    564                     return -WTERMSIG(sts)
    565                 elif WIFEXITED(sts):
    566                     return WEXITSTATUS(sts)
    567                 else:
    568                     raise error, "Not stopped, signaled or exited???"
    569 
    570     def spawnv(mode, file, args):
    571         """spawnv(mode, file, args) -> integer
    572 
    573 Execute file with arguments from args in a subprocess.
    574 If mode == P_NOWAIT return the pid of the process.
    575 If mode == P_WAIT return the process's exit code if it exits normally;
    576 otherwise return -SIG, where SIG is the signal that killed it. """
    577         return _spawnvef(mode, file, args, None, execv)
    578 
    579     def spawnve(mode, file, args, env):
    580         """spawnve(mode, file, args, env) -> integer
    581 
    582 Execute file with arguments from args in a subprocess with the
    583 specified environment.
    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, env, execve)
    588 
    589     # Note: spawnvp[e] is't currently supported on Windows

    590 
    591     def spawnvp(mode, file, args):
    592         """spawnvp(mode, file, args) -> integer
    593 
    594 Execute file (which is looked for along $PATH) with arguments from
    595 args in a subprocess.
    596 If mode == P_NOWAIT return the pid of the process.
    597 If mode == P_WAIT return the process's exit code if it exits normally;
    598 otherwise return -SIG, where SIG is the signal that killed it. """
    599         return _spawnvef(mode, file, args, None, execvp)
    600 
    601     def spawnvpe(mode, file, args, env):
    602         """spawnvpe(mode, file, args, env) -> integer
    603 
    604 Execute file (which is looked for along $PATH) with arguments from
    605 args in a subprocess with the supplied environment.
    606 If mode == P_NOWAIT return the pid of the process.
    607 If mode == P_WAIT return the process's exit code if it exits normally;
    608 otherwise return -SIG, where SIG is the signal that killed it. """
    609         return _spawnvef(mode, file, args, env, execvpe)
    610 
    611 if _exists("spawnv"):
    612     # These aren't supplied by the basic Windows code

    613     # but can be easily implemented in Python

    614 
    615     def spawnl(mode, file, *args):
    616         """spawnl(mode, file, *args) -> integer
    617 
    618 Execute file with arguments from args in a subprocess.
    619 If mode == P_NOWAIT return the pid of the process.
    620 If mode == P_WAIT return the process's exit code if it exits normally;
    621 otherwise return -SIG, where SIG is the signal that killed it. """
    622         return spawnv(mode, file, args)
    623 
    624     def spawnle(mode, file, *args):
    625         """spawnle(mode, file, *args, env) -> integer
    626 
    627 Execute file with arguments from args in a subprocess with the
    628 supplied environment.
    629 If mode == P_NOWAIT return the pid of the process.
    630 If mode == P_WAIT return the process's exit code if it exits normally;
    631 otherwise return -SIG, where SIG is the signal that killed it. """
    632         env = args[-1]
    633         return spawnve(mode, file, args[:-1], env)
    634 
    635 
    636     __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
    637 
    638 
    639 if _exists("spawnvp"):
    640     # At the moment, Windows doesn't implement spawnvp[e],

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

    642     def spawnlp(mode, file, *args):
    643         """spawnlp(mode, file, *args) -> integer
    644 
    645 Execute file (which is looked for along $PATH) with arguments from
    646 args in a subprocess with the supplied environment.
    647 If mode == P_NOWAIT return the pid of the process.
    648 If mode == P_WAIT return the process's exit code if it exits normally;
    649 otherwise return -SIG, where SIG is the signal that killed it. """
    650         return spawnvp(mode, file, args)
    651 
    652     def spawnlpe(mode, file, *args):
    653         """spawnlpe(mode, file, *args, env) -> integer
    654 
    655 Execute file (which is looked for along $PATH) with arguments from
    656 args in a subprocess with the supplied environment.
    657 If mode == P_NOWAIT return the pid of the process.
    658 If mode == P_WAIT return the process's exit code if it exits normally;
    659 otherwise return -SIG, where SIG is the signal that killed it. """
    660         env = args[-1]
    661         return spawnvpe(mode, file, args[:-1], env)
    662 
    663 
    664     __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
    665 
    666 
    667 # Supply popen2 etc. (for Unix)

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

    741     pass
    742 
    743 def _make_statvfs_result(tup, dict):
    744     return statvfs_result(tup, dict)
    745 
    746 def _pickle_statvfs_result(sr):
    747     (type, args) = sr.__reduce__()
    748     return (_make_statvfs_result, args)
    749 
    750 try:
    751     _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
    752                      _make_statvfs_result)
    753 except NameError: # statvfs_result may not exist

    754     pass
    755 
    756 if not _exists("urandom"):
    757     def urandom(n):
    758         """urandom(n) -> str
    759 
    760         Return a string of n random bytes suitable for cryptographic use.
    761 
    762         """
    763         try:
    764             _urandomfd = open("/dev/urandom", O_RDONLY)
    765         except (OSError, IOError):
    766             raise NotImplementedError("/dev/urandom (or equivalent) not found")
    767         try:
    768             bs = b""
    769             while n > len(bs):
    770                 bs += read(_urandomfd, n - len(bs))
    771         finally:
    772             close(_urandomfd)
    773         return bs
    774