mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			105 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
// Copyright 2017 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.
 | 
						|
 | 
						|
// +build aix
 | 
						|
 | 
						|
package os
 | 
						|
 | 
						|
// We query the working directory at init, to use it later to search for the
 | 
						|
// executable file
 | 
						|
// errWd will be checked later, if we need to use initWd
 | 
						|
var initWd, errWd = Getwd()
 | 
						|
 | 
						|
func executable() (string, error) {
 | 
						|
	var err error
 | 
						|
	var exePath string
 | 
						|
	if len(Args) == 0 || Args[0] == "" {
 | 
						|
		return "", ErrNotExist
 | 
						|
	}
 | 
						|
	// Args[0] is an absolute path : this is the executable
 | 
						|
	if IsPathSeparator(Args[0][0]) {
 | 
						|
		exePath = Args[0]
 | 
						|
	} else {
 | 
						|
		for i := 1; i < len(Args[0]); i++ {
 | 
						|
			// Args[0] is a relative path : append current directory
 | 
						|
			if IsPathSeparator(Args[0][i]) {
 | 
						|
				if errWd != nil {
 | 
						|
					return "", errWd
 | 
						|
				}
 | 
						|
				exePath = initWd + string(PathSeparator) + Args[0]
 | 
						|
				break
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if exePath != "" {
 | 
						|
		err = isExecutable(exePath)
 | 
						|
		if err == nil {
 | 
						|
			return exePath, nil
 | 
						|
		}
 | 
						|
		// File does not exist or is not executable,
 | 
						|
		// this is an unexpected situation !
 | 
						|
		return "", err
 | 
						|
	}
 | 
						|
	// Search for executable in $PATH
 | 
						|
	for _, dir := range splitPathList(Getenv("PATH")) {
 | 
						|
		if len(dir) == 0 {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		if !IsPathSeparator(dir[0]) {
 | 
						|
			if errWd != nil {
 | 
						|
				return "", errWd
 | 
						|
			}
 | 
						|
			dir = initWd + string(PathSeparator) + dir
 | 
						|
		}
 | 
						|
		exePath = dir + string(PathSeparator) + Args[0]
 | 
						|
		err = isExecutable(exePath)
 | 
						|
		if err == nil {
 | 
						|
			return exePath, nil
 | 
						|
		}
 | 
						|
		if err == ErrPermission {
 | 
						|
			return "", err
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return "", ErrNotExist
 | 
						|
}
 | 
						|
 | 
						|
// isExecutable returns an error if a given file is not an executable.
 | 
						|
func isExecutable(path string) error {
 | 
						|
	stat, err := Stat(path)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	mode := stat.Mode()
 | 
						|
	if !mode.IsRegular() {
 | 
						|
		return ErrPermission
 | 
						|
	}
 | 
						|
	if (mode & 0111) != 0 {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	return ErrPermission
 | 
						|
}
 | 
						|
 | 
						|
// splitPathList splits a path list.
 | 
						|
// This is based on genSplit from strings/strings.go
 | 
						|
func splitPathList(pathList string) []string {
 | 
						|
	n := 1
 | 
						|
	for i := 0; i < len(pathList); i++ {
 | 
						|
		if pathList[i] == PathListSeparator {
 | 
						|
			n++
 | 
						|
		}
 | 
						|
	}
 | 
						|
	start := 0
 | 
						|
	a := make([]string, n)
 | 
						|
	na := 0
 | 
						|
	for i := 0; i+1 <= len(pathList) && na+1 < n; i++ {
 | 
						|
		if pathList[i] == PathListSeparator {
 | 
						|
			a[na] = pathList[start:i]
 | 
						|
			na++
 | 
						|
			start = i + 1
 | 
						|
		}
 | 
						|
	}
 | 
						|
	a[na] = pathList[start:]
 | 
						|
	return a[:na+1]
 | 
						|
}
 |