diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py index 7cb5fb80bce0..e1469dca2a92 100644 --- a/src/python/bcc/__init__.py +++ b/src/python/bcc/__init__.py @@ -118,6 +118,35 @@ def _find_file(filename): raise Exception("Could not find file %s" % filename) return filename + @staticmethod + def _find_exe(cls, bin_path): + """ + _find_exe(bin_path) + + Traverses the PATH environment variable, looking for the first + directory that contains an executable file named bin_path, and + returns the full path to that file, or None if no such file + can be found. This is meant to replace invocations of the + "which" shell utility, which doesn't have portable semantics + for skipping aliases. + """ + # Source: http://stackoverflow.com/a/377028 + def is_exe(fpath): + return os.path.isfile(fpath) and \ + os.access(fpath, os.X_OK) + + fpath, fname = os.path.split(bin_path) + if fpath: + if is_exe(bin_path): + return bin_path + else: + for path in os.environ["PATH"].split(os.pathsep): + path = path.strip('"') + exe_file = os.path.join(path, bin_path) + if is_exe(exe_file): + return exe_file + return None + def __init__(self, src_file="", hdr_file="", text=None, cb=None, debug=0, cflags=[], usdt=None): """Create a a new BPF module with the given source code. @@ -487,7 +516,8 @@ def _check_path_symbol(cls, module, symname, addr): @staticmethod def find_library(libname): - return lib.bcc_procutils_which_so(libname.encode("ascii")).decode() + res = lib.bcc_procutils_which_so(libname.encode("ascii")) + return res if res is None else res.decode() def attach_tracepoint(self, tp="", fn_name="", pid=-1, cpu=0, group_fd=-1): """attach_tracepoint(tp="", fn_name="", pid=-1, cpu=0, group_fd=-1) diff --git a/tools/argdist.py b/tools/argdist.py index 36d0425dc473..fa9276c0d677 100755 --- a/tools/argdist.py +++ b/tools/argdist.py @@ -371,7 +371,7 @@ def generate_text(self): def _attach_u(self): libpath = BPF.find_library(self.library) if libpath is None: - libpath = ProcUtils.which(self.library) + libpath = BPF._find_exe(self.library) if libpath is None or len(libpath) == 0: self._bail("unable to find library %s" % self.library) diff --git a/tools/trace.py b/tools/trace.py index 8fff394cd765..d4b604b2f272 100755 --- a/tools/trace.py +++ b/tools/trace.py @@ -9,7 +9,7 @@ # Licensed under the Apache License, Version 2.0 (the "License") # Copyright (C) 2016 Sasha Goldshtein. -from bcc import BPF, Tracepoint, Perf, ProcUtils, USDT +from bcc import BPF, Tracepoint, Perf, USDT from time import sleep, strftime import argparse import re @@ -416,7 +416,7 @@ def _attach_u(self, bpf): libpath = BPF.find_library(self.library) if libpath is None: # This might be an executable (e.g. 'bash') - libpath = ProcUtils.which(self.library) + libpath = BPF._find_exe(self.library) if libpath is None or len(libpath) == 0: self._bail("unable to find library %s" % self.library)