1// Copyright 2023 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//go:build unix 6 7package toolchain 8 9import ( 10 "internal/syscall/unix" 11 "io/fs" 12 "os" 13 "path/filepath" 14 "syscall" 15 16 "cmd/go/internal/gover" 17) 18 19// pathDirs returns the directories in the system search path. 20func pathDirs() []string { 21 return filepath.SplitList(os.Getenv("PATH")) 22} 23 24// pathVersion returns the Go version implemented by the file 25// described by de and info in directory dir. 26// The analysis only uses the name itself; it does not run the program. 27func pathVersion(dir string, de fs.DirEntry, info fs.FileInfo) (string, bool) { 28 v := gover.FromToolchain(de.Name()) 29 if v == "" { 30 return "", false 31 } 32 33 // Mimicking exec.findExecutable here. 34 // ENOSYS means Eaccess is not available or not implemented. 35 // EPERM can be returned by Linux containers employing seccomp. 36 // In both cases, fall back to checking the permission bits. 37 err := unix.Eaccess(filepath.Join(dir, de.Name()), unix.X_OK) 38 if (err == syscall.ENOSYS || err == syscall.EPERM) && info.Mode()&0111 != 0 { 39 err = nil 40 } 41 if err != nil { 42 return "", false 43 } 44 45 return v, true 46} 47