def _execvpe(file, args, env=None): if env is not None: func = posix.execve argrest = (args, env) else: func = posix.execv argrest = (args, ) env = posix.environ head, tail = os_path.split(file) if head: func(file, *argrest) return if 'PATH' in env: envpath = env['PATH'] else: envpath = os_path.defpath PATH = envpath.split(os_path.pathsep) saved_exc = None saved_tb = None for dir in PATH: fullname = os_path.join(dir, file) try: func(fullname, *argrest) except posix.error as e: tb = sys.exc_info()[2] if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR and saved_exc is None): saved_exc = e saved_tb = tb # TODO: Don't use this archaic syntax? if saved_exc: raise posix.error, saved_exc, saved_tb raise posix.error, e, tb
def Matches(self, comp): # type: (Api) -> Iterator[Union[Iterator, Iterator[str]]] to_complete = comp.to_complete # Problem: .. and ../.. don't complete /. # TODO: Set display_pos before fixing this. #import os #to_complete = os.path.normpath(to_complete) dirname, basename = os_path.split(to_complete) if dirname == '': # We're completing in this directory to_list = '.' else: # We're completing in some other directory to_list = dirname if 0: log('basename %r', basename) log('to_list %r', to_list) log('dirname %r', dirname) try: names = posix.listdir(to_list) except OSError as e: return # nothing for name in names: path = os_path.join(dirname, name) if path.startswith(to_complete): if self.dirs_only: # add_slash not used here # NOTE: There is a duplicate isdir() check later to add a trailing # slash. Consolidate the checks for fewer stat() ops. This is hard # because all the completion actions must obey the same interface. # We could have another type like candidate = File | Dir | # OtherString ? if path_stat.isdir(path): yield path continue if self.exec_only: # TODO: Handle exception if file gets deleted in between listing and # check? if not posix.access(path, posix.X_OK_): continue if self.add_slash and path_stat.isdir(path): yield path + '/' else: yield path