Host introspection: Difference between revisions

Content added Content deleted
(→‎{{header|Go}}: Replace /proc hack)
(→‎{{header|Go}}: Put back completely non-portable /proc hack but and some comments)
Line 261: Line 261:
import (
import (
"fmt"
"fmt"
"io/ioutil"
"runtime"
"runtime"
"strconv"
"strconv"
"strings"
"unsafe"
"unsafe"
)
)
Line 279: Line 281:
fmt.Println("mixed endian?")
fmt.Println("mixed endian?")
}
}

// Usually one cares about the size the executible was compiled for
// rather than the actual underlying host's size.


// There are several ways of determining the size of an int/uint.
// There are several ways of determining the size of an int/uint.
fmt.Println(" strconv.IntSize =", strconv.IntSize)
fmt.Println(" strconv.IntSize =", strconv.IntSize)
// That uses the following definition which can also be done by hand
// That uses the following definition we can also be done by hand
intSize := 32 << uint(^uint(0)>>63)
intSize := 32 << uint(^uint(0)>>63)
fmt.Println("32 << uint(^uint(0)>>63) =", intSize)
fmt.Println("32 << uint(^uint(0)>>63) =", intSize)
Line 293: Line 298:
fmt.Println(" sizeof(int) in bits:", unsafe.Sizeof(int(0))*bitsPerByte)
fmt.Println(" sizeof(int) in bits:", unsafe.Sizeof(int(0))*bitsPerByte)
fmt.Println(" sizeof(uintptr) in bits:", unsafe.Sizeof(uintptr(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
// If we really want to know the architecture size the executable was
// it safest to take the max of those.
// compiled for and not the size of int it safest to take the max of those.
archSize := unsafe.Sizeof(int(0))
archSize := unsafe.Sizeof(int(0))
if psize := unsafe.Sizeof(uintptr(0)); psize > archSize {
if psize := unsafe.Sizeof(uintptr(0)); psize > archSize {
archSize = psize
archSize = psize
}
}
fmt.Println(" architecture word size:", archSize*bitsPerByte)
fmt.Println(" compiled with word size:", archSize*bitsPerByte)

// There are some *very* unportable ways to attempt to get the actual
// underlying hosts' word size.
// Inspect cpuinfo to determine word size (some unix-like OS' only).
c, err := ioutil.ReadFile("/proc/cpuinfo")
if err != nil {
fmt.Println(err)
return
}
ls := strings.Split(string(c), "\n")
for _, l := range ls {
if strings.HasPrefix(l, "flags") {
for _, f := range strings.Fields(l) {
if f == "lm" { // "long mode"
fmt.Println("64 bit word size")
return
}
}
fmt.Println("32 bit word size")
return
}
}
}</lang>
}</lang>
{{out}}
{{out}}
Line 309: Line 336:
sizeof(int) in bits: 64
sizeof(int) in bits: 64
sizeof(uintptr) in bits: 64
sizeof(uintptr) in bits: 64
architecture word size: 64
compiled with word size: 64
open /proc/cpuinfo: no such file or directory
</pre>
</pre>
<pre>
<pre>
Line 318: Line 346:
sizeof(int) in bits: 32
sizeof(int) in bits: 32
sizeof(uintptr) in bits: 32
sizeof(uintptr) in bits: 32
architecture word size: 32
compiled with word size: 32
open /proc/cpuinfo: no such file or directory
</pre>
</pre>
<pre>
<pre>
Line 327: Line 356:
sizeof(int) in bits: 32
sizeof(int) in bits: 32
sizeof(uintptr) in bits: 32
sizeof(uintptr) in bits: 32
architecture word size: 32
compiled with word size: 32
open /proc/cpuinfo: No such file or directory
</pre>
</pre>
Alternative technique:
Alternative technique: