Source file 
src/os/exec/lp_windows.go
     1  
     2  
     3  
     4  
     5  package exec
     6  
     7  import (
     8  	"errors"
     9  	"io/fs"
    10  	"os"
    11  	"path/filepath"
    12  	"strings"
    13  )
    14  
    15  
    16  var ErrNotFound = errors.New("executable file not found in %PATH%")
    17  
    18  func chkStat(file string) error {
    19  	d, err := os.Stat(file)
    20  	if err != nil {
    21  		return err
    22  	}
    23  	if d.IsDir() {
    24  		return fs.ErrPermission
    25  	}
    26  	return nil
    27  }
    28  
    29  func hasExt(file string) bool {
    30  	i := strings.LastIndex(file, ".")
    31  	if i < 0 {
    32  		return false
    33  	}
    34  	return strings.LastIndexAny(file, `:\/`) < i
    35  }
    36  
    37  func findExecutable(file string, exts []string) (string, error) {
    38  	if len(exts) == 0 {
    39  		return file, chkStat(file)
    40  	}
    41  	if hasExt(file) {
    42  		if chkStat(file) == nil {
    43  			return file, nil
    44  		}
    45  		
    46  		
    47  	}
    48  	for _, e := range exts {
    49  		if f := file + e; chkStat(f) == nil {
    50  			return f, nil
    51  		}
    52  	}
    53  	if hasExt(file) {
    54  		return "", fs.ErrNotExist
    55  	}
    56  	return "", ErrNotFound
    57  }
    58  
    59  
    60  
    61  
    62  
    63  
    64  
    65  
    66  
    67  
    68  
    69  func LookPath(file string) (string, error) {
    70  	if err := validateLookPath(file); err != nil {
    71  		return "", &Error{file, err}
    72  	}
    73  
    74  	return lookPath(file, pathExt())
    75  }
    76  
    77  
    78  
    79  
    80  
    81  
    82  
    83  
    84  
    85  
    86  func lookExtensions(path, dir string) (string, error) {
    87  	if err := validateLookPath(path); err != nil {
    88  		return "", &Error{path, err}
    89  	}
    90  
    91  	if filepath.Base(path) == path {
    92  		path = "." + string(filepath.Separator) + path
    93  	}
    94  	exts := pathExt()
    95  	if ext := filepath.Ext(path); ext != "" {
    96  		for _, e := range exts {
    97  			if strings.EqualFold(ext, e) {
    98  				
    99  				return path, nil
   100  			}
   101  		}
   102  	}
   103  	if dir == "" {
   104  		return lookPath(path, exts)
   105  	}
   106  	if filepath.VolumeName(path) != "" {
   107  		return lookPath(path, exts)
   108  	}
   109  	if len(path) > 1 && os.IsPathSeparator(path[0]) {
   110  		return lookPath(path, exts)
   111  	}
   112  	dirandpath := filepath.Join(dir, path)
   113  	
   114  	lp, err := lookPath(dirandpath, exts)
   115  	if err != nil {
   116  		return "", err
   117  	}
   118  	ext := strings.TrimPrefix(lp, dirandpath)
   119  	return path + ext, nil
   120  }
   121  
   122  func pathExt() []string {
   123  	var exts []string
   124  	x := os.Getenv(`PATHEXT`)
   125  	if x != "" {
   126  		for e := range strings.SplitSeq(strings.ToLower(x), `;`) {
   127  			if e == "" {
   128  				continue
   129  			}
   130  			if e[0] != '.' {
   131  				e = "." + e
   132  			}
   133  			exts = append(exts, e)
   134  		}
   135  	} else {
   136  		exts = []string{".com", ".exe", ".bat", ".cmd"}
   137  	}
   138  	return exts
   139  }
   140  
   141  
   142  func lookPath(file string, exts []string) (string, error) {
   143  	if strings.ContainsAny(file, `:\/`) {
   144  		f, err := findExecutable(file, exts)
   145  		if err == nil {
   146  			return f, nil
   147  		}
   148  		return "", &Error{file, err}
   149  	}
   150  
   151  	
   152  	
   153  	
   154  	
   155  	
   156  	
   157  	
   158  	
   159  	
   160  	var (
   161  		dotf   string
   162  		dotErr error
   163  	)
   164  	if _, found := os.LookupEnv("NoDefaultCurrentDirectoryInExePath"); !found {
   165  		if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
   166  			if execerrdot.Value() == "0" {
   167  				execerrdot.IncNonDefault()
   168  				return f, nil
   169  			}
   170  			dotf, dotErr = f, &Error{file, ErrDot}
   171  		}
   172  	}
   173  
   174  	path := os.Getenv("path")
   175  	for _, dir := range filepath.SplitList(path) {
   176  		if dir == "" {
   177  			
   178  			
   179  			continue
   180  		}
   181  
   182  		if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil {
   183  			if dotErr != nil {
   184  				
   185  				
   186  				
   187  				
   188  				
   189  				
   190  				
   191  				dotfi, dotfiErr := os.Lstat(dotf)
   192  				fi, fiErr := os.Lstat(f)
   193  				if dotfiErr != nil || fiErr != nil || !os.SameFile(dotfi, fi) {
   194  					return dotf, dotErr
   195  				}
   196  			}
   197  
   198  			if !filepath.IsAbs(f) {
   199  				if execerrdot.Value() != "0" {
   200  					
   201  					
   202  					
   203  					
   204  					if dotErr == nil {
   205  						dotf, dotErr = f, &Error{file, ErrDot}
   206  					}
   207  					continue
   208  				}
   209  				execerrdot.IncNonDefault()
   210  			}
   211  			return f, nil
   212  		}
   213  	}
   214  
   215  	if dotErr != nil {
   216  		return dotf, dotErr
   217  	}
   218  	return "", &Error{file, ErrNotFound}
   219  }
   220  
View as plain text