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 |
// 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 |
// 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(" |
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 |
||
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 |
||
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 |
||
compiled with word size: 32 |
|||
open /proc/cpuinfo: No such file or directory |
|||
</pre> |
</pre> |
||
Alternative technique: |
Alternative technique: |