...
1 package xexec
2
3 import (
4 "io/fs"
5 "os"
6 "path/filepath"
7 "runtime"
8 "strings"
9 )
10
11
12 func findExecutable(file string) error {
13 d, err := os.Stat(file)
14 if err != nil {
15 return err
16 }
17 m := d.Mode()
18 if !m.IsDir() && m&0111 != 0 {
19 return nil
20 }
21 return fs.ErrPermission
22 }
23
24
25
26 func SearchPath(prefix string) ([]string, error) {
27 var matches []string
28 envPath := os.Getenv("PATH")
29 dirSet := make(map[string]struct{})
30 for _, dir := range filepath.SplitList(envPath) {
31 if dir == "" {
32
33
34 dir = "."
35 }
36 if _, ok := dirSet[dir]; ok {
37 continue
38 }
39 dirSet[dir] = struct{}{}
40 files, err := os.ReadDir(dir)
41 if err != nil {
42 continue
43 }
44 for _, f := range files {
45 if strings.HasPrefix(f.Name(), prefix) {
46 match := filepath.Join(dir, f.Name())
47
48
49 if runtime.GOOS == "windows" {
50 matches = append(matches, match)
51 continue
52 }
53 err = findExecutable(match)
54 if err == nil {
55 matches = append(matches, match)
56 }
57 }
58 }
59
60 }
61 return matches, nil
62 }
63
View as plain text