mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-05 11:37:46 +00:00
cgo: support errno value as second return parameter
Making this work on all targets was interesting but there's now a test in place to make sure this works on all targets that have the CGo test enabled (which is almost all targets).
This commit is contained in:
@@ -86,3 +86,16 @@ func AdjustTimeOffset(offset int64) {
|
||||
// TODO: do this atomically?
|
||||
timeOffset += offset
|
||||
}
|
||||
|
||||
// Picolibc is not configured to define its own errno value, instead it calls
|
||||
// __errno_location.
|
||||
// TODO: a global works well enough for now (same as errno on Linux with
|
||||
// -scheduler=tasks), but this should ideally be a thread-local variable stored
|
||||
// in task.Task.
|
||||
// Especially when we add multicore support for microcontrollers.
|
||||
var errno int32
|
||||
|
||||
//export __errno_location
|
||||
func libc_errno_location() *int32 {
|
||||
return &errno
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
|
||||
r1 = uintptr(result)
|
||||
if result == -1 {
|
||||
// Syscall returns -1 on failure.
|
||||
err = uintptr(*libc___error())
|
||||
err = uintptr(*libc_errno_location())
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -161,7 +161,7 @@ func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
|
||||
r1 = call_syscallX(fn, a1, a2, a3)
|
||||
if int64(r1) == -1 {
|
||||
// Syscall returns -1 on failure.
|
||||
err = uintptr(*libc___error())
|
||||
err = uintptr(*libc_errno_location())
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -171,7 +171,7 @@ func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
|
||||
r1 = call_syscallX(fn, a1, a2, a3)
|
||||
if r1 == 0 {
|
||||
// Syscall returns a pointer on success, or NULL on failure.
|
||||
err = uintptr(*libc___error())
|
||||
err = uintptr(*libc_errno_location())
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -182,7 +182,7 @@ func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
||||
r1 = uintptr(result)
|
||||
if result == -1 {
|
||||
// Syscall returns -1 on failure.
|
||||
err = uintptr(*libc___error())
|
||||
err = uintptr(*libc_errno_location())
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -192,7 +192,7 @@ func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
||||
r1 = call_syscall6X(fn, a1, a2, a3, a4, a5, a6)
|
||||
if int64(r1) == -1 {
|
||||
// Syscall returns -1 on failure.
|
||||
err = uintptr(*libc___error())
|
||||
err = uintptr(*libc_errno_location())
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -216,7 +216,7 @@ func libc_getpagesize() int32
|
||||
// }
|
||||
//
|
||||
//export __error
|
||||
func libc___error() *int32
|
||||
func libc_errno_location() *int32
|
||||
|
||||
//export tinygo_syscall
|
||||
func call_syscall(fn, a1, a2, a3 uintptr) int32
|
||||
|
||||
@@ -113,3 +113,6 @@ func syscall_Getpagesize() int {
|
||||
_GetSystemInfo(unsafe.Pointer(&info))
|
||||
return int(info.dwpagesize)
|
||||
}
|
||||
|
||||
//export _errno
|
||||
func libc_errno_location() *int32
|
||||
|
||||
@@ -127,3 +127,8 @@ func write(fd uintptr, p unsafe.Pointer, n int32) int32 {
|
||||
func getAuxv() []uintptr {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Called from cgo to obtain the errno value.
|
||||
func cgo_errno() uintptr {
|
||||
return uintptr(*libc_errno_location())
|
||||
}
|
||||
|
||||
@@ -313,3 +313,9 @@ func hardwareRand() (n uint64, ok bool) {
|
||||
// TODO: see whether there is a RNG and use it.
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func libc_errno_location() *int32 {
|
||||
// CGo is unavailable, so this function should be unreachable.
|
||||
runtimePanic("runtime: no cgo errno")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -112,3 +112,8 @@ func hardwareRand() (n uint64, ok bool) {
|
||||
//
|
||||
//export arc4random
|
||||
func libc_arc4random() uint32
|
||||
|
||||
// int *__errno_location(void);
|
||||
//
|
||||
//export __errno_location
|
||||
func libc_errno_location() *int32
|
||||
|
||||
@@ -51,3 +51,9 @@ func procUnpin() {
|
||||
func hardwareRand() (n uint64, ok bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func libc_errno_location() *int32 {
|
||||
// CGo is unavailable, so this function should be unreachable.
|
||||
runtimePanic("runtime: no cgo errno")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -81,3 +81,9 @@ func procUnpin() {
|
||||
func hardwareRand() (n uint64, ok bool) {
|
||||
return random.GetRandomU64(), true
|
||||
}
|
||||
|
||||
func libc_errno_location() *int32 {
|
||||
// CGo is unavailable, so this function should be unreachable.
|
||||
runtimePanic("runtime: no cgo errno")
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user