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.
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%")
17 func chkStat(file
string) error
{
18 d
, err
:= os
.Stat(file
)
23 return os
.ErrPermission
28 func hasExt(file
string) bool {
29 i
:= strings
.LastIndex(file
, ".")
33 return strings
.LastIndexAny(file
, `:\/`) < i
36 func findExecutable(file
string, exts
[]string) (string, error
) {
38 return file
, chkStat(file
)
41 if chkStat(file
) == nil {
45 for _
, e
:= range exts
{
46 if f
:= file
+ e
; chkStat(f
) == nil {
50 return "", os
.ErrNotExist
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
) {
61 x
:= os
.Getenv(`PATHEXT`)
63 for _
, e
:= range strings
.Split(strings
.ToLower(x
), `;`) {
70 exts
= append(exts
, e
)
73 exts
= []string{".com", ".exe", ".bat", ".cmd"}
76 if strings
.ContainsAny(file
, `:\/`) {
77 if f
, err
:= findExecutable(file
, exts
); err
== nil {
80 return "", &Error
{file
, err
}
83 if f
, err
:= findExecutable(filepath
.Join(".", file
), exts
); err
== nil {
86 path
:= os
.Getenv("path")
87 for _
, dir
:= range filepath
.SplitList(path
) {
88 if f
, err
:= findExecutable(filepath
.Join(dir
, file
), exts
); err
== nil {
92 return "", &Error
{file
, ErrNotFound
}