...
Source file
src/os/executable_path.go
Documentation: os
1
2
3
4
5
6
7
8 package os
9
10
11
12
13 var initWd, errWd = Getwd()
14
15 func executable() (string, error) {
16 var exePath string
17 if len(Args) == 0 || Args[0] == "" {
18 return "", ErrNotExist
19 }
20 if IsPathSeparator(Args[0][0]) {
21
22
23 exePath = Args[0]
24 } else {
25 for i := 1; i < len(Args[0]); i++ {
26 if IsPathSeparator(Args[0][i]) {
27
28
29 if errWd != nil {
30 return "", errWd
31 }
32 exePath = initWd + string(PathSeparator) + Args[0]
33 break
34 }
35 }
36 }
37 if exePath != "" {
38 if err := isExecutable(exePath); err != nil {
39 return "", err
40 }
41 return exePath, nil
42 }
43
44 for _, dir := range splitPathList(Getenv("PATH")) {
45 if len(dir) == 0 {
46 dir = "."
47 }
48 if !IsPathSeparator(dir[0]) {
49 if errWd != nil {
50 return "", errWd
51 }
52 dir = initWd + string(PathSeparator) + dir
53 }
54 exePath = dir + string(PathSeparator) + Args[0]
55 switch isExecutable(exePath) {
56 case nil:
57 return exePath, nil
58 case ErrPermission:
59 return "", ErrPermission
60 }
61 }
62 return "", ErrNotExist
63 }
64
65
66 func isExecutable(path string) error {
67 stat, err := Stat(path)
68 if err != nil {
69 return err
70 }
71 mode := stat.Mode()
72 if !mode.IsRegular() {
73 return ErrPermission
74 }
75 if (mode & 0111) == 0 {
76 return ErrPermission
77 }
78 return nil
79 }
80
81
82
83 func splitPathList(pathList string) []string {
84 if pathList == "" {
85 return nil
86 }
87 n := 1
88 for i := 0; i < len(pathList); i++ {
89 if pathList[i] == PathListSeparator {
90 n++
91 }
92 }
93 start := 0
94 a := make([]string, n)
95 na := 0
96 for i := 0; i+1 <= len(pathList) && na+1 < n; i++ {
97 if pathList[i] == PathListSeparator {
98 a[na] = pathList[start:i]
99 na++
100 start = i + 1
101 }
102 }
103 a[na] = pathList[start:]
104 return a[:na+1]
105 }
106
View as plain text