github.com/slantview/etcdctl@v0.1.3-0.20131011185546-5aaeca137f94/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  }