[release-branch.go1.19] runtime: change fcntl to return two values

Separate the result and the errno value, rather than assuming
that the result can never be negative.

Change-Id: Ib01a70a3d46285aa77e95371cdde74e1504e7c12
Reviewed-on: https://go-review.googlesource.com/c/go/+/496416
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/497136
Run-TryBot: Roland Shoemaker <roland@golang.org>
Auto-Submit: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Ian Lance Taylor 2023-05-18 21:13:03 -07:00 committed by Gopher Robot
parent ecb9ecfb72
commit 65cc8e6ad8
26 changed files with 167 additions and 101 deletions

View File

@ -31,11 +31,11 @@ func TestNonblockingPipe(t *testing.T) {
if runtime.Close(r) != 0 { if runtime.Close(r) != 0 {
t.Fatalf("Close(%d) failed", r) t.Fatalf("Close(%d) failed", r)
} }
val := runtime.Fcntl(r, syscall.F_GETFD, 0) val, errno := runtime.Fcntl(r, syscall.F_GETFD, 0)
if val >= 0 { if val != -1 {
t.Errorf("Fcntl succeeded unexpectedly") t.Errorf("Fcntl succeeded unexpectedly")
} else if syscall.Errno(-val) != syscall.EBADF { } else if syscall.Errno(errno) != syscall.EBADF {
t.Errorf("Fcntl failed with error %v, expected %v", -val, syscall.EBADF) t.Errorf("Fcntl failed with error %v, expected %v", syscall.Errno(errno), syscall.EBADF)
} }
} }
@ -55,9 +55,9 @@ func checkIsPipe(t *testing.T, r, w int32) {
func checkNonblocking(t *testing.T, fd int32, name string) { func checkNonblocking(t *testing.T, fd int32, name string) {
t.Helper() t.Helper()
flags := runtime.Fcntl(fd, syscall.F_GETFL, 0) flags, errno := runtime.Fcntl(fd, syscall.F_GETFL, 0)
if flags < 0 { if flags == -1 {
t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(-flags)) t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(errno))
} else if flags&syscall.O_NONBLOCK == 0 { } else if flags&syscall.O_NONBLOCK == 0 {
t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags) t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags)
} }
@ -65,9 +65,9 @@ func checkNonblocking(t *testing.T, fd int32, name string) {
func checkCloseonexec(t *testing.T, fd int32, name string) { func checkCloseonexec(t *testing.T, fd int32, name string) {
t.Helper() t.Helper()
flags := runtime.Fcntl(fd, syscall.F_GETFD, 0) flags, errno := runtime.Fcntl(fd, syscall.F_GETFD, 0)
if flags < 0 { if flags == -1 {
t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(flags)) t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(errno))
} else if flags&syscall.FD_CLOEXEC == 0 { } else if flags&syscall.FD_CLOEXEC == 0 {
t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags) t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags)
} }

View File

@ -569,12 +569,9 @@ func pipe2(flags int32) (r, w int32, errno int32) {
} }
//go:nosplit //go:nosplit
func fcntl(fd, cmd, arg int32) int32 { func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
r1, err := sysvicall3Err(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg)) r1, err := sysvicall3Err(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))
if r := int32(r1); r >= 0 { return int32(r1), int32(err)
return r
}
return -int32(err)
} }
//go:nosplit //go:nosplit

View File

