Host introspection: Difference between revisions

Content added Content deleted
(Add Nimrod)
(→‎{{header|Go}}: Replace /proc hack)
Line 260: Line 260:


import (
import (
"fmt"
"fmt"
"runtime"
"io/ioutil"
"strconv"
"strings"
"unsafe"
"unsafe"
)
)


func main() {
func main() {
fmt.Println(runtime.Version(), runtime.GOOS, runtime.GOARCH)
// inspect an int variable to determine endianness

x := 1
// Inspect a uint32 variable to determine endianness.
if *(*byte)(unsafe.Pointer(&x)) == 1 {
x := uint32(0x01020304)
fmt.Println("little endian")
switch *(*byte)(unsafe.Pointer(&x)) {
} else {
case 0x01:
fmt.Println("big endian")
fmt.Println("big endian")
}
case 0x04:
// inspect cpuinfo to determine word size (unix-like os only)
fmt.Println("little endian")
c, err := ioutil.ReadFile("/proc/cpuinfo")
default:
if err != nil {
fmt.Println(err)
fmt.Println("mixed endian?")
}
return

}
// There are several ways of determining the size of an int/uint.
ls := strings.Split(string(c), "\n")
fmt.Println(" strconv.IntSize =", strconv.IntSize)
for _, l := range ls {
// That uses the following definition which can also be done by hand
if strings.HasPrefix(l, "flags") {
intSize := 32 << uint(^uint(0)>>63)
for _, f := range strings.Fields(l) {
fmt.Println("32 << uint(^uint(0)>>63) =", intSize)
if f == "lm" { // "long mode"

fmt.Println("64 bit word size")
// With Go 1.0, 64-bit architectures had 32-bit int and 64-bit
return
// uintptr. This was changed in Go 1.1. In general it would
}
// still be possible that int and uintptr (the type large enough
}
// to hold the bit pattern of any pointer) are of different sizes.
fmt.Println("32 bit word size")
const bitsPerByte = 8
return
fmt.Println(" sizeof(int) in bits:", unsafe.Sizeof(int(0))*bitsPerByte)
}
fmt.Println(" sizeof(uintptr) in bits:", unsafe.Sizeof(uintptr(0))*bitsPerByte)
}
// If we really want to know the architecture size and not the size of int
fmt.Println("cpuinfo flags not found")
// it safest to take the max of those.
archSize := unsafe.Sizeof(int(0))
if psize := unsafe.Sizeof(uintptr(0)); psize > archSize {
archSize = psize
}
fmt.Println(" architecture word size:", archSize*bitsPerByte)
}</lang>
}</lang>
{{out}}
Output:
<pre>
go1.3.1 freebsd amd64
little endian
strconv.IntSize = 64
32 << uint(^uint(0)>>63) = 64
sizeof(int) in bits: 64
sizeof(uintptr) in bits: 64
architecture word size: 64
</pre>
<pre>
go1.3.1 freebsd 386
little endian
strconv.IntSize = 32
32 << uint(^uint(0)>>63) = 32
sizeof(int) in bits: 32
sizeof(uintptr) in bits: 32
architecture word size: 32
</pre>
<pre>
<pre>
go1.3.1 nacl amd64p32
little endian
little endian
strconv.IntSize = 32
64 bit word size
32 << uint(^uint(0)>>63) = 32
sizeof(int) in bits: 32
sizeof(uintptr) in bits: 32
architecture word size: 32
</pre>
</pre>
Alternative technique:
Alternative technique:
Line 318: Line 347:
f.Close()
f.Close()
}</lang>
}</lang>
{{out}}
Output:
<pre>
<pre>
LittleEndian
LittleEndian