github.com/sakana/etcdctl@v0.1.2-0.20130925194301-eab7435d452d/third_party/bitbucket.org/kardianos/osext/osext_sysctl.go (about) 1 // Copyright 2012 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 // +build darwin freebsd 6 7 package osext 8 9 import ( 10 "os" 11 "runtime" 12 "syscall" 13 "unsafe" 14 ) 15 16 var startUpcwd, getwdError = os.Getwd() 17 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 // get length 29 _, _, err := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0) 30 if err != 0 { 31 return "", err 32 } 33 if n == 0 { // shouldn't happen 34 return "", nil 35 } 36 buf := make([]byte, n) 37 _, _, err = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0) 38 if err != 0 { 39 return "", err 40 } 41 if n == 0 { // shouldn't happen 42 return "", nil 43 } 44 for i, v := range buf { 45 if v == 0 { 46 buf = buf[:i] 47 break 48 } 49 } 50 if buf[0] != '/' { 51 if getwdError != nil { 52 return string(buf), getwdError 53 } else { 54 if buf[0] == '.' { 55 buf = buf[1:] 56 } 57 if startUpcwd[len(startUpcwd)-1] != '/' { 58 return startUpcwd + "/" + string(buf), nil 59 } 60 return startUpcwd + string(buf), nil 61 } 62 } 63 return string(buf), nil 64 }