@ -361,12 +361,9 @@ func walltime() (sec int64, nsec int32) {
} }
//go:nosplit //go:nosplit
func fcntl(fd, cmd, arg int32) int32 { func fcntl(fd, cmd, arg int32) (int32, int32) {
r, errno := syscall3(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg)) r, errno := syscall3(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))
if int32(r) < 0 { return int32(r), int32(errno)
return -int32(errno)
}
return int32(r)
} }
//go:nosplit //go:nosplit
@ -376,8 +373,10 @@ func closeonexec(fd int32) {
//go:nosplit //go:nosplit
func setNonblock(fd int32) { func setNonblock(fd int32) {
flags := fcntl(fd, _F_GETFL, 0) flags, _ := fcntl(fd, _F_GETFL, 0)
fcntl(fd, _F_SETFL, flags|_O_NONBLOCK) if flags != -1 {
fcntl(fd, _F_SETFL, flags|_O_NONBLOCK)
}
} }
// sigPerThreadSyscall is only used on linux, so we assign a bogus signal // sigPerThreadSyscall is only used on linux, so we assign a bogus signal

View File

@ -63,7 +63,7 @@ func kqueue() int32
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func pipe2(flags int32) (r, w int32, errno int32) func pipe2(flags int32) (r, w int32, errno int32)
func fcntl(fd, cmd, arg int32) int32 func fcntl(fd, cmd, arg int32) (ret int32, errno int32)
func closeonexec(fd int32) func closeonexec(fd int32)
// From DragonFly's <sys/sysctl.h> // From DragonFly's <sys/sysctl.h>

View File

@ -48,7 +48,7 @@ func kqueue() int32
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func pipe2(flags int32) (r, w int32, errno int32) func pipe2(flags int32) (r, w int32, errno int32)
func fcntl(fd, cmd, arg int32) int32 func fcntl(fd, cmd, arg int32) (ret int32, errno int32)
func closeonexec(fd int32) func closeonexec(fd int32)
// From FreeBSD's <sys/sysctl.h> // From FreeBSD's <sys/sysctl.h>

View File

@ -457,13 +457,9 @@ func osyield_no_g() {
func pipe2(flags int32) (r, w int32, errno int32) func pipe2(flags int32) (r, w int32, errno int32)
//go:nosplit //go:nosplit
func fcntl(fd, cmd, arg int32) int32 { func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
r, _, errno := syscall.Syscall6(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0) r, _, err := syscall.Syscall6(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
ri := int32(r) return int32(r), int32(err)
if ri < 0 {
return -int32(errno)
}
return ri
} }
const ( const (

View File

@ -79,7 +79,7 @@ func kqueue() int32
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
func pipe2(flags int32) (r, w int32, errno int32) func pipe2(flags int32) (r, w int32, errno int32)
func fcntl(fd, cmd, arg int32) int32 func fcntl(fd, cmd, arg int32) (ret int32, errno int32)
func closeonexec(fd int32) func closeonexec(fd int32)
const ( const (

View File

@ -95,7 +95,7 @@ func nanotime1() int64
//go:noescape //go:noescape
func sigaltstack(new, old *stackt) func sigaltstack(new, old *stackt)
func fcntl(fd, cmd, arg int32) int32 func fcntl(fd, cmd, arg int32) (ret int32, errno int32)
func closeonexec(fd int32) func closeonexec(fd int32)
func walltime() (sec int64, nsec int32) func walltime() (sec int64, nsec int32)

View File

@ -382,8 +382,13 @@ func sysctlbyname_trampoline()
//go:nosplit //go:nosplit
//go:cgo_unsafe_args //go:cgo_unsafe_args
func fcntl(fd, cmd, arg int32) int32 { func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&fd)) args := struct {
fd, cmd, arg int32
ret, errno int32
}{fd, cmd, arg, 0, 0}
libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&args))
return args.ret, args.errno
} }
func fcntl_trampoline() func fcntl_trampoline()
@ -485,8 +490,10 @@ func closeonexec(fd int32) {
//go:nosplit //go:nosplit
func setNonblock(fd int32) { func setNonblock(fd int32) {
flags := fcntl(fd, _F_GETFL, 0) flags, _ := fcntl(fd, _F_GETFL, 0)
fcntl(fd, _F_SETFL, flags|_O_NONBLOCK) if flags != -1 {
fcntl(fd, _F_SETFL, flags|_O_NONBLOCK)
}
} }
// Tell the linker that the libc_* functions are to be found // Tell the linker that the libc_* functions are to be found

View File

@ -432,17 +432,21 @@ ok:
TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
PUSHQ BP PUSHQ BP
MOVQ SP, BP MOVQ SP, BP
MOVL 4(DI), SI // arg 2 cmd MOVQ DI, BX
MOVL 8(DI), DX // arg 3 arg MOVL 0(BX), DI // arg 1 fd
MOVL 0(DI), DI // arg 1 fd MOVL 4(BX), SI // arg 2 cmd
MOVL 8(BX), DX // arg 3 arg
XORL AX, AX // vararg: say "no float args" XORL AX, AX // vararg: say "no float args"
CALL libc_fcntl(SB) CALL libc_fcntl(SB)
TESTL AX, AX XORL DX, DX
JGT noerr CMPQ AX, $-1
JNE noerr
CALL libc_error(SB) CALL libc_error(SB)
MOVL (AX), AX MOVL (AX), DX
NEGL AX // caller expects negative errno value MOVL $-1, AX
noerr: noerr:
MOVL AX, 12(BX)
MOVL DX, 16(BX)
POPQ BP POPQ BP
RET RET

View File

@ -309,18 +309,22 @@ ok:
TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
SUB $16, RSP SUB $16, RSP
MOVW 4(R0), R1 // arg 2 cmd MOVD R0, R19
MOVW 8(R0), R2 // arg 3 arg MOVW 0(R19), R0 // arg 1 fd
MOVW 4(R19), R1 // arg 2 cmd
MOVW 8(R19), R2 // arg 3 arg
MOVW R2, (RSP) // arg 3 is variadic, pass on stack MOVW R2, (RSP) // arg 3 is variadic, pass on stack
MOVW 0(R0), R0 // arg 1 fd
BL libc_fcntl(SB) BL libc_fcntl(SB)
MOVD $-1, R1 MOVD $0, R1
CMP R0, R1 MOVD $-1, R2
CMP R0, R2
BNE noerr BNE noerr
BL libc_error(SB) BL libc_error(SB)
MOVW (R0), R0 MOVW (R0), R1
NEG R0, R0 // caller expects negative errno value MOVW $-1, R0
noerr: noerr:
MOVW R0, 12(R19)
MOVW R1, 16(R19)
ADD $16, RSP ADD $16, RSP
RET RET

View File

@ -387,16 +387,20 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
MOVL AX, ret+48(FP) MOVL AX, ret+48(FP)
RET RET
// func fcntl(fd, cmd, arg int32) int32 // func fcntl(fd, cmd, arg int32) (ret int32, errno int32)
TEXT runtime·fcntl(SB),NOSPLIT,$0 TEXT runtime·fcntl(SB),NOSPLIT,$0
MOVL fd+0(FP), DI // fd MOVL fd+0(FP), DI // fd
MOVL cmd+4(FP), SI // cmd MOVL cmd+4(FP), SI // cmd
MOVL arg+8(FP), DX // arg MOVL arg+8(FP), DX // arg
MOVL $92, AX // fcntl MOVL $92, AX // fcntl
SYSCALL SYSCALL
JCC 2(PC) JCC noerr
NEGL AX // caller expects negative errno MOVL $-1, ret+16(FP)
MOVL AX, errno+20(FP)
RET
noerr:
MOVL AX, ret+16(FP) MOVL AX, ret+16(FP)
MOVL $0, errno+20(FP)
RET RET
// void runtime·closeonexec(int32 fd); // void runtime·closeonexec(int32 fd);

View File

@ -415,13 +415,17 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
MOVL AX, ret+24(FP) MOVL AX, ret+24(FP)
RET RET
// func fcntl(fd, cmd, arg int32) int32 // func fcntl(fd, cmd, arg int32) (int32, int32)
TEXT runtime·fcntl(SB),NOSPLIT,$-4 TEXT runtime·fcntl(SB),NOSPLIT,$-4
MOVL $92, AX MOVL $92, AX
INT $0x80 INT $0x80
JAE 2(PC) JAE noerr
NEGL AX // caller expects negative errno MOVL $-1, ret+12(FP)
MOVL AX, errno+16(FP)
RET
noerr:
MOVL AX, ret+12(FP) MOVL AX, ret+12(FP)
MOVL $0, errno+16(FP)
RET RET
// int32 runtime·closeonexec(int32 fd); // int32 runtime·closeonexec(int32 fd);

View File

@ -483,16 +483,20 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
MOVL AX, ret+48(FP) MOVL AX, ret+48(FP)
RET RET
// func fcntl(fd, cmd, arg int32) int32 // func fcntl(fd, cmd, arg int32) (int32, int32)
TEXT runtime·fcntl(SB),NOSPLIT,$0 TEXT runtime·fcntl(SB),NOSPLIT,$0
MOVL fd+0(FP), DI // fd MOVL fd+0(FP), DI // fd
MOVL cmd+4(FP), SI // cmd MOVL cmd+4(FP), SI // cmd
MOVL arg+8(FP), DX // arg MOVL arg+8(FP), DX // arg
MOVL $92, AX MOVL $92, AX
SYSCALL SYSCALL
JCC 2(PC) JCC noerr
NEGQ AX // caller expects negative errno MOVL $-1, ret+16(FP)
MOVL AX, errno+20(FP)
RET
noerr:
MOVL AX, ret+16(FP) MOVL AX, ret+16(FP)
MOVL $0, errno+20(FP)
RET RET
// void runtime·closeonexec(int32 fd); // void runtime·closeonexec(int32 fd);

View File

@ -387,15 +387,18 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
MOVW R0, ret+24(FP) MOVW R0, ret+24(FP)
RET RET
// func fcntl(fd, cmd, arg int32) int32 // func fcntl(fd, cmd, arg int32) (int32, int32)
TEXT runtime·fcntl(SB),NOSPLIT,$0 TEXT runtime·fcntl(SB),NOSPLIT,$0
MOVW fd+0(FP), R0 // fd MOVW fd+0(FP), R0 // fd
MOVW cmd+4(FP), R1 // cmd MOVW cmd+4(FP), R1 // cmd
MOVW arg+8(FP), R2 // arg MOVW arg+8(FP), R2 // arg
MOVW $SYS_fcntl, R7 MOVW $SYS_fcntl, R7
SWI $0 SWI $0
RSB.CS $0, R0 // caller expects negative errno MOVW $0, R1
MOVW.CS R0, R1
MOVW.CS $-1, R0
MOVW R0, ret+12(FP) MOVW R0, ret+12(FP)
MOVW R1, errno+16(FP)
RET RET
// void runtime·closeonexec(int32 fd) // void runtime·closeonexec(int32 fd)

View File

@ -444,17 +444,21 @@ ok:
MOVW R0, ret+48(FP) MOVW R0, ret+48(FP)
RET RET
// func fcntl(fd, cmd, arg int32) int32 // func fcntl(fd, cmd, arg int32) (int32, int32)
TEXT runtime·fcntl(SB),NOSPLIT,$0 TEXT runtime·fcntl(SB),NOSPLIT,$0
MOVW fd+0(FP), R0 MOVW fd+0(FP), R0
MOVW cmd+4(FP), R1 MOVW cmd+4(FP), R1
MOVW arg+8(FP), R2 MOVW arg+8(FP), R2
MOVD $SYS_fcntl, R8 MOVD $SYS_fcntl, R8
SVC SVC
BCC ok BCC noerr
NEG R0, R0 // caller expects negative errno MOVW $-1, R1
ok: MOVW R1, ret+16(FP)
MOVW R0, errno+20(FP)
RET
noerr:
MOVW R0, ret+16(FP) MOVW R0, ret+16(FP)
MOVW $0, errno+20(FP)
RET RET
// func closeonexec(fd int32) // func closeonexec(fd int32)

View File

@ -457,13 +457,17 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
MOVL AX, ret+24(FP) MOVL AX, ret+24(FP)
RET RET
// func fcntl(fd, cmd, arg int32) int32 // func fcntl(fd, cmd, arg int32) (int32, int32)
TEXT runtime·fcntl(SB),NOSPLIT,$-4 TEXT runtime·fcntl(SB),NOSPLIT,$-4
MOVL $SYS_fcntl, AX MOVL $SYS_fcntl, AX
INT $0x80 INT $0x80
JAE 2(PC) JAE noerr
NEGL AX // caller expects negative errno MOVL $-1, ret+12(FP)
MOVL AX, errno+16(FP)
RET
noerr:
MOVL AX, ret+12(FP) MOVL AX, ret+12(FP)
MOVL $0, errno+16(FP)
RET RET
// int32 runtime·closeonexec(int32 fd) // int32 runtime·closeonexec(int32 fd)

View File

@ -434,16 +434,20 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
MOVL AX, ret+48(FP) MOVL AX, ret+48(FP)
RET RET
// func fcntl(fd, cmd, arg int32) int2 // func fcntl(fd, cmd, arg int32) (int32, int32)
TEXT runtime·fcntl(SB),NOSPLIT,$0 TEXT runtime·fcntl(SB),NOSPLIT,$0
MOVL fd+0(FP), DI // fd MOVL fd+0(FP), DI // fd
MOVL cmd+4(FP), SI // cmd MOVL cmd+4(FP), SI // cmd
MOVL arg+8(FP), DX // arg MOVL arg+8(FP), DX // arg
MOVL $SYS_fcntl, AX MOVL $SYS_fcntl, AX
SYSCALL SYSCALL
JCC 2(PC) JCC noerr
NEGQ AX // caller expects negative errno MOVL $-1, ret+16(FP)
MOVL AX, errno+20(FP)
RET
noerr:
MOVL AX, ret+16(FP) MOVL AX, ret+16(FP)
MOVL $0, errno+20(FP)
RET RET
// void runtime·closeonexec(int32 fd) // void runtime·closeonexec(int32 fd)

View File

@ -404,8 +404,11 @@ TEXT runtime·fcntl(SB),NOSPLIT,$0
MOVW cmd+4(FP), R1 MOVW cmd+4(FP), R1
MOVW arg+8(FP), R2 MOVW arg+8(FP), R2
SWI $SYS_fcntl SWI $SYS_fcntl
RSB.CS $0, R0 // caller expects negative errno MOVW $0, R1
MOVW.CS R0, R1
MOVW.CS $-1, R0
MOVW R0, ret+12(FP) MOVW R0, ret+12(FP)
MOVW R1, errno+16(FP)
RET RET
// void runtime·closeonexec(int32 fd) // void runtime·closeonexec(int32 fd)

View File

@ -421,16 +421,20 @@ ok:
MOVW R0, ret+48(FP) MOVW R0, ret+48(FP)
RET RET
// func fcntl(fd, cmd, arg int32) int32 // func fcntl(fd, cmd, arg int32) (int32, int32)
TEXT runtime·fcntl(SB),NOSPLIT,$0 TEXT runtime·fcntl(SB),NOSPLIT,$0
MOVW fd+0(FP), R0 // fd MOVW fd+0(FP), R0 // fd
MOVW cmd+4(FP), R1 // cmd MOVW cmd+4(FP), R1 // cmd
MOVW arg+8(FP), R2 // arg MOVW arg+8(FP), R2 // arg
SVC $SYS_fcntl SVC $SYS_fcntl
BCC ok BCC noerr
NEG R0, R0 // caller expects negative errno MOVW $-1, R1
ok: MOVW R1, ret+16(FP)
MOVW R0, errno+20(FP)
RET
noerr:
MOVW R0, ret+16(FP) MOVW R0, ret+16(FP)
MOVW $0, errno+20(FP)
RET RET
// void runtime·closeonexec(int32 fd) // void runtime·closeonexec(int32 fd)

View File

@ -161,8 +161,13 @@ func sysctl_trampoline()
//go:nosplit //go:nosplit
//go:cgo_unsafe_args //go:cgo_unsafe_args
func fcntl(fd, cmd, arg int32) int32 { func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
return libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&fd)) args := struct {
fd, cmd, arg int32
ret, errno int32
}{fd, cmd, arg, 0, 0}
libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&args))
return args.ret, args.errno
} }
func fcntl_trampoline() func fcntl_trampoline()

View File

@ -542,12 +542,16 @@ TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
MOVL CX, 8(SP) // arg 3 - arg MOVL CX, 8(SP) // arg 3 - arg
MOVL $0, 12(SP) // vararg MOVL $0, 12(SP) // vararg
CALL libc_fcntl(SB) CALL libc_fcntl(SB)
MOVL $0, BX
CMPL AX, $-1 CMPL AX, $-1
JNE noerr JNE noerr
CALL libc_errno(SB) CALL libc_errno(SB)
MOVL (AX), AX MOVL (AX), BX
NEGL AX // caller expects negative errno MOVL $-1, AX
noerr: noerr:
MOVL 24(SP), DX // pointer to args
MOVL AX, 12(DX)
MOVL BX, 16(DX)
MOVL BP, SP MOVL BP, SP
POPL BP POPL BP
RET RET

View File

@ -388,17 +388,21 @@ noerr:
TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
PUSHQ BP PUSHQ BP
MOVQ SP, BP MOVQ SP, BP
MOVL 4(DI), SI // arg 2 cmd MOVQ DI, BX
MOVL 8(DI), DX // arg 3 arg MOVL 0(BX), DI // arg 1 fd
MOVL 0(DI), DI // arg 1 fd MOVL 4(BX), SI // arg 2 cmd
MOVL 8(BX), DX // arg 3 arg
XORL AX, AX // vararg: say "no float args" XORL AX, AX // vararg: say "no float args"
CALL libc_fcntl(SB) CALL libc_fcntl(SB)
TESTL AX, AX XORL DX, DX
JGE noerr CMPL AX, $-1
JNE noerr
CALL libc_errno(SB) CALL libc_errno(SB)
MOVL (AX), AX MOVL (AX), DX
NEGL AX // caller expects negative errno value MOVL $-1, AX
noerr: noerr:
MOVL AX, 12(BX)
MOVL DX, 16(BX)
POPQ BP POPQ BP
RET RET

View File

@ -419,17 +419,21 @@ TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
MOVW R13, R9 MOVW R13, R9
SUB $8, R13 SUB $8, R13
BIC $0x7, R13 // align for ELF ABI BIC $0x7, R13 // align for ELF ABI
MOVW 4(R0), R1 // arg 2 cmd MOVW R0, R8
MOVW 8(R0), R2 // arg 3 arg (vararg, on stack) MOVW 0(R8), R0 // arg 1 fd
MOVW 4(R8), R1 // arg 2 cmd
MOVW 8(R8), R2 // arg 3 arg (vararg, on stack)
MOVW R2, 0(R13) MOVW R2, 0(R13)
MOVW 0(R0), R0 // arg 1 fd
BL libc_fcntl(SB) BL libc_fcntl(SB)
MOVW $0, R1
CMP $-1, R0 CMP $-1, R0
BNE noerr BNE noerr
BL libc_errno(SB) BL libc_errno(SB)
MOVW (R0), R0 MOVW (R0), R1
RSB.CS $0, R0 // caller expects negative errno MOVW $-1, R0
noerr: noerr:
MOVW R0, 12(R8)
MOVW R1, 16(R8)
MOVW R9, R13 MOVW R9, R13
RET RET

View File

@ -306,17 +306,21 @@ noerr:
RET RET
TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
MOVW 4(R0), R1 // arg 2 - cmd MOVD R0, R19
MOVW 8(R0), R2 // arg 3 - arg MOVW 0(R19), R0 // arg 1 - fd
MOVW 0(R0), R0 // arg 1 - fd MOVW 4(R19), R1 // arg 2 - cmd
MOVW 8(R19), R2 // arg 3 - arg
MOVD $0, R3 // vararg MOVD $0, R3 // vararg
CALL libc_fcntl(SB) CALL libc_fcntl(SB)
MOVD $0, R1
CMP $-1, R0 CMP $-1, R0
BNE noerr BNE noerr
CALL libc_errno(SB) CALL libc_errno(SB)
MOVW (R0), R0 MOVW (R0), R1
NEG R0, R0 // caller expects negative errno value MOVW $-1, R0
noerr: noerr:
MOVW R0, 12(R19)
MOVW R1, 16(R19)
RET RET
TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0

View File

@ -364,16 +364,20 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
MOVW R2, ret+48(FP) MOVW R2, ret+48(FP)
RET RET
// func fcntl(fd, cmd, arg int32) int32 // func fcntl(fd, cmd, arg int32) (int32, int32)
TEXT runtime·fcntl(SB),NOSPLIT,$0 TEXT runtime·fcntl(SB),NOSPLIT,$0
MOVW fd+0(FP), R4 // fd MOVW fd+0(FP), R4 // fd
MOVW cmd+4(FP), R5 // cmd MOVW cmd+4(FP), R5 // cmd
MOVW arg+8(FP), R6 // arg MOVW arg+8(FP), R6 // arg
MOVV $92, R2 // sys_fcntl MOVV $92, R2 // sys_fcntl
SYSCALL SYSCALL
BEQ R7, 2(PC) MOVV $0, R4
SUBVU R2, R0, R2 // caller expects negative errno BEQ R7, noerr
MOVV R2, R4
MOVW $-1, R2
noerr:
MOVW R2, ret+16(FP) MOVW R2, ret+16(FP)
MOVW R4, errno+20(FP)
RET RET
// func closeonexec(fd int32) // func closeonexec(fd int32)