1
2
3
4
5
6
7 package unix
8
9 import (
10 "sync/atomic"
11 "syscall"
12 "unsafe"
13 )
14
15
16
17 func vgetrandom(p []byte, flags uint32) (ret int, supported bool)
18
19 var getrandomUnsupported atomic.Bool
20
21
22 type GetRandomFlag uintptr
23
24
25 func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) {
26 ret, supported := vgetrandom(p, uint32(flags))
27 if supported {
28 if ret < 0 {
29 return 0, syscall.Errno(-ret)
30 }
31 return ret, nil
32 }
33 if getrandomUnsupported.Load() {
34 return 0, syscall.ENOSYS
35 }
36 r1, _, errno := syscall.Syscall(getrandomTrap,
37 uintptr(unsafe.Pointer(unsafe.SliceData(p))),
38 uintptr(len(p)),
39 uintptr(flags))
40 if errno != 0 {
41 if errno == syscall.ENOSYS {
42 getrandomUnsupported.Store(true)
43 }
44 return 0, errno
45 }
46 return int(r1), nil
47 }
48
View as plain text