github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/os/exec/lp_unix.go (about) 1 // Copyright 2010 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 // +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris 6 7 package exec 8 9 import ( 10 "errors" 11 "os" 12 "path/filepath" 13 "strings" 14 ) 15 16 // ErrNotFound is the error resulting if a path search failed to find an executable file. 17 var ErrNotFound = errors.New("executable file not found in $PATH") 18 19 func findExecutable(file string) error { 20 d, err := os.Stat(file) 21 if err != nil { 22 return err 23 } 24 if m := d.Mode(); !m.IsDir() && m&0111 != 0 { 25 return nil 26 } 27 return os.ErrPermission 28 } 29 30 // LookPath searches for an executable named file in the 31 // directories named by the PATH environment variable. 32 // If file contains a slash, it is tried 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 // NOTE(rsc): I wish we could use the Plan 9 behavior here 36 // (only bypass the path if file begins with / or ./ or ../) 37 // but that would not match all the Unix shells. 38 39 if strings.Contains(file, "/") { 40 err := findExecutable(file) 41 if err == nil { 42 return file, nil 43 } 44 return "", &Error{file, err} 45 } 46 path := os.Getenv("PATH") 47 for _, dir := range filepath.SplitList(path) { 48 if dir == "" { 49 // Unix shell semantics: path element "" means "." 50 dir = "." 51 } 52 path := filepath.Join(dir, file) 53 if err := findExecutable(path); err == nil { 54 return path, nil 55 } 56 } 57 return "", &Error{file, ErrNotFound} 58 }