xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/os.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Workerr"""OS routines for NT or Posix depending on what system we're on.
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard WorkerThis exports:
4*cda5da8dSAndroid Build Coastguard Worker  - all functions from posix or nt, e.g. unlink, stat, etc.
5*cda5da8dSAndroid Build Coastguard Worker  - os.path is either posixpath or ntpath
6*cda5da8dSAndroid Build Coastguard Worker  - os.name is either 'posix' or 'nt'
7*cda5da8dSAndroid Build Coastguard Worker  - os.curdir is a string representing the current directory (always '.')
8*cda5da8dSAndroid Build Coastguard Worker  - os.pardir is a string representing the parent directory (always '..')
9*cda5da8dSAndroid Build Coastguard Worker  - os.sep is the (or a most common) pathname separator ('/' or '\\')
10*cda5da8dSAndroid Build Coastguard Worker  - os.extsep is the extension separator (always '.')
11*cda5da8dSAndroid Build Coastguard Worker  - os.altsep is the alternate pathname separator (None or '/')
12*cda5da8dSAndroid Build Coastguard Worker  - os.pathsep is the component separator used in $PATH etc
13*cda5da8dSAndroid Build Coastguard Worker  - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
14*cda5da8dSAndroid Build Coastguard Worker  - os.defpath is the default search path for executables
15*cda5da8dSAndroid Build Coastguard Worker  - os.devnull is the file path of the null device ('/dev/null', etc.)
16*cda5da8dSAndroid Build Coastguard Worker
17*cda5da8dSAndroid Build Coastguard WorkerPrograms that import and use 'os' stand a better chance of being
18*cda5da8dSAndroid Build Coastguard Workerportable between different platforms.  Of course, they must then
19*cda5da8dSAndroid Build Coastguard Workeronly use functions that are defined by all platforms (e.g., unlink
20*cda5da8dSAndroid Build Coastguard Workerand opendir), and leave all pathname manipulation to os.path
21*cda5da8dSAndroid Build Coastguard Worker(e.g., split and join).
22*cda5da8dSAndroid Build Coastguard Worker"""
23*cda5da8dSAndroid Build Coastguard Worker
24*cda5da8dSAndroid Build Coastguard Worker#'
25*cda5da8dSAndroid Build Coastguard Workerimport abc
26*cda5da8dSAndroid Build Coastguard Workerimport sys
27*cda5da8dSAndroid Build Coastguard Workerimport stat as st
28*cda5da8dSAndroid Build Coastguard Worker
29*cda5da8dSAndroid Build Coastguard Workerfrom _collections_abc import _check_methods
30*cda5da8dSAndroid Build Coastguard Worker
31*cda5da8dSAndroid Build Coastguard WorkerGenericAlias = type(list[int])
32*cda5da8dSAndroid Build Coastguard Worker
33*cda5da8dSAndroid Build Coastguard Worker_names = sys.builtin_module_names
34*cda5da8dSAndroid Build Coastguard Worker
35*cda5da8dSAndroid Build Coastguard Worker# Note:  more names are added to __all__ later.
36*cda5da8dSAndroid Build Coastguard Worker__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
37*cda5da8dSAndroid Build Coastguard Worker           "defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR",
38*cda5da8dSAndroid Build Coastguard Worker           "SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen",
39*cda5da8dSAndroid Build Coastguard Worker           "extsep"]
40*cda5da8dSAndroid Build Coastguard Worker
41*cda5da8dSAndroid Build Coastguard Workerdef _exists(name):
42*cda5da8dSAndroid Build Coastguard Worker    return name in globals()
43*cda5da8dSAndroid Build Coastguard Worker
44*cda5da8dSAndroid Build Coastguard Workerdef _get_exports_list(module):
45*cda5da8dSAndroid Build Coastguard Worker    try:
46*cda5da8dSAndroid Build Coastguard Worker        return list(module.__all__)
47*cda5da8dSAndroid Build Coastguard Worker    except AttributeError:
48*cda5da8dSAndroid Build Coastguard Worker        return [n for n in dir(module) if n[0] != '_']
49*cda5da8dSAndroid Build Coastguard Worker
50*cda5da8dSAndroid Build Coastguard Worker# Any new dependencies of the os module and/or changes in path separator
51*cda5da8dSAndroid Build Coastguard Worker# requires updating importlib as well.
52*cda5da8dSAndroid Build Coastguard Workerif 'posix' in _names:
53*cda5da8dSAndroid Build Coastguard Worker    name = 'posix'
54*cda5da8dSAndroid Build Coastguard Worker    linesep = '\n'
55*cda5da8dSAndroid Build Coastguard Worker    from posix import *
56*cda5da8dSAndroid Build Coastguard Worker    try:
57*cda5da8dSAndroid Build Coastguard Worker        from posix import _exit
58*cda5da8dSAndroid Build Coastguard Worker        __all__.append('_exit')
59*cda5da8dSAndroid Build Coastguard Worker    except ImportError:
60*cda5da8dSAndroid Build Coastguard Worker        pass
61*cda5da8dSAndroid Build Coastguard Worker    import posixpath as path
62*cda5da8dSAndroid Build Coastguard Worker
63*cda5da8dSAndroid Build Coastguard Worker    try:
64*cda5da8dSAndroid Build Coastguard Worker        from posix import _have_functions
65*cda5da8dSAndroid Build Coastguard Worker    except ImportError:
66*cda5da8dSAndroid Build Coastguard Worker        pass
67*cda5da8dSAndroid Build Coastguard Worker
68*cda5da8dSAndroid Build Coastguard Worker    import posix
69*cda5da8dSAndroid Build Coastguard Worker    __all__.extend(_get_exports_list(posix))
70*cda5da8dSAndroid Build Coastguard Worker    del posix
71*cda5da8dSAndroid Build Coastguard Worker
72*cda5da8dSAndroid Build Coastguard Workerelif 'nt' in _names:
73*cda5da8dSAndroid Build Coastguard Worker    name = 'nt'
74*cda5da8dSAndroid Build Coastguard Worker    linesep = '\r\n'
75*cda5da8dSAndroid Build Coastguard Worker    from nt import *
76*cda5da8dSAndroid Build Coastguard Worker    try:
77*cda5da8dSAndroid Build Coastguard Worker        from nt import _exit
78*cda5da8dSAndroid Build Coastguard Worker        __all__.append('_exit')
79*cda5da8dSAndroid Build Coastguard Worker    except ImportError:
80*cda5da8dSAndroid Build Coastguard Worker        pass
81*cda5da8dSAndroid Build Coastguard Worker    import ntpath as path
82*cda5da8dSAndroid Build Coastguard Worker
83*cda5da8dSAndroid Build Coastguard Worker    import nt
84*cda5da8dSAndroid Build Coastguard Worker    __all__.extend(_get_exports_list(nt))
85*cda5da8dSAndroid Build Coastguard Worker    del nt
86*cda5da8dSAndroid Build Coastguard Worker
87*cda5da8dSAndroid Build Coastguard Worker    try:
88*cda5da8dSAndroid Build Coastguard Worker        from nt import _have_functions
89*cda5da8dSAndroid Build Coastguard Worker    except ImportError:
90*cda5da8dSAndroid Build Coastguard Worker        pass
91*cda5da8dSAndroid Build Coastguard Worker
92*cda5da8dSAndroid Build Coastguard Workerelse:
93*cda5da8dSAndroid Build Coastguard Worker    raise ImportError('no os specific module found')
94*cda5da8dSAndroid Build Coastguard Worker
95*cda5da8dSAndroid Build Coastguard Workersys.modules['os.path'] = path
96*cda5da8dSAndroid Build Coastguard Workerfrom os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
97*cda5da8dSAndroid Build Coastguard Worker    devnull)
98*cda5da8dSAndroid Build Coastguard Worker
99*cda5da8dSAndroid Build Coastguard Workerdel _names
100*cda5da8dSAndroid Build Coastguard Worker
101*cda5da8dSAndroid Build Coastguard Worker
102*cda5da8dSAndroid Build Coastguard Workerif _exists("_have_functions"):
103*cda5da8dSAndroid Build Coastguard Worker    _globals = globals()
104*cda5da8dSAndroid Build Coastguard Worker    def _add(str, fn):
105*cda5da8dSAndroid Build Coastguard Worker        if (fn in _globals) and (str in _have_functions):
106*cda5da8dSAndroid Build Coastguard Worker            _set.add(_globals[fn])
107*cda5da8dSAndroid Build Coastguard Worker
108*cda5da8dSAndroid Build Coastguard Worker    _set = set()
109*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FACCESSAT",  "access")
110*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FCHMODAT",   "chmod")
111*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FCHOWNAT",   "chown")
112*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FSTATAT",    "stat")
113*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FUTIMESAT",  "utime")
114*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_LINKAT",     "link")
115*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_MKDIRAT",    "mkdir")
116*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_MKFIFOAT",   "mkfifo")
117*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_MKNODAT",    "mknod")
118*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_OPENAT",     "open")
119*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_READLINKAT", "readlink")
120*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_RENAMEAT",   "rename")
121*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_SYMLINKAT",  "symlink")
122*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_UNLINKAT",   "unlink")
123*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_UNLINKAT",   "rmdir")
124*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_UTIMENSAT",  "utime")
125*cda5da8dSAndroid Build Coastguard Worker    supports_dir_fd = _set
126*cda5da8dSAndroid Build Coastguard Worker
127*cda5da8dSAndroid Build Coastguard Worker    _set = set()
128*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FACCESSAT",  "access")
129*cda5da8dSAndroid Build Coastguard Worker    supports_effective_ids = _set
130*cda5da8dSAndroid Build Coastguard Worker
131*cda5da8dSAndroid Build Coastguard Worker    _set = set()
132*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FCHDIR",     "chdir")
133*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FCHMOD",     "chmod")
134*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FCHOWN",     "chown")
135*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FDOPENDIR",  "listdir")
136*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FDOPENDIR",  "scandir")
137*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FEXECVE",    "execve")
138*cda5da8dSAndroid Build Coastguard Worker    _set.add(stat) # fstat always works
139*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FTRUNCATE",  "truncate")
140*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FUTIMENS",   "utime")
141*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FUTIMES",    "utime")
142*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FPATHCONF",  "pathconf")
143*cda5da8dSAndroid Build Coastguard Worker    if _exists("statvfs") and _exists("fstatvfs"): # mac os x10.3
144*cda5da8dSAndroid Build Coastguard Worker        _add("HAVE_FSTATVFS", "statvfs")
145*cda5da8dSAndroid Build Coastguard Worker    supports_fd = _set
146*cda5da8dSAndroid Build Coastguard Worker
147*cda5da8dSAndroid Build Coastguard Worker    _set = set()
148*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FACCESSAT",  "access")
149*cda5da8dSAndroid Build Coastguard Worker    # Some platforms don't support lchmod().  Often the function exists
150*cda5da8dSAndroid Build Coastguard Worker    # anyway, as a stub that always returns ENOSUP or perhaps EOPNOTSUPP.
151*cda5da8dSAndroid Build Coastguard Worker    # (No, I don't know why that's a good design.)  ./configure will detect
152*cda5da8dSAndroid Build Coastguard Worker    # this and reject it--so HAVE_LCHMOD still won't be defined on such
153*cda5da8dSAndroid Build Coastguard Worker    # platforms.  This is Very Helpful.
154*cda5da8dSAndroid Build Coastguard Worker    #
155*cda5da8dSAndroid Build Coastguard Worker    # However, sometimes platforms without a working lchmod() *do* have
156*cda5da8dSAndroid Build Coastguard Worker    # fchmodat().  (Examples: Linux kernel 3.2 with glibc 2.15,
157*cda5da8dSAndroid Build Coastguard Worker    # OpenIndiana 3.x.)  And fchmodat() has a flag that theoretically makes
158*cda5da8dSAndroid Build Coastguard Worker    # it behave like lchmod().  So in theory it would be a suitable
159*cda5da8dSAndroid Build Coastguard Worker    # replacement for lchmod().  But when lchmod() doesn't work, fchmodat()'s
160*cda5da8dSAndroid Build Coastguard Worker    # flag doesn't work *either*.  Sadly ./configure isn't sophisticated
161*cda5da8dSAndroid Build Coastguard Worker    # enough to detect this condition--it only determines whether or not
162*cda5da8dSAndroid Build Coastguard Worker    # fchmodat() minimally works.
163*cda5da8dSAndroid Build Coastguard Worker    #
164*cda5da8dSAndroid Build Coastguard Worker    # Therefore we simply ignore fchmodat() when deciding whether or not
165*cda5da8dSAndroid Build Coastguard Worker    # os.chmod supports follow_symlinks.  Just checking lchmod() is
166*cda5da8dSAndroid Build Coastguard Worker    # sufficient.  After all--if you have a working fchmodat(), your
167*cda5da8dSAndroid Build Coastguard Worker    # lchmod() almost certainly works too.
168*cda5da8dSAndroid Build Coastguard Worker    #
169*cda5da8dSAndroid Build Coastguard Worker    # _add("HAVE_FCHMODAT",   "chmod")
170*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FCHOWNAT",   "chown")
171*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FSTATAT",    "stat")
172*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_LCHFLAGS",   "chflags")
173*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_LCHMOD",     "chmod")
174*cda5da8dSAndroid Build Coastguard Worker    if _exists("lchown"): # mac os x10.3
175*cda5da8dSAndroid Build Coastguard Worker        _add("HAVE_LCHOWN", "chown")
176*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_LINKAT",     "link")
177*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_LUTIMES",    "utime")
178*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_LSTAT",      "stat")
179*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_FSTATAT",    "stat")
180*cda5da8dSAndroid Build Coastguard Worker    _add("HAVE_UTIMENSAT",  "utime")
181*cda5da8dSAndroid Build Coastguard Worker    _add("MS_WINDOWS",      "stat")
182*cda5da8dSAndroid Build Coastguard Worker    supports_follow_symlinks = _set
183*cda5da8dSAndroid Build Coastguard Worker
184*cda5da8dSAndroid Build Coastguard Worker    del _set
185*cda5da8dSAndroid Build Coastguard Worker    del _have_functions
186*cda5da8dSAndroid Build Coastguard Worker    del _globals
187*cda5da8dSAndroid Build Coastguard Worker    del _add
188*cda5da8dSAndroid Build Coastguard Worker
189*cda5da8dSAndroid Build Coastguard Worker
190*cda5da8dSAndroid Build Coastguard Worker# Python uses fixed values for the SEEK_ constants; they are mapped
191*cda5da8dSAndroid Build Coastguard Worker# to native constants if necessary in posixmodule.c
192*cda5da8dSAndroid Build Coastguard Worker# Other possible SEEK values are directly imported from posixmodule.c
193*cda5da8dSAndroid Build Coastguard WorkerSEEK_SET = 0
194*cda5da8dSAndroid Build Coastguard WorkerSEEK_CUR = 1
195*cda5da8dSAndroid Build Coastguard WorkerSEEK_END = 2
196*cda5da8dSAndroid Build Coastguard Worker
197*cda5da8dSAndroid Build Coastguard Worker# Super directory utilities.
198*cda5da8dSAndroid Build Coastguard Worker# (Inspired by Eric Raymond; the doc strings are mostly his)
199*cda5da8dSAndroid Build Coastguard Worker
200*cda5da8dSAndroid Build Coastguard Workerdef makedirs(name, mode=0o777, exist_ok=False):
201*cda5da8dSAndroid Build Coastguard Worker    """makedirs(name [, mode=0o777][, exist_ok=False])
202*cda5da8dSAndroid Build Coastguard Worker
203*cda5da8dSAndroid Build Coastguard Worker    Super-mkdir; create a leaf directory and all intermediate ones.  Works like
204*cda5da8dSAndroid Build Coastguard Worker    mkdir, except that any intermediate path segment (not just the rightmost)
205*cda5da8dSAndroid Build Coastguard Worker    will be created if it does not exist. If the target directory already
206*cda5da8dSAndroid Build Coastguard Worker    exists, raise an OSError if exist_ok is False. Otherwise no exception is
207*cda5da8dSAndroid Build Coastguard Worker    raised.  This is recursive.
208*cda5da8dSAndroid Build Coastguard Worker
209*cda5da8dSAndroid Build Coastguard Worker    """
210*cda5da8dSAndroid Build Coastguard Worker    head, tail = path.split(name)
211*cda5da8dSAndroid Build Coastguard Worker    if not tail:
212*cda5da8dSAndroid Build Coastguard Worker        head, tail = path.split(head)
213*cda5da8dSAndroid Build Coastguard Worker    if head and tail and not path.exists(head):
214*cda5da8dSAndroid Build Coastguard Worker        try:
215*cda5da8dSAndroid Build Coastguard Worker            makedirs(head, exist_ok=exist_ok)
216*cda5da8dSAndroid Build Coastguard Worker        except FileExistsError:
217*cda5da8dSAndroid Build Coastguard Worker            # Defeats race condition when another thread created the path
218*cda5da8dSAndroid Build Coastguard Worker            pass
219*cda5da8dSAndroid Build Coastguard Worker        cdir = curdir
220*cda5da8dSAndroid Build Coastguard Worker        if isinstance(tail, bytes):
221*cda5da8dSAndroid Build Coastguard Worker            cdir = bytes(curdir, 'ASCII')
222*cda5da8dSAndroid Build Coastguard Worker        if tail == cdir:           # xxx/newdir/. exists if xxx/newdir exists
223*cda5da8dSAndroid Build Coastguard Worker            return
224*cda5da8dSAndroid Build Coastguard Worker    try:
225*cda5da8dSAndroid Build Coastguard Worker        mkdir(name, mode)
226*cda5da8dSAndroid Build Coastguard Worker    except OSError:
227*cda5da8dSAndroid Build Coastguard Worker        # Cannot rely on checking for EEXIST, since the operating system
228*cda5da8dSAndroid Build Coastguard Worker        # could give priority to other errors like EACCES or EROFS
229*cda5da8dSAndroid Build Coastguard Worker        if not exist_ok or not path.isdir(name):
230*cda5da8dSAndroid Build Coastguard Worker            raise
231*cda5da8dSAndroid Build Coastguard Worker
232*cda5da8dSAndroid Build Coastguard Workerdef removedirs(name):
233*cda5da8dSAndroid Build Coastguard Worker    """removedirs(name)
234*cda5da8dSAndroid Build Coastguard Worker
235*cda5da8dSAndroid Build Coastguard Worker    Super-rmdir; remove a leaf directory and all empty intermediate
236*cda5da8dSAndroid Build Coastguard Worker    ones.  Works like rmdir except that, if the leaf directory is
237*cda5da8dSAndroid Build Coastguard Worker    successfully removed, directories corresponding to rightmost path
238*cda5da8dSAndroid Build Coastguard Worker    segments will be pruned away until either the whole path is
239*cda5da8dSAndroid Build Coastguard Worker    consumed or an error occurs.  Errors during this latter phase are
240*cda5da8dSAndroid Build Coastguard Worker    ignored -- they generally mean that a directory was not empty.
241*cda5da8dSAndroid Build Coastguard Worker
242*cda5da8dSAndroid Build Coastguard Worker    """
243*cda5da8dSAndroid Build Coastguard Worker    rmdir(name)
244*cda5da8dSAndroid Build Coastguard Worker    head, tail = path.split(name)
245*cda5da8dSAndroid Build Coastguard Worker    if not tail:
246*cda5da8dSAndroid Build Coastguard Worker        head, tail = path.split(head)
247*cda5da8dSAndroid Build Coastguard Worker    while head and tail:
248*cda5da8dSAndroid Build Coastguard Worker        try:
249*cda5da8dSAndroid Build Coastguard Worker            rmdir(head)
250*cda5da8dSAndroid Build Coastguard Worker        except OSError:
251*cda5da8dSAndroid Build Coastguard Worker            break
252*cda5da8dSAndroid Build Coastguard Worker        head, tail = path.split(head)
253*cda5da8dSAndroid Build Coastguard Worker
254*cda5da8dSAndroid Build Coastguard Workerdef renames(old, new):
255*cda5da8dSAndroid Build Coastguard Worker    """renames(old, new)
256*cda5da8dSAndroid Build Coastguard Worker
257*cda5da8dSAndroid Build Coastguard Worker    Super-rename; create directories as necessary and delete any left
258*cda5da8dSAndroid Build Coastguard Worker    empty.  Works like rename, except creation of any intermediate
259*cda5da8dSAndroid Build Coastguard Worker    directories needed to make the new pathname good is attempted
260*cda5da8dSAndroid Build Coastguard Worker    first.  After the rename, directories corresponding to rightmost
261*cda5da8dSAndroid Build Coastguard Worker    path segments of the old name will be pruned until either the
262*cda5da8dSAndroid Build Coastguard Worker    whole path is consumed or a nonempty directory is found.
263*cda5da8dSAndroid Build Coastguard Worker
264*cda5da8dSAndroid Build Coastguard Worker    Note: this function can fail with the new directory structure made
265*cda5da8dSAndroid Build Coastguard Worker    if you lack permissions needed to unlink the leaf directory or
266*cda5da8dSAndroid Build Coastguard Worker    file.
267*cda5da8dSAndroid Build Coastguard Worker
268*cda5da8dSAndroid Build Coastguard Worker    """
269*cda5da8dSAndroid Build Coastguard Worker    head, tail = path.split(new)
270*cda5da8dSAndroid Build Coastguard Worker    if head and tail and not path.exists(head):
271*cda5da8dSAndroid Build Coastguard Worker        makedirs(head)
272*cda5da8dSAndroid Build Coastguard Worker    rename(old, new)
273*cda5da8dSAndroid Build Coastguard Worker    head, tail = path.split(old)
274*cda5da8dSAndroid Build Coastguard Worker    if head and tail:
275*cda5da8dSAndroid Build Coastguard Worker        try:
276*cda5da8dSAndroid Build Coastguard Worker            removedirs(head)
277*cda5da8dSAndroid Build Coastguard Worker        except OSError:
278*cda5da8dSAndroid Build Coastguard Worker            pass
279*cda5da8dSAndroid Build Coastguard Worker
280*cda5da8dSAndroid Build Coastguard Worker__all__.extend(["makedirs", "removedirs", "renames"])
281*cda5da8dSAndroid Build Coastguard Worker
282*cda5da8dSAndroid Build Coastguard Workerdef walk(top, topdown=True, onerror=None, followlinks=False):
283*cda5da8dSAndroid Build Coastguard Worker    """Directory tree generator.
284*cda5da8dSAndroid Build Coastguard Worker
285*cda5da8dSAndroid Build Coastguard Worker    For each directory in the directory tree rooted at top (including top
286*cda5da8dSAndroid Build Coastguard Worker    itself, but excluding '.' and '..'), yields a 3-tuple
287*cda5da8dSAndroid Build Coastguard Worker
288*cda5da8dSAndroid Build Coastguard Worker        dirpath, dirnames, filenames
289*cda5da8dSAndroid Build Coastguard Worker
290*cda5da8dSAndroid Build Coastguard Worker    dirpath is a string, the path to the directory.  dirnames is a list of
291*cda5da8dSAndroid Build Coastguard Worker    the names of the subdirectories in dirpath (including symlinks to directories,
292*cda5da8dSAndroid Build Coastguard Worker    and excluding '.' and '..').
293*cda5da8dSAndroid Build Coastguard Worker    filenames is a list of the names of the non-directory files in dirpath.
294*cda5da8dSAndroid Build Coastguard Worker    Note that the names in the lists are just names, with no path components.
295*cda5da8dSAndroid Build Coastguard Worker    To get a full path (which begins with top) to a file or directory in
296*cda5da8dSAndroid Build Coastguard Worker    dirpath, do os.path.join(dirpath, name).
297*cda5da8dSAndroid Build Coastguard Worker
298*cda5da8dSAndroid Build Coastguard Worker    If optional arg 'topdown' is true or not specified, the triple for a
299*cda5da8dSAndroid Build Coastguard Worker    directory is generated before the triples for any of its subdirectories
300*cda5da8dSAndroid Build Coastguard Worker    (directories are generated top down).  If topdown is false, the triple
301*cda5da8dSAndroid Build Coastguard Worker    for a directory is generated after the triples for all of its
302*cda5da8dSAndroid Build Coastguard Worker    subdirectories (directories are generated bottom up).
303*cda5da8dSAndroid Build Coastguard Worker
304*cda5da8dSAndroid Build Coastguard Worker    When topdown is true, the caller can modify the dirnames list in-place
305*cda5da8dSAndroid Build Coastguard Worker    (e.g., via del or slice assignment), and walk will only recurse into the
306*cda5da8dSAndroid Build Coastguard Worker    subdirectories whose names remain in dirnames; this can be used to prune the
307*cda5da8dSAndroid Build Coastguard Worker    search, or to impose a specific order of visiting.  Modifying dirnames when
308*cda5da8dSAndroid Build Coastguard Worker    topdown is false has no effect on the behavior of os.walk(), since the
309*cda5da8dSAndroid Build Coastguard Worker    directories in dirnames have already been generated by the time dirnames
310*cda5da8dSAndroid Build Coastguard Worker    itself is generated. No matter the value of topdown, the list of
311*cda5da8dSAndroid Build Coastguard Worker    subdirectories is retrieved before the tuples for the directory and its
312*cda5da8dSAndroid Build Coastguard Worker    subdirectories are generated.
313*cda5da8dSAndroid Build Coastguard Worker
314*cda5da8dSAndroid Build Coastguard Worker    By default errors from the os.scandir() call are ignored.  If
315*cda5da8dSAndroid Build Coastguard Worker    optional arg 'onerror' is specified, it should be a function; it
316*cda5da8dSAndroid Build Coastguard Worker    will be called with one argument, an OSError instance.  It can
317*cda5da8dSAndroid Build Coastguard Worker    report the error to continue with the walk, or raise the exception
318*cda5da8dSAndroid Build Coastguard Worker    to abort the walk.  Note that the filename is available as the
319*cda5da8dSAndroid Build Coastguard Worker    filename attribute of the exception object.
320*cda5da8dSAndroid Build Coastguard Worker
321*cda5da8dSAndroid Build Coastguard Worker    By default, os.walk does not follow symbolic links to subdirectories on
322*cda5da8dSAndroid Build Coastguard Worker    systems that support them.  In order to get this functionality, set the
323*cda5da8dSAndroid Build Coastguard Worker    optional argument 'followlinks' to true.
324*cda5da8dSAndroid Build Coastguard Worker
325*cda5da8dSAndroid Build Coastguard Worker    Caution:  if you pass a relative pathname for top, don't change the
326*cda5da8dSAndroid Build Coastguard Worker    current working directory between resumptions of walk.  walk never
327*cda5da8dSAndroid Build Coastguard Worker    changes the current directory, and assumes that the client doesn't
328*cda5da8dSAndroid Build Coastguard Worker    either.
329*cda5da8dSAndroid Build Coastguard Worker
330*cda5da8dSAndroid Build Coastguard Worker    Example:
331*cda5da8dSAndroid Build Coastguard Worker
332*cda5da8dSAndroid Build Coastguard Worker    import os
333*cda5da8dSAndroid Build Coastguard Worker    from os.path import join, getsize
334*cda5da8dSAndroid Build Coastguard Worker    for root, dirs, files in os.walk('python/Lib/email'):
335*cda5da8dSAndroid Build Coastguard Worker        print(root, "consumes ")
336*cda5da8dSAndroid Build Coastguard Worker        print(sum(getsize(join(root, name)) for name in files), end=" ")
337*cda5da8dSAndroid Build Coastguard Worker        print("bytes in", len(files), "non-directory files")
338*cda5da8dSAndroid Build Coastguard Worker        if 'CVS' in dirs:
339*cda5da8dSAndroid Build Coastguard Worker            dirs.remove('CVS')  # don't visit CVS directories
340*cda5da8dSAndroid Build Coastguard Worker
341*cda5da8dSAndroid Build Coastguard Worker    """
342*cda5da8dSAndroid Build Coastguard Worker    sys.audit("os.walk", top, topdown, onerror, followlinks)
343*cda5da8dSAndroid Build Coastguard Worker    return _walk(fspath(top), topdown, onerror, followlinks)
344*cda5da8dSAndroid Build Coastguard Worker
345*cda5da8dSAndroid Build Coastguard Workerdef _walk(top, topdown, onerror, followlinks):
346*cda5da8dSAndroid Build Coastguard Worker    dirs = []
347*cda5da8dSAndroid Build Coastguard Worker    nondirs = []
348*cda5da8dSAndroid Build Coastguard Worker    walk_dirs = []
349*cda5da8dSAndroid Build Coastguard Worker
350*cda5da8dSAndroid Build Coastguard Worker    # We may not have read permission for top, in which case we can't
351*cda5da8dSAndroid Build Coastguard Worker    # get a list of the files the directory contains.  os.walk
352*cda5da8dSAndroid Build Coastguard Worker    # always suppressed the exception then, rather than blow up for a
353*cda5da8dSAndroid Build Coastguard Worker    # minor reason when (say) a thousand readable directories are still
354*cda5da8dSAndroid Build Coastguard Worker    # left to visit.  That logic is copied here.
355*cda5da8dSAndroid Build Coastguard Worker    try:
356*cda5da8dSAndroid Build Coastguard Worker        # Note that scandir is global in this module due
357*cda5da8dSAndroid Build Coastguard Worker        # to earlier import-*.
358*cda5da8dSAndroid Build Coastguard Worker        scandir_it = scandir(top)
359*cda5da8dSAndroid Build Coastguard Worker    except OSError as error:
360*cda5da8dSAndroid Build Coastguard Worker        if onerror is not None:
361*cda5da8dSAndroid Build Coastguard Worker            onerror(error)
362*cda5da8dSAndroid Build Coastguard Worker        return
363*cda5da8dSAndroid Build Coastguard Worker
364*cda5da8dSAndroid Build Coastguard Worker    with scandir_it:
365*cda5da8dSAndroid Build Coastguard Worker        while True:
366*cda5da8dSAndroid Build Coastguard Worker            try:
367*cda5da8dSAndroid Build Coastguard Worker                try:
368*cda5da8dSAndroid Build Coastguard Worker                    entry = next(scandir_it)
369*cda5da8dSAndroid Build Coastguard Worker                except StopIteration:
370*cda5da8dSAndroid Build Coastguard Worker                    break
371*cda5da8dSAndroid Build Coastguard Worker            except OSError as error:
372*cda5da8dSAndroid Build Coastguard Worker                if onerror is not None:
373*cda5da8dSAndroid Build Coastguard Worker                    onerror(error)
374*cda5da8dSAndroid Build Coastguard Worker                return
375*cda5da8dSAndroid Build Coastguard Worker
376*cda5da8dSAndroid Build Coastguard Worker            try:
377*cda5da8dSAndroid Build Coastguard Worker                is_dir = entry.is_dir()
378*cda5da8dSAndroid Build Coastguard Worker            except OSError:
379*cda5da8dSAndroid Build Coastguard Worker                # If is_dir() raises an OSError, consider that the entry is not
380*cda5da8dSAndroid Build Coastguard Worker                # a directory, same behaviour than os.path.isdir().
381*cda5da8dSAndroid Build Coastguard Worker                is_dir = False
382*cda5da8dSAndroid Build Coastguard Worker
383*cda5da8dSAndroid Build Coastguard Worker            if is_dir:
384*cda5da8dSAndroid Build Coastguard Worker                dirs.append(entry.name)
385*cda5da8dSAndroid Build Coastguard Worker            else:
386*cda5da8dSAndroid Build Coastguard Worker                nondirs.append(entry.name)
387*cda5da8dSAndroid Build Coastguard Worker
388*cda5da8dSAndroid Build Coastguard Worker            if not topdown and is_dir:
389*cda5da8dSAndroid Build Coastguard Worker                # Bottom-up: recurse into sub-directory, but exclude symlinks to
390*cda5da8dSAndroid Build Coastguard Worker                # directories if followlinks is False
391*cda5da8dSAndroid Build Coastguard Worker                if followlinks:
392*cda5da8dSAndroid Build Coastguard Worker                    walk_into = True
393*cda5da8dSAndroid Build Coastguard Worker                else:
394*cda5da8dSAndroid Build Coastguard Worker                    try:
395*cda5da8dSAndroid Build Coastguard Worker                        is_symlink = entry.is_symlink()
396*cda5da8dSAndroid Build Coastguard Worker                    except OSError:
397*cda5da8dSAndroid Build Coastguard Worker                        # If is_symlink() raises an OSError, consider that the
398*cda5da8dSAndroid Build Coastguard Worker                        # entry is not a symbolic link, same behaviour than
399*cda5da8dSAndroid Build Coastguard Worker                        # os.path.islink().
400*cda5da8dSAndroid Build Coastguard Worker                        is_symlink = False
401*cda5da8dSAndroid Build Coastguard Worker                    walk_into = not is_symlink
402*cda5da8dSAndroid Build Coastguard Worker
403*cda5da8dSAndroid Build Coastguard Worker                if walk_into:
404*cda5da8dSAndroid Build Coastguard Worker                    walk_dirs.append(entry.path)
405*cda5da8dSAndroid Build Coastguard Worker
406*cda5da8dSAndroid Build Coastguard Worker    # Yield before recursion if going top down
407*cda5da8dSAndroid Build Coastguard Worker    if topdown:
408*cda5da8dSAndroid Build Coastguard Worker        yield top, dirs, nondirs
409*cda5da8dSAndroid Build Coastguard Worker
410*cda5da8dSAndroid Build Coastguard Worker        # Recurse into sub-directories
411*cda5da8dSAndroid Build Coastguard Worker        islink, join = path.islink, path.join
412*cda5da8dSAndroid Build Coastguard Worker        for dirname in dirs:
413*cda5da8dSAndroid Build Coastguard Worker            new_path = join(top, dirname)
414*cda5da8dSAndroid Build Coastguard Worker            # Issue #23605: os.path.islink() is used instead of caching
415*cda5da8dSAndroid Build Coastguard Worker            # entry.is_symlink() result during the loop on os.scandir() because
416*cda5da8dSAndroid Build Coastguard Worker            # the caller can replace the directory entry during the "yield"
417*cda5da8dSAndroid Build Coastguard Worker            # above.
418*cda5da8dSAndroid Build Coastguard Worker            if followlinks or not islink(new_path):
419*cda5da8dSAndroid Build Coastguard Worker                yield from _walk(new_path, topdown, onerror, followlinks)
420*cda5da8dSAndroid Build Coastguard Worker    else:
421*cda5da8dSAndroid Build Coastguard Worker        # Recurse into sub-directories
422*cda5da8dSAndroid Build Coastguard Worker        for new_path in walk_dirs:
423*cda5da8dSAndroid Build Coastguard Worker            yield from _walk(new_path, topdown, onerror, followlinks)
424*cda5da8dSAndroid Build Coastguard Worker        # Yield after recursion if going bottom up
425*cda5da8dSAndroid Build Coastguard Worker        yield top, dirs, nondirs
426*cda5da8dSAndroid Build Coastguard Worker
427*cda5da8dSAndroid Build Coastguard Worker__all__.append("walk")
428*cda5da8dSAndroid Build Coastguard Worker
429*cda5da8dSAndroid Build Coastguard Workerif {open, stat} <= supports_dir_fd and {scandir, stat} <= supports_fd:
430*cda5da8dSAndroid Build Coastguard Worker
431*cda5da8dSAndroid Build Coastguard Worker    def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=None):
432*cda5da8dSAndroid Build Coastguard Worker        """Directory tree generator.
433*cda5da8dSAndroid Build Coastguard Worker
434*cda5da8dSAndroid Build Coastguard Worker        This behaves exactly like walk(), except that it yields a 4-tuple
435*cda5da8dSAndroid Build Coastguard Worker
436*cda5da8dSAndroid Build Coastguard Worker            dirpath, dirnames, filenames, dirfd
437*cda5da8dSAndroid Build Coastguard Worker
438*cda5da8dSAndroid Build Coastguard Worker        `dirpath`, `dirnames` and `filenames` are identical to walk() output,
439*cda5da8dSAndroid Build Coastguard Worker        and `dirfd` is a file descriptor referring to the directory `dirpath`.
440*cda5da8dSAndroid Build Coastguard Worker
441*cda5da8dSAndroid Build Coastguard Worker        The advantage of fwalk() over walk() is that it's safe against symlink
442*cda5da8dSAndroid Build Coastguard Worker        races (when follow_symlinks is False).
443*cda5da8dSAndroid Build Coastguard Worker
444*cda5da8dSAndroid Build Coastguard Worker        If dir_fd is not None, it should be a file descriptor open to a directory,
445*cda5da8dSAndroid Build Coastguard Worker          and top should be relative; top will then be relative to that directory.
446*cda5da8dSAndroid Build Coastguard Worker          (dir_fd is always supported for fwalk.)
447*cda5da8dSAndroid Build Coastguard Worker
448*cda5da8dSAndroid Build Coastguard Worker        Caution:
449*cda5da8dSAndroid Build Coastguard Worker        Since fwalk() yields file descriptors, those are only valid until the
450*cda5da8dSAndroid Build Coastguard Worker        next iteration step, so you should dup() them if you want to keep them
451*cda5da8dSAndroid Build Coastguard Worker        for a longer period.
452*cda5da8dSAndroid Build Coastguard Worker
453*cda5da8dSAndroid Build Coastguard Worker        Example:
454*cda5da8dSAndroid Build Coastguard Worker
455*cda5da8dSAndroid Build Coastguard Worker        import os
456*cda5da8dSAndroid Build Coastguard Worker        for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
457*cda5da8dSAndroid Build Coastguard Worker            print(root, "consumes", end="")
458*cda5da8dSAndroid Build Coastguard Worker            print(sum(os.stat(name, dir_fd=rootfd).st_size for name in files),
459*cda5da8dSAndroid Build Coastguard Worker                  end="")
460*cda5da8dSAndroid Build Coastguard Worker            print("bytes in", len(files), "non-directory files")
461*cda5da8dSAndroid Build Coastguard Worker            if 'CVS' in dirs:
462*cda5da8dSAndroid Build Coastguard Worker                dirs.remove('CVS')  # don't visit CVS directories
463*cda5da8dSAndroid Build Coastguard Worker        """
464*cda5da8dSAndroid Build Coastguard Worker        sys.audit("os.fwalk", top, topdown, onerror, follow_symlinks, dir_fd)
465*cda5da8dSAndroid Build Coastguard Worker        top = fspath(top)
466*cda5da8dSAndroid Build Coastguard Worker        # Note: To guard against symlink races, we use the standard
467*cda5da8dSAndroid Build Coastguard Worker        # lstat()/open()/fstat() trick.
468*cda5da8dSAndroid Build Coastguard Worker        if not follow_symlinks:
469*cda5da8dSAndroid Build Coastguard Worker            orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd)
470*cda5da8dSAndroid Build Coastguard Worker        topfd = open(top, O_RDONLY, dir_fd=dir_fd)
471*cda5da8dSAndroid Build Coastguard Worker        try:
472*cda5da8dSAndroid Build Coastguard Worker            if (follow_symlinks or (st.S_ISDIR(orig_st.st_mode) and
473*cda5da8dSAndroid Build Coastguard Worker                                    path.samestat(orig_st, stat(topfd)))):
474*cda5da8dSAndroid Build Coastguard Worker                yield from _fwalk(topfd, top, isinstance(top, bytes),
475*cda5da8dSAndroid Build Coastguard Worker                                  topdown, onerror, follow_symlinks)
476*cda5da8dSAndroid Build Coastguard Worker        finally:
477*cda5da8dSAndroid Build Coastguard Worker            close(topfd)
478*cda5da8dSAndroid Build Coastguard Worker
479*cda5da8dSAndroid Build Coastguard Worker    def _fwalk(topfd, toppath, isbytes, topdown, onerror, follow_symlinks):
480*cda5da8dSAndroid Build Coastguard Worker        # Note: This uses O(depth of the directory tree) file descriptors: if
481*cda5da8dSAndroid Build Coastguard Worker        # necessary, it can be adapted to only require O(1) FDs, see issue
482*cda5da8dSAndroid Build Coastguard Worker        # #13734.
483*cda5da8dSAndroid Build Coastguard Worker
484*cda5da8dSAndroid Build Coastguard Worker        scandir_it = scandir(topfd)
485*cda5da8dSAndroid Build Coastguard Worker        dirs = []
486*cda5da8dSAndroid Build Coastguard Worker        nondirs = []
487*cda5da8dSAndroid Build Coastguard Worker        entries = None if topdown or follow_symlinks else []
488*cda5da8dSAndroid Build Coastguard Worker        for entry in scandir_it:
489*cda5da8dSAndroid Build Coastguard Worker            name = entry.name
490*cda5da8dSAndroid Build Coastguard Worker            if isbytes:
491*cda5da8dSAndroid Build Coastguard Worker                name = fsencode(name)
492*cda5da8dSAndroid Build Coastguard Worker            try:
493*cda5da8dSAndroid Build Coastguard Worker                if entry.is_dir():
494*cda5da8dSAndroid Build Coastguard Worker                    dirs.append(name)
495*cda5da8dSAndroid Build Coastguard Worker                    if entries is not None:
496*cda5da8dSAndroid Build Coastguard Worker                        entries.append(entry)
497*cda5da8dSAndroid Build Coastguard Worker                else:
498*cda5da8dSAndroid Build Coastguard Worker                    nondirs.append(name)
499*cda5da8dSAndroid Build Coastguard Worker            except OSError:
500*cda5da8dSAndroid Build Coastguard Worker                try:
501*cda5da8dSAndroid Build Coastguard Worker                    # Add dangling symlinks, ignore disappeared files
502*cda5da8dSAndroid Build Coastguard Worker                    if entry.is_symlink():
503*cda5da8dSAndroid Build Coastguard Worker                        nondirs.append(name)
504*cda5da8dSAndroid Build Coastguard Worker                except OSError:
505*cda5da8dSAndroid Build Coastguard Worker                    pass
506*cda5da8dSAndroid Build Coastguard Worker
507*cda5da8dSAndroid Build Coastguard Worker        if topdown:
508*cda5da8dSAndroid Build Coastguard Worker            yield toppath, dirs, nondirs, topfd
509*cda5da8dSAndroid Build Coastguard Worker
510*cda5da8dSAndroid Build Coastguard Worker        for name in dirs if entries is None else zip(dirs, entries):
511*cda5da8dSAndroid Build Coastguard Worker            try:
512*cda5da8dSAndroid Build Coastguard Worker                if not follow_symlinks:
513*cda5da8dSAndroid Build Coastguard Worker                    if topdown:
514*cda5da8dSAndroid Build Coastguard Worker                        orig_st = stat(name, dir_fd=topfd, follow_symlinks=False)
515*cda5da8dSAndroid Build Coastguard Worker                    else:
516*cda5da8dSAndroid Build Coastguard Worker                        assert entries is not None
517*cda5da8dSAndroid Build Coastguard Worker                        name, entry = name
518*cda5da8dSAndroid Build Coastguard Worker                        orig_st = entry.stat(follow_symlinks=False)
519*cda5da8dSAndroid Build Coastguard Worker                dirfd = open(name, O_RDONLY, dir_fd=topfd)
520*cda5da8dSAndroid Build Coastguard Worker            except OSError as err:
521*cda5da8dSAndroid Build Coastguard Worker                if onerror is not None:
522*cda5da8dSAndroid Build Coastguard Worker                    onerror(err)
523*cda5da8dSAndroid Build Coastguard Worker                continue
524*cda5da8dSAndroid Build Coastguard Worker            try:
525*cda5da8dSAndroid Build Coastguard Worker                if follow_symlinks or path.samestat(orig_st, stat(dirfd)):
526*cda5da8dSAndroid Build Coastguard Worker                    dirpath = path.join(toppath, name)
527*cda5da8dSAndroid Build Coastguard Worker                    yield from _fwalk(dirfd, dirpath, isbytes,
528*cda5da8dSAndroid Build Coastguard Worker                                      topdown, onerror, follow_symlinks)
529*cda5da8dSAndroid Build Coastguard Worker            finally:
530*cda5da8dSAndroid Build Coastguard Worker                close(dirfd)
531*cda5da8dSAndroid Build Coastguard Worker
532*cda5da8dSAndroid Build Coastguard Worker        if not topdown:
533*cda5da8dSAndroid Build Coastguard Worker            yield toppath, dirs, nondirs, topfd
534*cda5da8dSAndroid Build Coastguard Worker
535*cda5da8dSAndroid Build Coastguard Worker    __all__.append("fwalk")
536*cda5da8dSAndroid Build Coastguard Worker
537*cda5da8dSAndroid Build Coastguard Workerdef execl(file, *args):
538*cda5da8dSAndroid Build Coastguard Worker    """execl(file, *args)
539*cda5da8dSAndroid Build Coastguard Worker
540*cda5da8dSAndroid Build Coastguard Worker    Execute the executable file with argument list args, replacing the
541*cda5da8dSAndroid Build Coastguard Worker    current process. """
542*cda5da8dSAndroid Build Coastguard Worker    execv(file, args)
543*cda5da8dSAndroid Build Coastguard Worker
544*cda5da8dSAndroid Build Coastguard Workerdef execle(file, *args):
545*cda5da8dSAndroid Build Coastguard Worker    """execle(file, *args, env)
546*cda5da8dSAndroid Build Coastguard Worker
547*cda5da8dSAndroid Build Coastguard Worker    Execute the executable file with argument list args and
548*cda5da8dSAndroid Build Coastguard Worker    environment env, replacing the current process. """
549*cda5da8dSAndroid Build Coastguard Worker    env = args[-1]
550*cda5da8dSAndroid Build Coastguard Worker    execve(file, args[:-1], env)
551*cda5da8dSAndroid Build Coastguard Worker
552*cda5da8dSAndroid Build Coastguard Workerdef execlp(file, *args):
553*cda5da8dSAndroid Build Coastguard Worker    """execlp(file, *args)
554*cda5da8dSAndroid Build Coastguard Worker
555*cda5da8dSAndroid Build Coastguard Worker    Execute the executable file (which is searched for along $PATH)
556*cda5da8dSAndroid Build Coastguard Worker    with argument list args, replacing the current process. """
557*cda5da8dSAndroid Build Coastguard Worker    execvp(file, args)
558*cda5da8dSAndroid Build Coastguard Worker
559*cda5da8dSAndroid Build Coastguard Workerdef execlpe(file, *args):
560*cda5da8dSAndroid Build Coastguard Worker    """execlpe(file, *args, env)
561*cda5da8dSAndroid Build Coastguard Worker
562*cda5da8dSAndroid Build Coastguard Worker    Execute the executable file (which is searched for along $PATH)
563*cda5da8dSAndroid Build Coastguard Worker    with argument list args and environment env, replacing the current
564*cda5da8dSAndroid Build Coastguard Worker    process. """
565*cda5da8dSAndroid Build Coastguard Worker    env = args[-1]
566*cda5da8dSAndroid Build Coastguard Worker    execvpe(file, args[:-1], env)
567*cda5da8dSAndroid Build Coastguard Worker
568*cda5da8dSAndroid Build Coastguard Workerdef execvp(file, args):
569*cda5da8dSAndroid Build Coastguard Worker    """execvp(file, args)
570*cda5da8dSAndroid Build Coastguard Worker
571*cda5da8dSAndroid Build Coastguard Worker    Execute the executable file (which is searched for along $PATH)
572*cda5da8dSAndroid Build Coastguard Worker    with argument list args, replacing the current process.
573*cda5da8dSAndroid Build Coastguard Worker    args may be a list or tuple of strings. """
574*cda5da8dSAndroid Build Coastguard Worker    _execvpe(file, args)
575*cda5da8dSAndroid Build Coastguard Worker
576*cda5da8dSAndroid Build Coastguard Workerdef execvpe(file, args, env):
577*cda5da8dSAndroid Build Coastguard Worker    """execvpe(file, args, env)
578*cda5da8dSAndroid Build Coastguard Worker
579*cda5da8dSAndroid Build Coastguard Worker    Execute the executable file (which is searched for along $PATH)
580*cda5da8dSAndroid Build Coastguard Worker    with argument list args and environment env, replacing the
581*cda5da8dSAndroid Build Coastguard Worker    current process.
582*cda5da8dSAndroid Build Coastguard Worker    args may be a list or tuple of strings. """
583*cda5da8dSAndroid Build Coastguard Worker    _execvpe(file, args, env)
584*cda5da8dSAndroid Build Coastguard Worker
585*cda5da8dSAndroid Build Coastguard Worker__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
586*cda5da8dSAndroid Build Coastguard Worker
587*cda5da8dSAndroid Build Coastguard Workerdef _execvpe(file, args, env=None):
588*cda5da8dSAndroid Build Coastguard Worker    if env is not None:
589*cda5da8dSAndroid Build Coastguard Worker        exec_func = execve
590*cda5da8dSAndroid Build Coastguard Worker        argrest = (args, env)
591*cda5da8dSAndroid Build Coastguard Worker    else:
592*cda5da8dSAndroid Build Coastguard Worker        exec_func = execv
593*cda5da8dSAndroid Build Coastguard Worker        argrest = (args,)
594*cda5da8dSAndroid Build Coastguard Worker        env = environ
595*cda5da8dSAndroid Build Coastguard Worker
596*cda5da8dSAndroid Build Coastguard Worker    if path.dirname(file):
597*cda5da8dSAndroid Build Coastguard Worker        exec_func(file, *argrest)
598*cda5da8dSAndroid Build Coastguard Worker        return
599*cda5da8dSAndroid Build Coastguard Worker    saved_exc = None
600*cda5da8dSAndroid Build Coastguard Worker    path_list = get_exec_path(env)
601*cda5da8dSAndroid Build Coastguard Worker    if name != 'nt':
602*cda5da8dSAndroid Build Coastguard Worker        file = fsencode(file)
603*cda5da8dSAndroid Build Coastguard Worker        path_list = map(fsencode, path_list)
604*cda5da8dSAndroid Build Coastguard Worker    for dir in path_list:
605*cda5da8dSAndroid Build Coastguard Worker        fullname = path.join(dir, file)
606*cda5da8dSAndroid Build Coastguard Worker        try:
607*cda5da8dSAndroid Build Coastguard Worker            exec_func(fullname, *argrest)
608*cda5da8dSAndroid Build Coastguard Worker        except (FileNotFoundError, NotADirectoryError) as e:
609*cda5da8dSAndroid Build Coastguard Worker            last_exc = e
610*cda5da8dSAndroid Build Coastguard Worker        except OSError as e:
611*cda5da8dSAndroid Build Coastguard Worker            last_exc = e
612*cda5da8dSAndroid Build Coastguard Worker            if saved_exc is None:
613*cda5da8dSAndroid Build Coastguard Worker                saved_exc = e
614*cda5da8dSAndroid Build Coastguard Worker    if saved_exc is not None:
615*cda5da8dSAndroid Build Coastguard Worker        raise saved_exc
616*cda5da8dSAndroid Build Coastguard Worker    raise last_exc
617*cda5da8dSAndroid Build Coastguard Worker
618*cda5da8dSAndroid Build Coastguard Worker
619*cda5da8dSAndroid Build Coastguard Workerdef get_exec_path(env=None):
620*cda5da8dSAndroid Build Coastguard Worker    """Returns the sequence of directories that will be searched for the
621*cda5da8dSAndroid Build Coastguard Worker    named executable (similar to a shell) when launching a process.
622*cda5da8dSAndroid Build Coastguard Worker
623*cda5da8dSAndroid Build Coastguard Worker    *env* must be an environment variable dict or None.  If *env* is None,
624*cda5da8dSAndroid Build Coastguard Worker    os.environ will be used.
625*cda5da8dSAndroid Build Coastguard Worker    """
626*cda5da8dSAndroid Build Coastguard Worker    # Use a local import instead of a global import to limit the number of
627*cda5da8dSAndroid Build Coastguard Worker    # modules loaded at startup: the os module is always loaded at startup by
628*cda5da8dSAndroid Build Coastguard Worker    # Python. It may also avoid a bootstrap issue.
629*cda5da8dSAndroid Build Coastguard Worker    import warnings
630*cda5da8dSAndroid Build Coastguard Worker
631*cda5da8dSAndroid Build Coastguard Worker    if env is None:
632*cda5da8dSAndroid Build Coastguard Worker        env = environ
633*cda5da8dSAndroid Build Coastguard Worker
634*cda5da8dSAndroid Build Coastguard Worker    # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a
635*cda5da8dSAndroid Build Coastguard Worker    # BytesWarning when using python -b or python -bb: ignore the warning
636*cda5da8dSAndroid Build Coastguard Worker    with warnings.catch_warnings():
637*cda5da8dSAndroid Build Coastguard Worker        warnings.simplefilter("ignore", BytesWarning)
638*cda5da8dSAndroid Build Coastguard Worker
639*cda5da8dSAndroid Build Coastguard Worker        try:
640*cda5da8dSAndroid Build Coastguard Worker            path_list = env.get('PATH')
641*cda5da8dSAndroid Build Coastguard Worker        except TypeError:
642*cda5da8dSAndroid Build Coastguard Worker            path_list = None
643*cda5da8dSAndroid Build Coastguard Worker
644*cda5da8dSAndroid Build Coastguard Worker        if supports_bytes_environ:
645*cda5da8dSAndroid Build Coastguard Worker            try:
646*cda5da8dSAndroid Build Coastguard Worker                path_listb = env[b'PATH']
647*cda5da8dSAndroid Build Coastguard Worker            except (KeyError, TypeError):
648*cda5da8dSAndroid Build Coastguard Worker                pass
649*cda5da8dSAndroid Build Coastguard Worker            else:
650*cda5da8dSAndroid Build Coastguard Worker                if path_list is not None:
651*cda5da8dSAndroid Build Coastguard Worker                    raise ValueError(
652*cda5da8dSAndroid Build Coastguard Worker                        "env cannot contain 'PATH' and b'PATH' keys")
653*cda5da8dSAndroid Build Coastguard Worker                path_list = path_listb
654*cda5da8dSAndroid Build Coastguard Worker
655*cda5da8dSAndroid Build Coastguard Worker            if path_list is not None and isinstance(path_list, bytes):
656*cda5da8dSAndroid Build Coastguard Worker                path_list = fsdecode(path_list)
657*cda5da8dSAndroid Build Coastguard Worker
658*cda5da8dSAndroid Build Coastguard Worker    if path_list is None:
659*cda5da8dSAndroid Build Coastguard Worker        path_list = defpath
660*cda5da8dSAndroid Build Coastguard Worker    return path_list.split(pathsep)
661*cda5da8dSAndroid Build Coastguard Worker
662*cda5da8dSAndroid Build Coastguard Worker
663*cda5da8dSAndroid Build Coastguard Worker# Change environ to automatically call putenv() and unsetenv()
664*cda5da8dSAndroid Build Coastguard Workerfrom _collections_abc import MutableMapping, Mapping
665*cda5da8dSAndroid Build Coastguard Worker
666*cda5da8dSAndroid Build Coastguard Workerclass _Environ(MutableMapping):
667*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue):
668*cda5da8dSAndroid Build Coastguard Worker        self.encodekey = encodekey
669*cda5da8dSAndroid Build Coastguard Worker        self.decodekey = decodekey
670*cda5da8dSAndroid Build Coastguard Worker        self.encodevalue = encodevalue
671*cda5da8dSAndroid Build Coastguard Worker        self.decodevalue = decodevalue
672*cda5da8dSAndroid Build Coastguard Worker        self._data = data
673*cda5da8dSAndroid Build Coastguard Worker
674*cda5da8dSAndroid Build Coastguard Worker    def __getitem__(self, key):
675*cda5da8dSAndroid Build Coastguard Worker        try:
676*cda5da8dSAndroid Build Coastguard Worker            value = self._data[self.encodekey(key)]
677*cda5da8dSAndroid Build Coastguard Worker        except KeyError:
678*cda5da8dSAndroid Build Coastguard Worker            # raise KeyError with the original key value
679*cda5da8dSAndroid Build Coastguard Worker            raise KeyError(key) from None
680*cda5da8dSAndroid Build Coastguard Worker        return self.decodevalue(value)
681*cda5da8dSAndroid Build Coastguard Worker
682*cda5da8dSAndroid Build Coastguard Worker    def __setitem__(self, key, value):
683*cda5da8dSAndroid Build Coastguard Worker        key = self.encodekey(key)
684*cda5da8dSAndroid Build Coastguard Worker        value = self.encodevalue(value)
685*cda5da8dSAndroid Build Coastguard Worker        putenv(key, value)
686*cda5da8dSAndroid Build Coastguard Worker        self._data[key] = value
687*cda5da8dSAndroid Build Coastguard Worker
688*cda5da8dSAndroid Build Coastguard Worker    def __delitem__(self, key):
689*cda5da8dSAndroid Build Coastguard Worker        encodedkey = self.encodekey(key)
690*cda5da8dSAndroid Build Coastguard Worker        unsetenv(encodedkey)
691*cda5da8dSAndroid Build Coastguard Worker        try:
692*cda5da8dSAndroid Build Coastguard Worker            del self._data[encodedkey]
693*cda5da8dSAndroid Build Coastguard Worker        except KeyError:
694*cda5da8dSAndroid Build Coastguard Worker            # raise KeyError with the original key value
695*cda5da8dSAndroid Build Coastguard Worker            raise KeyError(key) from None
696*cda5da8dSAndroid Build Coastguard Worker
697*cda5da8dSAndroid Build Coastguard Worker    def __iter__(self):
698*cda5da8dSAndroid Build Coastguard Worker        # list() from dict object is an atomic operation
699*cda5da8dSAndroid Build Coastguard Worker        keys = list(self._data)
700*cda5da8dSAndroid Build Coastguard Worker        for key in keys:
701*cda5da8dSAndroid Build Coastguard Worker            yield self.decodekey(key)
702*cda5da8dSAndroid Build Coastguard Worker
703*cda5da8dSAndroid Build Coastguard Worker    def __len__(self):
704*cda5da8dSAndroid Build Coastguard Worker        return len(self._data)
705*cda5da8dSAndroid Build Coastguard Worker
706*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
707*cda5da8dSAndroid Build Coastguard Worker        formatted_items = ", ".join(
708*cda5da8dSAndroid Build Coastguard Worker            f"{self.decodekey(key)!r}: {self.decodevalue(value)!r}"
709*cda5da8dSAndroid Build Coastguard Worker            for key, value in self._data.items()
710*cda5da8dSAndroid Build Coastguard Worker        )
711*cda5da8dSAndroid Build Coastguard Worker        return f"environ({{{formatted_items}}})"
712*cda5da8dSAndroid Build Coastguard Worker
713*cda5da8dSAndroid Build Coastguard Worker    def copy(self):
714*cda5da8dSAndroid Build Coastguard Worker        return dict(self)
715*cda5da8dSAndroid Build Coastguard Worker
716*cda5da8dSAndroid Build Coastguard Worker    def setdefault(self, key, value):
717*cda5da8dSAndroid Build Coastguard Worker        if key not in self:
718*cda5da8dSAndroid Build Coastguard Worker            self[key] = value
719*cda5da8dSAndroid Build Coastguard Worker        return self[key]
720*cda5da8dSAndroid Build Coastguard Worker
721*cda5da8dSAndroid Build Coastguard Worker    def __ior__(self, other):
722*cda5da8dSAndroid Build Coastguard Worker        self.update(other)
723*cda5da8dSAndroid Build Coastguard Worker        return self
724*cda5da8dSAndroid Build Coastguard Worker
725*cda5da8dSAndroid Build Coastguard Worker    def __or__(self, other):
726*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(other, Mapping):
727*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
728*cda5da8dSAndroid Build Coastguard Worker        new = dict(self)
729*cda5da8dSAndroid Build Coastguard Worker        new.update(other)
730*cda5da8dSAndroid Build Coastguard Worker        return new
731*cda5da8dSAndroid Build Coastguard Worker
732*cda5da8dSAndroid Build Coastguard Worker    def __ror__(self, other):
733*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(other, Mapping):
734*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
735*cda5da8dSAndroid Build Coastguard Worker        new = dict(other)
736*cda5da8dSAndroid Build Coastguard Worker        new.update(self)
737*cda5da8dSAndroid Build Coastguard Worker        return new
738*cda5da8dSAndroid Build Coastguard Worker
739*cda5da8dSAndroid Build Coastguard Workerdef _createenviron():
740*cda5da8dSAndroid Build Coastguard Worker    if name == 'nt':
741*cda5da8dSAndroid Build Coastguard Worker        # Where Env Var Names Must Be UPPERCASE
742*cda5da8dSAndroid Build Coastguard Worker        def check_str(value):
743*cda5da8dSAndroid Build Coastguard Worker            if not isinstance(value, str):
744*cda5da8dSAndroid Build Coastguard Worker                raise TypeError("str expected, not %s" % type(value).__name__)
745*cda5da8dSAndroid Build Coastguard Worker            return value
746*cda5da8dSAndroid Build Coastguard Worker        encode = check_str
747*cda5da8dSAndroid Build Coastguard Worker        decode = str
748*cda5da8dSAndroid Build Coastguard Worker        def encodekey(key):
749*cda5da8dSAndroid Build Coastguard Worker            return encode(key).upper()
750*cda5da8dSAndroid Build Coastguard Worker        data = {}
751*cda5da8dSAndroid Build Coastguard Worker        for key, value in environ.items():
752*cda5da8dSAndroid Build Coastguard Worker            data[encodekey(key)] = value
753*cda5da8dSAndroid Build Coastguard Worker    else:
754*cda5da8dSAndroid Build Coastguard Worker        # Where Env Var Names Can Be Mixed Case
755*cda5da8dSAndroid Build Coastguard Worker        encoding = sys.getfilesystemencoding()
756*cda5da8dSAndroid Build Coastguard Worker        def encode(value):
757*cda5da8dSAndroid Build Coastguard Worker            if not isinstance(value, str):
758*cda5da8dSAndroid Build Coastguard Worker                raise TypeError("str expected, not %s" % type(value).__name__)
759*cda5da8dSAndroid Build Coastguard Worker            return value.encode(encoding, 'surrogateescape')
760*cda5da8dSAndroid Build Coastguard Worker        def decode(value):
761*cda5da8dSAndroid Build Coastguard Worker            return value.decode(encoding, 'surrogateescape')
762*cda5da8dSAndroid Build Coastguard Worker        encodekey = encode
763*cda5da8dSAndroid Build Coastguard Worker        data = environ
764*cda5da8dSAndroid Build Coastguard Worker    return _Environ(data,
765*cda5da8dSAndroid Build Coastguard Worker        encodekey, decode,
766*cda5da8dSAndroid Build Coastguard Worker        encode, decode)
767*cda5da8dSAndroid Build Coastguard Worker
768*cda5da8dSAndroid Build Coastguard Worker# unicode environ
769*cda5da8dSAndroid Build Coastguard Workerenviron = _createenviron()
770*cda5da8dSAndroid Build Coastguard Workerdel _createenviron
771*cda5da8dSAndroid Build Coastguard Worker
772*cda5da8dSAndroid Build Coastguard Worker
773*cda5da8dSAndroid Build Coastguard Workerdef getenv(key, default=None):
774*cda5da8dSAndroid Build Coastguard Worker    """Get an environment variable, return None if it doesn't exist.
775*cda5da8dSAndroid Build Coastguard Worker    The optional second argument can specify an alternate default.
776*cda5da8dSAndroid Build Coastguard Worker    key, default and the result are str."""
777*cda5da8dSAndroid Build Coastguard Worker    return environ.get(key, default)
778*cda5da8dSAndroid Build Coastguard Worker
779*cda5da8dSAndroid Build Coastguard Workersupports_bytes_environ = (name != 'nt')
780*cda5da8dSAndroid Build Coastguard Worker__all__.extend(("getenv", "supports_bytes_environ"))
781*cda5da8dSAndroid Build Coastguard Worker
782*cda5da8dSAndroid Build Coastguard Workerif supports_bytes_environ:
783*cda5da8dSAndroid Build Coastguard Worker    def _check_bytes(value):
784*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(value, bytes):
785*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("bytes expected, not %s" % type(value).__name__)
786*cda5da8dSAndroid Build Coastguard Worker        return value
787*cda5da8dSAndroid Build Coastguard Worker
788*cda5da8dSAndroid Build Coastguard Worker    # bytes environ
789*cda5da8dSAndroid Build Coastguard Worker    environb = _Environ(environ._data,
790*cda5da8dSAndroid Build Coastguard Worker        _check_bytes, bytes,
791*cda5da8dSAndroid Build Coastguard Worker        _check_bytes, bytes)
792*cda5da8dSAndroid Build Coastguard Worker    del _check_bytes
793*cda5da8dSAndroid Build Coastguard Worker
794*cda5da8dSAndroid Build Coastguard Worker    def getenvb(key, default=None):
795*cda5da8dSAndroid Build Coastguard Worker        """Get an environment variable, return None if it doesn't exist.
796*cda5da8dSAndroid Build Coastguard Worker        The optional second argument can specify an alternate default.
797*cda5da8dSAndroid Build Coastguard Worker        key, default and the result are bytes."""
798*cda5da8dSAndroid Build Coastguard Worker        return environb.get(key, default)
799*cda5da8dSAndroid Build Coastguard Worker
800*cda5da8dSAndroid Build Coastguard Worker    __all__.extend(("environb", "getenvb"))
801*cda5da8dSAndroid Build Coastguard Worker
802*cda5da8dSAndroid Build Coastguard Workerdef _fscodec():
803*cda5da8dSAndroid Build Coastguard Worker    encoding = sys.getfilesystemencoding()
804*cda5da8dSAndroid Build Coastguard Worker    errors = sys.getfilesystemencodeerrors()
805*cda5da8dSAndroid Build Coastguard Worker
806*cda5da8dSAndroid Build Coastguard Worker    def fsencode(filename):
807*cda5da8dSAndroid Build Coastguard Worker        """Encode filename (an os.PathLike, bytes, or str) to the filesystem
808*cda5da8dSAndroid Build Coastguard Worker        encoding with 'surrogateescape' error handler, return bytes unchanged.
809*cda5da8dSAndroid Build Coastguard Worker        On Windows, use 'strict' error handler if the file system encoding is
810*cda5da8dSAndroid Build Coastguard Worker        'mbcs' (which is the default encoding).
811*cda5da8dSAndroid Build Coastguard Worker        """
812*cda5da8dSAndroid Build Coastguard Worker        filename = fspath(filename)  # Does type-checking of `filename`.
813*cda5da8dSAndroid Build Coastguard Worker        if isinstance(filename, str):
814*cda5da8dSAndroid Build Coastguard Worker            return filename.encode(encoding, errors)
815*cda5da8dSAndroid Build Coastguard Worker        else:
816*cda5da8dSAndroid Build Coastguard Worker            return filename
817*cda5da8dSAndroid Build Coastguard Worker
818*cda5da8dSAndroid Build Coastguard Worker    def fsdecode(filename):
819*cda5da8dSAndroid Build Coastguard Worker        """Decode filename (an os.PathLike, bytes, or str) from the filesystem
820*cda5da8dSAndroid Build Coastguard Worker        encoding with 'surrogateescape' error handler, return str unchanged. On
821*cda5da8dSAndroid Build Coastguard Worker        Windows, use 'strict' error handler if the file system encoding is
822*cda5da8dSAndroid Build Coastguard Worker        'mbcs' (which is the default encoding).
823*cda5da8dSAndroid Build Coastguard Worker        """
824*cda5da8dSAndroid Build Coastguard Worker        filename = fspath(filename)  # Does type-checking of `filename`.
825*cda5da8dSAndroid Build Coastguard Worker        if isinstance(filename, bytes):
826*cda5da8dSAndroid Build Coastguard Worker            return filename.decode(encoding, errors)
827*cda5da8dSAndroid Build Coastguard Worker        else:
828*cda5da8dSAndroid Build Coastguard Worker            return filename
829*cda5da8dSAndroid Build Coastguard Worker
830*cda5da8dSAndroid Build Coastguard Worker    return fsencode, fsdecode
831*cda5da8dSAndroid Build Coastguard Worker
832*cda5da8dSAndroid Build Coastguard Workerfsencode, fsdecode = _fscodec()
833*cda5da8dSAndroid Build Coastguard Workerdel _fscodec
834*cda5da8dSAndroid Build Coastguard Worker
835*cda5da8dSAndroid Build Coastguard Worker# Supply spawn*() (probably only for Unix)
836*cda5da8dSAndroid Build Coastguard Workerif _exists("fork") and not _exists("spawnv") and _exists("execv"):
837*cda5da8dSAndroid Build Coastguard Worker
838*cda5da8dSAndroid Build Coastguard Worker    P_WAIT = 0
839*cda5da8dSAndroid Build Coastguard Worker    P_NOWAIT = P_NOWAITO = 1
840*cda5da8dSAndroid Build Coastguard Worker
841*cda5da8dSAndroid Build Coastguard Worker    __all__.extend(["P_WAIT", "P_NOWAIT", "P_NOWAITO"])
842*cda5da8dSAndroid Build Coastguard Worker
843*cda5da8dSAndroid Build Coastguard Worker    # XXX Should we support P_DETACH?  I suppose it could fork()**2
844*cda5da8dSAndroid Build Coastguard Worker    # and close the std I/O streams.  Also, P_OVERLAY is the same
845*cda5da8dSAndroid Build Coastguard Worker    # as execv*()?
846*cda5da8dSAndroid Build Coastguard Worker
847*cda5da8dSAndroid Build Coastguard Worker    def _spawnvef(mode, file, args, env, func):
848*cda5da8dSAndroid Build Coastguard Worker        # Internal helper; func is the exec*() function to use
849*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(args, (tuple, list)):
850*cda5da8dSAndroid Build Coastguard Worker            raise TypeError('argv must be a tuple or a list')
851*cda5da8dSAndroid Build Coastguard Worker        if not args or not args[0]:
852*cda5da8dSAndroid Build Coastguard Worker            raise ValueError('argv first element cannot be empty')
853*cda5da8dSAndroid Build Coastguard Worker        pid = fork()
854*cda5da8dSAndroid Build Coastguard Worker        if not pid:
855*cda5da8dSAndroid Build Coastguard Worker            # Child
856*cda5da8dSAndroid Build Coastguard Worker            try:
857*cda5da8dSAndroid Build Coastguard Worker                if env is None:
858*cda5da8dSAndroid Build Coastguard Worker                    func(file, args)
859*cda5da8dSAndroid Build Coastguard Worker                else:
860*cda5da8dSAndroid Build Coastguard Worker                    func(file, args, env)
861*cda5da8dSAndroid Build Coastguard Worker            except:
862*cda5da8dSAndroid Build Coastguard Worker                _exit(127)
863*cda5da8dSAndroid Build Coastguard Worker        else:
864*cda5da8dSAndroid Build Coastguard Worker            # Parent
865*cda5da8dSAndroid Build Coastguard Worker            if mode == P_NOWAIT:
866*cda5da8dSAndroid Build Coastguard Worker                return pid # Caller is responsible for waiting!
867*cda5da8dSAndroid Build Coastguard Worker            while 1:
868*cda5da8dSAndroid Build Coastguard Worker                wpid, sts = waitpid(pid, 0)
869*cda5da8dSAndroid Build Coastguard Worker                if WIFSTOPPED(sts):
870*cda5da8dSAndroid Build Coastguard Worker                    continue
871*cda5da8dSAndroid Build Coastguard Worker
872*cda5da8dSAndroid Build Coastguard Worker                return waitstatus_to_exitcode(sts)
873*cda5da8dSAndroid Build Coastguard Worker
874*cda5da8dSAndroid Build Coastguard Worker    def spawnv(mode, file, args):
875*cda5da8dSAndroid Build Coastguard Worker        """spawnv(mode, file, args) -> integer
876*cda5da8dSAndroid Build Coastguard Worker
877*cda5da8dSAndroid Build Coastguard WorkerExecute file with arguments from args in a subprocess.
878*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_NOWAIT return the pid of the process.
879*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_WAIT return the process's exit code if it exits normally;
880*cda5da8dSAndroid Build Coastguard Workerotherwise return -SIG, where SIG is the signal that killed it. """
881*cda5da8dSAndroid Build Coastguard Worker        return _spawnvef(mode, file, args, None, execv)
882*cda5da8dSAndroid Build Coastguard Worker
883*cda5da8dSAndroid Build Coastguard Worker    def spawnve(mode, file, args, env):
884*cda5da8dSAndroid Build Coastguard Worker        """spawnve(mode, file, args, env) -> integer
885*cda5da8dSAndroid Build Coastguard Worker
886*cda5da8dSAndroid Build Coastguard WorkerExecute file with arguments from args in a subprocess with the
887*cda5da8dSAndroid Build Coastguard Workerspecified environment.
888*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_NOWAIT return the pid of the process.
889*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_WAIT return the process's exit code if it exits normally;
890*cda5da8dSAndroid Build Coastguard Workerotherwise return -SIG, where SIG is the signal that killed it. """
891*cda5da8dSAndroid Build Coastguard Worker        return _spawnvef(mode, file, args, env, execve)
892*cda5da8dSAndroid Build Coastguard Worker
893*cda5da8dSAndroid Build Coastguard Worker    # Note: spawnvp[e] isn't currently supported on Windows
894*cda5da8dSAndroid Build Coastguard Worker
895*cda5da8dSAndroid Build Coastguard Worker    def spawnvp(mode, file, args):
896*cda5da8dSAndroid Build Coastguard Worker        """spawnvp(mode, file, args) -> integer
897*cda5da8dSAndroid Build Coastguard Worker
898*cda5da8dSAndroid Build Coastguard WorkerExecute file (which is looked for along $PATH) with arguments from
899*cda5da8dSAndroid Build Coastguard Workerargs in a subprocess.
900*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_NOWAIT return the pid of the process.
901*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_WAIT return the process's exit code if it exits normally;
902*cda5da8dSAndroid Build Coastguard Workerotherwise return -SIG, where SIG is the signal that killed it. """
903*cda5da8dSAndroid Build Coastguard Worker        return _spawnvef(mode, file, args, None, execvp)
904*cda5da8dSAndroid Build Coastguard Worker
905*cda5da8dSAndroid Build Coastguard Worker    def spawnvpe(mode, file, args, env):
906*cda5da8dSAndroid Build Coastguard Worker        """spawnvpe(mode, file, args, env) -> integer
907*cda5da8dSAndroid Build Coastguard Worker
908*cda5da8dSAndroid Build Coastguard WorkerExecute file (which is looked for along $PATH) with arguments from
909*cda5da8dSAndroid Build Coastguard Workerargs in a subprocess with the supplied environment.
910*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_NOWAIT return the pid of the process.
911*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_WAIT return the process's exit code if it exits normally;
912*cda5da8dSAndroid Build Coastguard Workerotherwise return -SIG, where SIG is the signal that killed it. """
913*cda5da8dSAndroid Build Coastguard Worker        return _spawnvef(mode, file, args, env, execvpe)
914*cda5da8dSAndroid Build Coastguard Worker
915*cda5da8dSAndroid Build Coastguard Worker
916*cda5da8dSAndroid Build Coastguard Worker    __all__.extend(["spawnv", "spawnve", "spawnvp", "spawnvpe"])
917*cda5da8dSAndroid Build Coastguard Worker
918*cda5da8dSAndroid Build Coastguard Worker
919*cda5da8dSAndroid Build Coastguard Workerif _exists("spawnv"):
920*cda5da8dSAndroid Build Coastguard Worker    # These aren't supplied by the basic Windows code
921*cda5da8dSAndroid Build Coastguard Worker    # but can be easily implemented in Python
922*cda5da8dSAndroid Build Coastguard Worker
923*cda5da8dSAndroid Build Coastguard Worker    def spawnl(mode, file, *args):
924*cda5da8dSAndroid Build Coastguard Worker        """spawnl(mode, file, *args) -> integer
925*cda5da8dSAndroid Build Coastguard Worker
926*cda5da8dSAndroid Build Coastguard WorkerExecute file with arguments from args in a subprocess.
927*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_NOWAIT return the pid of the process.
928*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_WAIT return the process's exit code if it exits normally;
929*cda5da8dSAndroid Build Coastguard Workerotherwise return -SIG, where SIG is the signal that killed it. """
930*cda5da8dSAndroid Build Coastguard Worker        return spawnv(mode, file, args)
931*cda5da8dSAndroid Build Coastguard Worker
932*cda5da8dSAndroid Build Coastguard Worker    def spawnle(mode, file, *args):
933*cda5da8dSAndroid Build Coastguard Worker        """spawnle(mode, file, *args, env) -> integer
934*cda5da8dSAndroid Build Coastguard Worker
935*cda5da8dSAndroid Build Coastguard WorkerExecute file with arguments from args in a subprocess with the
936*cda5da8dSAndroid Build Coastguard Workersupplied environment.
937*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_NOWAIT return the pid of the process.
938*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_WAIT return the process's exit code if it exits normally;
939*cda5da8dSAndroid Build Coastguard Workerotherwise return -SIG, where SIG is the signal that killed it. """
940*cda5da8dSAndroid Build Coastguard Worker        env = args[-1]
941*cda5da8dSAndroid Build Coastguard Worker        return spawnve(mode, file, args[:-1], env)
942*cda5da8dSAndroid Build Coastguard Worker
943*cda5da8dSAndroid Build Coastguard Worker
944*cda5da8dSAndroid Build Coastguard Worker    __all__.extend(["spawnl", "spawnle"])
945*cda5da8dSAndroid Build Coastguard Worker
946*cda5da8dSAndroid Build Coastguard Worker
947*cda5da8dSAndroid Build Coastguard Workerif _exists("spawnvp"):
948*cda5da8dSAndroid Build Coastguard Worker    # At the moment, Windows doesn't implement spawnvp[e],
949*cda5da8dSAndroid Build Coastguard Worker    # so it won't have spawnlp[e] either.
950*cda5da8dSAndroid Build Coastguard Worker    def spawnlp(mode, file, *args):
951*cda5da8dSAndroid Build Coastguard Worker        """spawnlp(mode, file, *args) -> integer
952*cda5da8dSAndroid Build Coastguard Worker
953*cda5da8dSAndroid Build Coastguard WorkerExecute file (which is looked for along $PATH) with arguments from
954*cda5da8dSAndroid Build Coastguard Workerargs in a subprocess with the supplied environment.
955*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_NOWAIT return the pid of the process.
956*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_WAIT return the process's exit code if it exits normally;
957*cda5da8dSAndroid Build Coastguard Workerotherwise return -SIG, where SIG is the signal that killed it. """
958*cda5da8dSAndroid Build Coastguard Worker        return spawnvp(mode, file, args)
959*cda5da8dSAndroid Build Coastguard Worker
960*cda5da8dSAndroid Build Coastguard Worker    def spawnlpe(mode, file, *args):
961*cda5da8dSAndroid Build Coastguard Worker        """spawnlpe(mode, file, *args, env) -> integer
962*cda5da8dSAndroid Build Coastguard Worker
963*cda5da8dSAndroid Build Coastguard WorkerExecute file (which is looked for along $PATH) with arguments from
964*cda5da8dSAndroid Build Coastguard Workerargs in a subprocess with the supplied environment.
965*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_NOWAIT return the pid of the process.
966*cda5da8dSAndroid Build Coastguard WorkerIf mode == P_WAIT return the process's exit code if it exits normally;
967*cda5da8dSAndroid Build Coastguard Workerotherwise return -SIG, where SIG is the signal that killed it. """
968*cda5da8dSAndroid Build Coastguard Worker        env = args[-1]
969*cda5da8dSAndroid Build Coastguard Worker        return spawnvpe(mode, file, args[:-1], env)
970*cda5da8dSAndroid Build Coastguard Worker
971*cda5da8dSAndroid Build Coastguard Worker
972*cda5da8dSAndroid Build Coastguard Worker    __all__.extend(["spawnlp", "spawnlpe"])
973*cda5da8dSAndroid Build Coastguard Worker
974*cda5da8dSAndroid Build Coastguard Worker# VxWorks has no user space shell provided. As a result, running
975*cda5da8dSAndroid Build Coastguard Worker# command in a shell can't be supported.
976*cda5da8dSAndroid Build Coastguard Workerif sys.platform != 'vxworks':
977*cda5da8dSAndroid Build Coastguard Worker    # Supply os.popen()
978*cda5da8dSAndroid Build Coastguard Worker    def popen(cmd, mode="r", buffering=-1):
979*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(cmd, str):
980*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
981*cda5da8dSAndroid Build Coastguard Worker        if mode not in ("r", "w"):
982*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("invalid mode %r" % mode)
983*cda5da8dSAndroid Build Coastguard Worker        if buffering == 0 or buffering is None:
984*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("popen() does not support unbuffered streams")
985*cda5da8dSAndroid Build Coastguard Worker        import subprocess
986*cda5da8dSAndroid Build Coastguard Worker        if mode == "r":
987*cda5da8dSAndroid Build Coastguard Worker            proc = subprocess.Popen(cmd,
988*cda5da8dSAndroid Build Coastguard Worker                                    shell=True, text=True,
989*cda5da8dSAndroid Build Coastguard Worker                                    stdout=subprocess.PIPE,
990*cda5da8dSAndroid Build Coastguard Worker                                    bufsize=buffering)
991*cda5da8dSAndroid Build Coastguard Worker            return _wrap_close(proc.stdout, proc)
992*cda5da8dSAndroid Build Coastguard Worker        else:
993*cda5da8dSAndroid Build Coastguard Worker            proc = subprocess.Popen(cmd,
994*cda5da8dSAndroid Build Coastguard Worker                                    shell=True, text=True,
995*cda5da8dSAndroid Build Coastguard Worker                                    stdin=subprocess.PIPE,
996*cda5da8dSAndroid Build Coastguard Worker                                    bufsize=buffering)
997*cda5da8dSAndroid Build Coastguard Worker            return _wrap_close(proc.stdin, proc)
998*cda5da8dSAndroid Build Coastguard Worker
999*cda5da8dSAndroid Build Coastguard Worker    # Helper for popen() -- a proxy for a file whose close waits for the process
1000*cda5da8dSAndroid Build Coastguard Worker    class _wrap_close:
1001*cda5da8dSAndroid Build Coastguard Worker        def __init__(self, stream, proc):
1002*cda5da8dSAndroid Build Coastguard Worker            self._stream = stream
1003*cda5da8dSAndroid Build Coastguard Worker            self._proc = proc
1004*cda5da8dSAndroid Build Coastguard Worker        def close(self):
1005*cda5da8dSAndroid Build Coastguard Worker            self._stream.close()
1006*cda5da8dSAndroid Build Coastguard Worker            returncode = self._proc.wait()
1007*cda5da8dSAndroid Build Coastguard Worker            if returncode == 0:
1008*cda5da8dSAndroid Build Coastguard Worker                return None
1009*cda5da8dSAndroid Build Coastguard Worker            if name == 'nt':
1010*cda5da8dSAndroid Build Coastguard Worker                return returncode
1011*cda5da8dSAndroid Build Coastguard Worker            else:
1012*cda5da8dSAndroid Build Coastguard Worker                return returncode << 8  # Shift left to match old behavior
1013*cda5da8dSAndroid Build Coastguard Worker        def __enter__(self):
1014*cda5da8dSAndroid Build Coastguard Worker            return self
1015*cda5da8dSAndroid Build Coastguard Worker        def __exit__(self, *args):
1016*cda5da8dSAndroid Build Coastguard Worker            self.close()
1017*cda5da8dSAndroid Build Coastguard Worker        def __getattr__(self, name):
1018*cda5da8dSAndroid Build Coastguard Worker            return getattr(self._stream, name)
1019*cda5da8dSAndroid Build Coastguard Worker        def __iter__(self):
1020*cda5da8dSAndroid Build Coastguard Worker            return iter(self._stream)
1021*cda5da8dSAndroid Build Coastguard Worker
1022*cda5da8dSAndroid Build Coastguard Worker    __all__.append("popen")
1023*cda5da8dSAndroid Build Coastguard Worker
1024*cda5da8dSAndroid Build Coastguard Worker# Supply os.fdopen()
1025*cda5da8dSAndroid Build Coastguard Workerdef fdopen(fd, mode="r", buffering=-1, encoding=None, *args, **kwargs):
1026*cda5da8dSAndroid Build Coastguard Worker    if not isinstance(fd, int):
1027*cda5da8dSAndroid Build Coastguard Worker        raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
1028*cda5da8dSAndroid Build Coastguard Worker    import io
1029*cda5da8dSAndroid Build Coastguard Worker    if "b" not in mode:
1030*cda5da8dSAndroid Build Coastguard Worker        encoding = io.text_encoding(encoding)
1031*cda5da8dSAndroid Build Coastguard Worker    return io.open(fd, mode, buffering, encoding, *args, **kwargs)
1032*cda5da8dSAndroid Build Coastguard Worker
1033*cda5da8dSAndroid Build Coastguard Worker
1034*cda5da8dSAndroid Build Coastguard Worker# For testing purposes, make sure the function is available when the C
1035*cda5da8dSAndroid Build Coastguard Worker# implementation exists.
1036*cda5da8dSAndroid Build Coastguard Workerdef _fspath(path):
1037*cda5da8dSAndroid Build Coastguard Worker    """Return the path representation of a path-like object.
1038*cda5da8dSAndroid Build Coastguard Worker
1039*cda5da8dSAndroid Build Coastguard Worker    If str or bytes is passed in, it is returned unchanged. Otherwise the
1040*cda5da8dSAndroid Build Coastguard Worker    os.PathLike interface is used to get the path representation. If the
1041*cda5da8dSAndroid Build Coastguard Worker    path representation is not str or bytes, TypeError is raised. If the
1042*cda5da8dSAndroid Build Coastguard Worker    provided path is not str, bytes, or os.PathLike, TypeError is raised.
1043*cda5da8dSAndroid Build Coastguard Worker    """
1044*cda5da8dSAndroid Build Coastguard Worker    if isinstance(path, (str, bytes)):
1045*cda5da8dSAndroid Build Coastguard Worker        return path
1046*cda5da8dSAndroid Build Coastguard Worker
1047*cda5da8dSAndroid Build Coastguard Worker    # Work from the object's type to match method resolution of other magic
1048*cda5da8dSAndroid Build Coastguard Worker    # methods.
1049*cda5da8dSAndroid Build Coastguard Worker    path_type = type(path)
1050*cda5da8dSAndroid Build Coastguard Worker    try:
1051*cda5da8dSAndroid Build Coastguard Worker        path_repr = path_type.__fspath__(path)
1052*cda5da8dSAndroid Build Coastguard Worker    except AttributeError:
1053*cda5da8dSAndroid Build Coastguard Worker        if hasattr(path_type, '__fspath__'):
1054*cda5da8dSAndroid Build Coastguard Worker            raise
1055*cda5da8dSAndroid Build Coastguard Worker        else:
1056*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("expected str, bytes or os.PathLike object, "
1057*cda5da8dSAndroid Build Coastguard Worker                            "not " + path_type.__name__)
1058*cda5da8dSAndroid Build Coastguard Worker    if isinstance(path_repr, (str, bytes)):
1059*cda5da8dSAndroid Build Coastguard Worker        return path_repr
1060*cda5da8dSAndroid Build Coastguard Worker    else:
1061*cda5da8dSAndroid Build Coastguard Worker        raise TypeError("expected {}.__fspath__() to return str or bytes, "
1062*cda5da8dSAndroid Build Coastguard Worker                        "not {}".format(path_type.__name__,
1063*cda5da8dSAndroid Build Coastguard Worker                                        type(path_repr).__name__))
1064*cda5da8dSAndroid Build Coastguard Worker
1065*cda5da8dSAndroid Build Coastguard Worker# If there is no C implementation, make the pure Python version the
1066*cda5da8dSAndroid Build Coastguard Worker# implementation as transparently as possible.
1067*cda5da8dSAndroid Build Coastguard Workerif not _exists('fspath'):
1068*cda5da8dSAndroid Build Coastguard Worker    fspath = _fspath
1069*cda5da8dSAndroid Build Coastguard Worker    fspath.__name__ = "fspath"
1070*cda5da8dSAndroid Build Coastguard Worker
1071*cda5da8dSAndroid Build Coastguard Worker
1072*cda5da8dSAndroid Build Coastguard Workerclass PathLike(abc.ABC):
1073*cda5da8dSAndroid Build Coastguard Worker
1074*cda5da8dSAndroid Build Coastguard Worker    """Abstract base class for implementing the file system path protocol."""
1075*cda5da8dSAndroid Build Coastguard Worker
1076*cda5da8dSAndroid Build Coastguard Worker    @abc.abstractmethod
1077*cda5da8dSAndroid Build Coastguard Worker    def __fspath__(self):
1078*cda5da8dSAndroid Build Coastguard Worker        """Return the file system path representation of the object."""
1079*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError
1080*cda5da8dSAndroid Build Coastguard Worker
1081*cda5da8dSAndroid Build Coastguard Worker    @classmethod
1082*cda5da8dSAndroid Build Coastguard Worker    def __subclasshook__(cls, subclass):
1083*cda5da8dSAndroid Build Coastguard Worker        if cls is PathLike:
1084*cda5da8dSAndroid Build Coastguard Worker            return _check_methods(subclass, '__fspath__')
1085*cda5da8dSAndroid Build Coastguard Worker        return NotImplemented
1086*cda5da8dSAndroid Build Coastguard Worker
1087*cda5da8dSAndroid Build Coastguard Worker    __class_getitem__ = classmethod(GenericAlias)
1088*cda5da8dSAndroid Build Coastguard Worker
1089*cda5da8dSAndroid Build Coastguard Worker
1090*cda5da8dSAndroid Build Coastguard Workerif name == 'nt':
1091*cda5da8dSAndroid Build Coastguard Worker    class _AddedDllDirectory:
1092*cda5da8dSAndroid Build Coastguard Worker        def __init__(self, path, cookie, remove_dll_directory):
1093*cda5da8dSAndroid Build Coastguard Worker            self.path = path
1094*cda5da8dSAndroid Build Coastguard Worker            self._cookie = cookie
1095*cda5da8dSAndroid Build Coastguard Worker            self._remove_dll_directory = remove_dll_directory
1096*cda5da8dSAndroid Build Coastguard Worker        def close(self):
1097*cda5da8dSAndroid Build Coastguard Worker            self._remove_dll_directory(self._cookie)
1098*cda5da8dSAndroid Build Coastguard Worker            self.path = None
1099*cda5da8dSAndroid Build Coastguard Worker        def __enter__(self):
1100*cda5da8dSAndroid Build Coastguard Worker            return self
1101*cda5da8dSAndroid Build Coastguard Worker        def __exit__(self, *args):
1102*cda5da8dSAndroid Build Coastguard Worker            self.close()
1103*cda5da8dSAndroid Build Coastguard Worker        def __repr__(self):
1104*cda5da8dSAndroid Build Coastguard Worker            if self.path:
1105*cda5da8dSAndroid Build Coastguard Worker                return "<AddedDllDirectory({!r})>".format(self.path)
1106*cda5da8dSAndroid Build Coastguard Worker            return "<AddedDllDirectory()>"
1107*cda5da8dSAndroid Build Coastguard Worker
1108*cda5da8dSAndroid Build Coastguard Worker    def add_dll_directory(path):
1109*cda5da8dSAndroid Build Coastguard Worker        """Add a path to the DLL search path.
1110*cda5da8dSAndroid Build Coastguard Worker
1111*cda5da8dSAndroid Build Coastguard Worker        This search path is used when resolving dependencies for imported
1112*cda5da8dSAndroid Build Coastguard Worker        extension modules (the module itself is resolved through sys.path),
1113*cda5da8dSAndroid Build Coastguard Worker        and also by ctypes.
1114*cda5da8dSAndroid Build Coastguard Worker
1115*cda5da8dSAndroid Build Coastguard Worker        Remove the directory by calling close() on the returned object or
1116*cda5da8dSAndroid Build Coastguard Worker        using it in a with statement.
1117*cda5da8dSAndroid Build Coastguard Worker        """
1118*cda5da8dSAndroid Build Coastguard Worker        import nt
1119*cda5da8dSAndroid Build Coastguard Worker        cookie = nt._add_dll_directory(path)
1120*cda5da8dSAndroid Build Coastguard Worker        return _AddedDllDirectory(
1121*cda5da8dSAndroid Build Coastguard Worker            path,
1122*cda5da8dSAndroid Build Coastguard Worker            cookie,
1123*cda5da8dSAndroid Build Coastguard Worker            nt._remove_dll_directory
1124*cda5da8dSAndroid Build Coastguard Worker        )
1125