12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- // Copyright 2012 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 darwin freebsd
- package osext
- import (
- "os"
- "path/filepath"
- "runtime"
- "syscall"
- "unsafe"
- )
- var startUpcwd, getwdError = os.Getwd()
- func executable() (string, error) {
- var mib [4]int32
- switch runtime.GOOS {
- case "freebsd":
- mib = [4]int32{1 /* CTL_KERN */, 14 /* KERN_PROC */, 12 /* KERN_PROC_PATHNAME */, -1}
- case "darwin":
- mib = [4]int32{1 /* CTL_KERN */, 38 /* KERN_PROCARGS */, int32(os.Getpid()), -1}
- }
- n := uintptr(0)
- // get length
- _, _, err := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
- if err != 0 {
- return "", err
- }
- if n == 0 { // shouldn't happen
- return "", nil
- }
- buf := make([]byte, n)
- _, _, err = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0)
- if err != 0 {
- return "", err
- }
- if n == 0 { // shouldn't happen
- return "", nil
- }
- for i, v := range buf {
- if v == 0 {
- buf = buf[:i]
- break
- }
- }
- var strpath string
- if buf[0] != '/' {
- var e error
- if strpath, e = getAbs(buf); e != nil {
- return strpath, e
- }
- } else {
- strpath = string(buf)
- }
- // darwin KERN_PROCARGS may return the path to a symlink rather than the
- // actual executable
- if runtime.GOOS == "darwin" {
- if strpath, err := filepath.EvalSymlinks(strpath); err != nil {
- return strpath, err
- }
- }
- return strpath, nil
- }
- func getAbs(buf []byte) (string, error) {
- if getwdError != nil {
- return string(buf), getwdError
- } else {
- if buf[0] == '.' {
- buf = buf[1:]
- }
- if startUpcwd[len(startUpcwd)-1] != '/' && buf[0] != '/' {
- return startUpcwd + "/" + string(buf), nil
- }
- return startUpcwd + string(buf), nil
- }
- }
|