github.com/yukk001/go1.10.8@v0.0.0-20190813125351-6df2d3982e20/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  }