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