github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/os/exec/lp_plan9.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package exec 6 7 import ( 8 "errors" 9 "io/fs" 10 "os" 11 "path/filepath" 12 "strings" 13 ) 14 15 // ErrNotFound is the error resulting if a path search failed to find an executable file. 16 var ErrNotFound = errors.New("executable file not found in $path") 17 18 func findExecutable(file string) error { 19 d, err := os.Stat(file) 20 if err != nil { 21 return err 22 } 23 if m := d.Mode(); !m.IsDir() && m&0111 != 0 { 24 return nil 25 } 26 return fs.ErrPermission 27 } 28 29 // LookPath searches for an executable named file in the 30 // directories named by the path environment variable. 31 // If file begins with "/", "#", "./", or "../", it is tried 32 // directly and the path is not consulted. 33 // The result may be an absolute path or a path relative to the current directory. 34 func LookPath(file string) (string, error) { 35 // skip the path lookup for these prefixes 36 skip := []string{"/", "#", "./", "../"} 37 38 for _, p := range skip { 39 if strings.HasPrefix(file, p) { 40 err := findExecutable(file) 41 if err == nil { 42 return file, nil 43 } 44 return "", &Error{file, err} 45 } 46 } 47 48 path := os.Getenv("path") 49 for _, dir := range filepath.SplitList(path) { 50 path := filepath.Join(dir, file) 51 if err := findExecutable(path); err == nil { 52 return path, nil 53 } 54 } 55 return "", &Error{file, ErrNotFound} 56 }