Host introspection: Difference between revisions
Content added Content deleted
(Add Nimrod) |
(→{{header|Go}}: Replace /proc hack) |
||
Line 260: | Line 260: | ||
import ( |
import ( |
||
"fmt" |
|||
"runtime" |
|||
"io/ioutil" |
|||
"strconv" |
|||
"strings" |
|||
"unsafe" |
|||
) |
) |
||
func main() { |
func main() { |
||
fmt.Println(runtime.Version(), runtime.GOOS, runtime.GOARCH) |
|||
⚫ | |||
x := 1 |
|||
⚫ | |||
⚫ | |||
x := uint32(0x01020304) |
|||
⚫ | |||
⚫ | |||
} else { |
|||
case 0x01: |
|||
fmt.Println("big endian") |
|||
} |
|||
case 0x04: |
|||
// inspect cpuinfo to determine word size (unix-like os only) |
|||
⚫ | |||
c, err := ioutil.ReadFile("/proc/cpuinfo") |
|||
default: |
|||
if err != nil { |
|||
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 |