github.com/btwiuse/jiri@v0.0.0-20191125065820-53353bcfef54/osutil/exec_sysctl.go (about) 1 // Copyright 2016 The Fuchsia 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 // +build freebsd darwin 6 7 package osutil 8 9 import ( 10 "os" 11 "path/filepath" 12 "runtime" 13 "syscall" 14 "unsafe" 15 ) 16 17 // Executable returns an absolute path to the currently executing program. 18 func Executable() (string, error) { 19 var mib [4]int32 20 switch runtime.GOOS { 21 case "freebsd": 22 mib = [4]int32{1 /* CTL_KERN */, 14 /* KERN_PROC */, 12 /* KERN_PROC_PATHNAME */, -1} 23 case "darwin": 24 mib = [4]int32{1 /* CTL_KERN */, 38 /* KERN_PROCARGS */, int32(os.Getpid()), -1} 25 } 26 27 n := uintptr(0) 28 _, _, err := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0) 29 if err != 0 { 30 return "", err 31 } 32 if n == 0 { 33 return "", nil 34 } 35 buf := make([]byte, n) 36 _, _, err = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0) 37 if err != 0 { 38 return "", err 39 } 40 if n == 0 { 41 return "", nil 42 } 43 for i, v := range buf { 44 if v == 0 { 45 buf = buf[:i] 46 break 47 } 48 } 49 p := string(buf) 50 if !filepath.IsAbs(p) { 51 wd, err := os.Getwd() 52 if err != nil { 53 return p, err 54 } 55 p = filepath.Join(wd, filepath.Clean(p)) 56 } 57 return filepath.EvalSymlinks(p) 58 }