github.com/stevenmatthewt/agent@v3.5.4+incompatible/bootstrap/shell/lookpath.go (about)

     1  // +build !windows
     2  
     3  // This file (along with it's Windows counterpart) have been taken from:
     4  //
     5  // https://github.com/golang/go/blob/master/src/os/exec/lp.go
     6  //
     7  // Their implemenations are exactly the same, however in this version - the
     8  // paths to search in (along with file extensions to look at) can be
     9  // customized.
    10  
    11  package shell
    12  
    13  import (
    14  	"os"
    15  	"os/exec"
    16  	"path/filepath"
    17  	"strings"
    18  )
    19  
    20  func findExecutable(file string) error {
    21  	d, err := os.Stat(file)
    22  	if err != nil {
    23  		return err
    24  	}
    25  	if m := d.Mode(); !m.IsDir() && m&0111 != 0 {
    26  		return nil
    27  	}
    28  	return os.ErrPermission
    29  }
    30  
    31  // LookPath searches for an executable binary named file in the directories within the path variable,
    32  // which is a colon delimited path.
    33  // If file contains a slash, it is tried directly
    34  func LookPath(file string, path string, fileExtensions string) (string, error) {
    35  	if strings.Contains(file, "/") {
    36  		err := findExecutable(file)
    37  		if err == nil {
    38  			return file, nil
    39  		}
    40  		return "", &exec.Error{file, err}
    41  	}
    42  	for _, dir := range filepath.SplitList(path) {
    43  		if dir == "" {
    44  			// Unix shell semantics: path element "" means "."
    45  			dir = "."
    46  		}
    47  		path := filepath.Join(dir, file)
    48  		if err := findExecutable(path); err == nil {
    49  			return path, nil
    50  		}
    51  	}
    52  	return "", &exec.Error{file, exec.ErrNotFound}
    53  }