| // Copyright 2011 The Go Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style | 
 | // license that can be found in the LICENSE file. | 
 |  | 
 | package exec | 
 |  | 
 | import ( | 
 | 	"errors" | 
 | 	"os" | 
 | 	"path/filepath" | 
 | 	"strings" | 
 | ) | 
 |  | 
 | // ErrNotFound is the error resulting if a path search failed to find an executable file. | 
 | var ErrNotFound = errors.New("executable file not found in $path") | 
 |  | 
 | func findExecutable(file string) error { | 
 | 	d, err := os.Stat(file) | 
 | 	if err != nil { | 
 | 		return err | 
 | 	} | 
 | 	if m := d.Mode(); !m.IsDir() && m&0111 != 0 { | 
 | 		return nil | 
 | 	} | 
 | 	return os.ErrPermission | 
 | } | 
 |  | 
 | // LookPath searches for an executable named file in the | 
 | // directories named by the path environment variable. | 
 | // If file begins with "/", "#", "./", or "../", it is tried | 
 | // directly and the path is not consulted. | 
 | // The result may be an absolute path or a path relative to the current directory. | 
 | func LookPath(file string) (string, error) { | 
 | 	// skip the path lookup for these prefixes | 
 | 	skip := []string{"/", "#", "./", "../"} | 
 |  | 
 | 	for _, p := range skip { | 
 | 		if strings.HasPrefix(file, p) { | 
 | 			err := findExecutable(file) | 
 | 			if err == nil { | 
 | 				return file, nil | 
 | 			} | 
 | 			return "", &Error{file, err} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	path := os.Getenv("path") | 
 | 	for _, dir := range filepath.SplitList(path) { | 
 | 		path := filepath.Join(dir, file) | 
 | 		if err := findExecutable(path); err == nil { | 
 | 			return path, nil | 
 | 		} | 
 | 	} | 
 | 	return "", &Error{file, ErrNotFound} | 
 | } |