Skip to content

Commit

Permalink
Merge pull request #54 from giuseppe/fix-auxv-enoent
Browse files Browse the repository at this point in the history
host: use /proc/self/auxv only when not using cgo
  • Loading branch information
vrothberg authored Jun 28, 2019
2 parents fbef66e + 4a0ced8 commit 0729b3f
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 62 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export GO111MODULE=off

SHELL= /bin/bash
GO ?= go
BUILD_DIR := ./bin
Expand Down Expand Up @@ -51,7 +53,7 @@ install:
.PHONY: .install.lint
.install.lint:
# Workaround for https://github.com/golangci/golangci-lint/issues/523
go get -u github.com/golangci/golangci-lint/cmd/golangci-lint@master
go get -u github.com/golangci/golangci-lint/cmd/golangci-lint

.PHONY: uninstall
uninstall:
Expand Down
61 changes: 0 additions & 61 deletions internal/host/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,73 +18,12 @@ package host

import (
"bufio"
"encoding/binary"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
"unsafe"
)

var (
// cache host queries to redundant calculations
clockTicks *int64
bootTime *int64
)

func getNativeEndianness() binary.ByteOrder {
var i int32 = 0x00000001
u := unsafe.Pointer(&i)
if *((*byte)(u)) == 0x01 {
return binary.LittleEndian
}
return binary.BigEndian
}

const (
atClktck = 17
)

func getFromAuxv(what uint, whatName string) (uint, error) {
dataLen := int(unsafe.Sizeof(int(0)))
p, err := ioutil.ReadFile("/proc/self/auxv")
if err != nil {
return 0, err
}
native := getNativeEndianness()
for i := 0; i < len(p); {
var k, v uint

switch dataLen {
case 4:
k = uint(native.Uint32(p[i : i+dataLen]))
v = uint(native.Uint32(p[i+dataLen : i+dataLen*2]))
case 8:
k = uint(native.Uint64(p[i : i+dataLen]))
v = uint(native.Uint64(p[i+dataLen : i+dataLen*2]))
}
i += dataLen * 2
if k == what {
return v, nil
}
}
return 0, fmt.Errorf("cannot find %s in auxv", whatName)
}

// ClockTicks returns sysconf(SC_CLK_TCK).
func ClockTicks() (int64, error) {
if clockTicks == nil {
ret, err := getFromAuxv(atClktck, "AT_CLKTCK")
if err != nil {
return -1, err
}
ticks := int64(ret)
clockTicks = &ticks
}
return *clockTicks, nil
}

// BootTime parses /proc/uptime returns the boot time in seconds since the
// Epoch, 1970-01-01 00:00:00 +0000 (UTC).
func BootTime() (int64, error) {
Expand Down
37 changes: 37 additions & 0 deletions internal/host/host_cgo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2018 psgo authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package host extracts data from the host, such as the system's boot time or
// the tick rate of the system clock.
package host

/*
#include <unistd.h>
*/
import "C"

var (
// cache host queries to redundant calculations
clockTicks *int64
bootTime *int64
)

// ClockTicks returns sysconf(SC_CLK_TCK).
func ClockTicks() (int64, error) {
if clockTicks == nil {
ticks := int64(C.sysconf(C._SC_CLK_TCK))
clockTicks = &ticks
}
return *clockTicks, nil
}
84 changes: 84 additions & 0 deletions internal/host/host_nocgo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// +build !cgo

// Copyright 2018 psgo authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package host extracts data from the host, such as the system's boot time or
// the tick rate of the system clock.
package host

import (
"encoding/binary"
"fmt"
"io/ioutil"
"unsafe"
)

var (
// cache host queries to redundant calculations
clockTicks *int64
bootTime *int64
)

func getNativeEndianness() binary.ByteOrder {
var i int32 = 0x00000001
u := unsafe.Pointer(&i)
if *((*byte)(u)) == 0x01 {
return binary.LittleEndian
}
return binary.BigEndian
}

const (
atClktck = 17
)

func getFromAuxv(what uint, whatName string) (uint, error) {
dataLen := int(unsafe.Sizeof(int(0)))
p, err := ioutil.ReadFile("/proc/self/auxv")
if err != nil {
return 0, err
}
native := getNativeEndianness()
for i := 0; i < len(p); {
var k, v uint

switch dataLen {
case 4:
k = uint(native.Uint32(p[i : i+dataLen]))
v = uint(native.Uint32(p[i+dataLen : i+dataLen*2]))
case 8:
k = uint(native.Uint64(p[i : i+dataLen]))
v = uint(native.Uint64(p[i+dataLen : i+dataLen*2]))
}
i += dataLen * 2
if k == what {
return v, nil
}
}
return 0, fmt.Errorf("cannot find %s in auxv", whatName)
}

// ClockTicks returns sysconf(SC_CLK_TCK).
func ClockTicks() (int64, error) {
if clockTicks == nil {
ret, err := getFromAuxv(atClktck, "AT_CLKTCK")
if err != nil {
return -1, err
}
ticks := int64(ret)
clockTicks = &ticks
}
return *clockTicks, nil
}

0 comments on commit 0729b3f

Please sign in to comment.