github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/os/exec/lp_windows.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 package exec 6 7 import ( 8 "errors" 9 "os" 10 "path/filepath" 11 "strings" 12 ) 13 14 // ErrNotFound is the error resulting if a path search failed to find an executable file. 15 var ErrNotFound = errors.New("executable file not found in %PATH%") 16 17 func chkStat(file string) error { 18 d, err := os.Stat(file) 19 if err != nil { 20 return err 21 } 22 if d.IsDir() { 23 return os.ErrPermission 24 } 25 return nil 26 } 27 28 func hasExt(file string) bool { 29 i := strings.LastIndex(file, ".") 30 if i < 0 { 31 return false 32 } 33 return strings.LastIndexAny(file, `:\/`) < i 34 } 35 36 func findExecutable(file string, exts []string) (string, error) { 37 if len(exts) == 0 { 38 return file, chkStat(file) 39 } 40 if hasExt(file) { 41 if chkStat(file) == nil { 42 return file, nil 43 } 44 } 45 for _, e := range exts { 46 if f := file + e; chkStat(f) == nil { 47 return f, nil 48 } 49 } 50 return "", os.ErrNotExist 51 } 52 53 // LookPath searches for an executable binary named file 54 // in the directories named by the PATH environment variable. 55 // If file contains a slash, it is tried directly and the PATH is not consulted. 56 // LookPath also uses PATHEXT environment variable to match 57 // a suitable candidate. 58 // The result may be an absolute path or a path relative to the current directory. 59 func LookPath(file string) (string, error) { 60 var exts []string 61 x := os.Getenv(`PATHEXT`) 62 if x != "" { 63 for _, e := range strings.Split(strings.ToLower(x), `;`) { 64 if e == "" { 65 continue 66 } 67 if e[0] != '.' { 68 e = "." + e 69 } 70 exts = append(exts, e) 71 } 72 } else { 73 exts = []string{".com", ".exe", ".bat", ".cmd"} 74 } 75 76 if strings.ContainsAny(file, `:\/`) { 77 if f, err := findExecutable(file, exts); err == nil { 78 return f, nil 79 } else { 80 return "", &Error{file, err} 81 } 82 } 83 if f, err := findExecutable(filepath.Join(".", file), exts); err == nil { 84 return f, nil 85 } 86 path := os.Getenv("path") 87 for _, dir := range filepath.SplitList(path) { 88 if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil { 89 return f, nil 90 } 91 } 92 return "", &Error{file, ErrNotFound} 93 }