package runtime
-var Fcntl = syscall_fcntl1
var SetNonblock = setNonblock
package runtime
-func Fcntl(fd, cmd, arg uintptr) (uintptr, uintptr) {
- r := fcntl(int32(fd), int32(cmd), int32(arg))
- if r < 0 {
- return ^uintptr(0), uintptr(-r)
- }
- return uintptr(r), 0
-}
-
var SetNonblock = setNonblock
+++ /dev/null
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build openbsd && !mips64
-
-package runtime
-
-func Fcntl(fd, cmd, arg uintptr) (uintptr, uintptr) {
- r := fcntl(int32(fd), int32(cmd), int32(arg))
- if r < 0 {
- return ^uintptr(0), uintptr(-r)
- }
- return uintptr(r), 0
-}
+++ /dev/null
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-func Fcntl(fd, cmd, arg uintptr) (uintptr, uintptr) {
- return sysvicall3Err(&libc_fcntl, fd, cmd, arg)
-}
import "unsafe"
var NonblockingPipe = nonblockingPipe
+var Fcntl = fcntl
func sigismember(mask *sigset, i int) bool {
clear := *mask
+++ /dev/null
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build aix || darwin || (openbsd && !mips64) || solaris
-
-package runtime_test
-
-import (
- "runtime"
- "syscall"
-)
-
-// Call fcntl libc function rather than calling syscall.
-func fcntl(fd uintptr, cmd int, arg uintptr) (uintptr, syscall.Errno) {
- res, errno := runtime.Fcntl(fd, uintptr(cmd), arg)
- return res, syscall.Errno(errno)
-}
+++ /dev/null
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build dragonfly || freebsd || linux || netbsd || (openbsd && mips64)
-
-package runtime_test
-
-import (
- "internal/syscall/unix"
- "syscall"
-)
-
-func fcntl(fd uintptr, cmd int, arg uintptr) (uintptr, syscall.Errno) {
- res, _, err := syscall.Syscall(unix.FcntlSyscall, fd, uintptr(cmd), arg)
- return res, err
-}
)
func TestNonblockingPipe(t *testing.T) {
- t.Parallel()
-
// NonblockingPipe is the test name for nonblockingPipe.
r, w, errno := runtime.NonblockingPipe()
if errno != 0 {
t.Fatal(syscall.Errno(errno))
}
- defer func() {
- runtime.Close(r)
- runtime.Close(w)
- }()
+ defer runtime.Close(w)
checkIsPipe(t, r, w)
checkNonblocking(t, r, "reader")
checkCloseonexec(t, r, "reader")
checkNonblocking(t, w, "writer")
checkCloseonexec(t, w, "writer")
+
+ // Test that fcntl returns an error as expected.
+ if runtime.Close(r) != 0 {
+ t.Fatalf("Close(%d) failed", r)
+ }
+ val := runtime.Fcntl(r, syscall.F_GETFD, 0)
+ if val >= 0 {
+ t.Errorf("Fcntl succeeded unexpectedly")
+ } else if syscall.Errno(-val) != syscall.EBADF {
+ t.Errorf("Fcntl failed with error %v, expected %v", -val, syscall.EBADF)
+ }
}
func checkIsPipe(t *testing.T, r, w int32) {
func checkNonblocking(t *testing.T, fd int32, name string) {
t.Helper()
- flags, errno := fcntl(uintptr(fd), syscall.F_GETFL, 0)
- if errno != 0 {
- t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(errno))
+ flags := runtime.Fcntl(fd, syscall.F_GETFL, 0)
+ if flags < 0 {
+ t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(-flags))
} else if flags&syscall.O_NONBLOCK == 0 {
t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags)
}
func checkCloseonexec(t *testing.T, fd int32, name string) {
t.Helper()
- flags, errno := fcntl(uintptr(fd), syscall.F_GETFD, 0)
- if errno != 0 {
- t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(errno))
+ flags := runtime.Fcntl(fd, syscall.F_GETFD, 0)
+ if flags < 0 {
+ t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(flags))
} else if flags&syscall.FD_CLOEXEC == 0 {
t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags)
}
return *getg().m.perrno
}
-func fcntl(fd, cmd, arg int32) int32 {
- return int32(sysvicall3(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg)))
-}
-
func port_create() int32 {
return int32(sysvicall0(&libc_port_create))
}
return p[0], p[1], int32(e)
}
+//go:nosplit
+func fcntl(fd, cmd, arg int32) int32 {
+ r1, err := sysvicall3Err(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))
+ if r := int32(r1); r >= 0 {
+ return r
+ }
+ return -int32(err)
+}
+
//go:nosplit
func closeonexec(fd int32) {
fcntl(fd, _F_SETFD, _FD_CLOEXEC)
//go:nosplit
func fcntl(fd, cmd, arg int32) int32 {
- r, _ := 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(errno)
+ }
return int32(r)
}
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 fcntl(fd, cmd, arg int32) int32
func closeonexec(fd int32)
// From DragonFly's <sys/sysctl.h>
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 fcntl(fd, cmd, arg int32) int32
func closeonexec(fd int32)
// From FreeBSD's <sys/sysctl.h>
func pipe2(flags int32) (r, w int32, errno int32)
+//go:nosplit
+func fcntl(fd, cmd, arg int32) int32 {
+ r, _, errno := syscall.Syscall6(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
+ ri := int32(r)
+ if ri < 0 {
+ return -int32(errno)
+ }
+ return ri
+}
+
const (
_si_max_size = 128
_sigev_max_size = 64
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 fcntl(fd, cmd, arg int32) int32
func closeonexec(fd int32)
const (
//go:noescape
func sigaltstack(new, old *stackt)
+func fcntl(fd, cmd, arg int32) int32
func closeonexec(fd int32)
func walltime() (sec int64, nsec int32)
//go:cgo_unsafe_args
// sysvicall3Err returns both the system call result and the errno value.
-// This is used by sysicall3 and write1.
+// This is used by sysvicall3 and write1.
func sysvicall3Err(fn *libcFunc, a1, a2, a3 uintptr) (r1, err uintptr) {
// Leave caller's PC/SP around for traceback.
gp := getg()
MOVL 0(DI), DI // arg 1 fd
XORL AX, AX // vararg: say "no float args"
CALL libc_fcntl(SB)
+ TESTL AX, AX
+ JGT noerr
+ CALL libc_error(SB)
+ MOVL (AX), AX
+ NEGL AX // caller expects negative errno value
+noerr:
POPQ BP
RET
MOVW R2, (RSP) // arg 3 is variadic, pass on stack
MOVW 0(R0), R0 // arg 1 fd
BL libc_fcntl(SB)
+ MOVD $-1, R1
+ CMP R0, R1
+ BNE noerr
+ BL libc_error(SB)
+ MOVW (R0), R0
+ NEG R0, R0 // caller expects negative errno value
+noerr:
ADD $16, RSP
RET
MOVL AX, ret+48(FP)
RET
+// func fcntl(fd, cmd, arg int32) int32
+TEXT runtime·fcntl(SB),NOSPLIT,$0
+ MOVL fd+0(FP), DI // fd
+ MOVL cmd+4(FP), SI // cmd
+ MOVL arg+8(FP), DX // arg
+ MOVL $92, AX // fcntl
+ SYSCALL
+ JCC 2(PC)
+ NEGL AX // caller expects negative errno
+ MOVL AX, ret+16(FP)
+ RET
+
// void runtime·closeonexec(int32 fd);
TEXT runtime·closeonexec(SB),NOSPLIT,$0
MOVL fd+0(FP), DI // fd
MOVL AX, ret+24(FP)
RET
+// func fcntl(fd, cmd, arg int32) int32
+TEXT runtime·fcntl(SB),NOSPLIT,$-4
+ MOVL $SYS_fcntl, AX
+ INT $0x80
+ JAE 2(PC)
+ NEGL AX // caller expects negative errno
+ MOVL AX, ret+12(FP)
+ RET
+
// int32 runtime·closeonexec(int32 fd);
TEXT runtime·closeonexec(SB),NOSPLIT,$32
MOVL $SYS_fcntl, AX
MOVL AX, ret+48(FP)
RET
+// func fcntl(fd, cmd, arg int32) int32
+TEXT runtime·fcntl(SB),NOSPLIT,$0
+ MOVL fd+0(FP), DI // fd
+ MOVL cmd+4(FP), SI // cmd
+ MOVL arg+8(FP), DX // arg
+ MOVL $SYS_fcntl, AX
+ SYSCALL
+ JCC 2(PC)
+ NEGQ AX // caller expects negative errno
+ MOVL AX, ret+16(FP)
+ RET
+
// void runtime·closeonexec(int32 fd);
TEXT runtime·closeonexec(SB),NOSPLIT,$0
MOVL fd+0(FP), DI // fd
MOVW R0, ret+24(FP)
RET
+// func fcntl(fd, cmd, arg int32) int32
+TEXT runtime·fcntl(SB),NOSPLIT,$0
+ MOVW fd+0(FP), R0 // fd
+ MOVW cmd+4(FP), R1 // cmd
+ MOVW arg+8(FP), R2 // arg
+ MOVW $SYS_fcntl, R7
+ SWI $0
+ RSB.CS $0, R0 // caller expects negative errno
+ MOVW R0, ret+12(FP)
+ RET
+
// void runtime·closeonexec(int32 fd)
TEXT runtime·closeonexec(SB),NOSPLIT,$0
MOVW fd+0(FP), R0 // fd
MOVW R0, ret+48(FP)
RET
+// func fcntl(fd, cmd, arg int32) int32
+TEXT runtime·fcntl(SB),NOSPLIT,$0
+ MOVW fd+0(FP), R0
+ MOVW cmd+4(FP), R1
+ MOVW arg+8(FP), R2
+ MOVD $SYS_fcntl, R8
+ SVC
+ BCC ok
+ NEG R0, R0 // caller expects negative errno
+ok:
+ MOVW R0, ret+16(FP)
+ RET
+
// func closeonexec(fd int32)
TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
MOVW fd+0(FP), R0
MOVW A0, ret+48(FP)
RET
+// func fcntl(fd, cmd, arg int32) int32
+TEXT runtime·fcntl(SB),NOSPLIT,$0
+ MOVW fd+0(FP), A0
+ MOVW cmd+4(FP), A1
+ MOVW arg+8(FP), A2
+ MOV $SYS_fcntl, T0
+ ECALL
+ BEQ T0, ZERO, ok
+ NEG A0, A0 // caller expects negative errno
+ok:
+ MOVW A0, ret+16(FP)
+ RET
+
// func closeonexec(fd int32)
TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
MOVW fd+0(FP), A0
MOVL AX, ret+24(FP)
RET
+// func fcntl(fd, cmd, arg int32) int32
+TEXT runtime·fcntl(SB),NOSPLIT,$-4
+ MOVL $SYS_fcntl, AX
+ INT $0x80
+ JAE 2(PC)
+ NEGL AX // caller expects negative errno
+ MOVL AX, ret+12(FP)
+ RET
+
// int32 runtime·closeonexec(int32 fd)
TEXT runtime·closeonexec(SB),NOSPLIT,$32
MOVL $SYS_fcntl, AX
MOVL AX, ret+48(FP)
RET
+// func fcntl(fd, cmd, arg int32) int2
+TEXT runtime·fcntl(SB),NOSPLIT,$0
+ MOVL fd+0(FP), DI // fd
+ MOVL cmd+4(FP), SI // cmd
+ MOVL arg+8(FP), DX // arg
+ MOVL $SYS_fcntl, AX
+ SYSCALL
+ JCC 2(PC)
+ NEGQ AX // caller expects negative errno
+ MOVL AX, ret+16(FP)
+ RET
+
// void runtime·closeonexec(int32 fd)
TEXT runtime·closeonexec(SB),NOSPLIT,$0
MOVL fd+0(FP), DI // fd
MOVW R0, ret+24(FP)
RET
+// func fcntl(fd, cmd, args int32) int32
+TEXT runtime·fcntl(SB),NOSPLIT,$0
+ MOVW fd+0(FP), R0
+ MOVW cmd+4(FP), R1
+ MOVW arg+8(FP), R2
+ SWI $SYS_fcntl
+ RSB.CS $0, R0 // caller expects negative errno
+ MOVW R0, ret+12(FP)
+ RET
+
// void runtime·closeonexec(int32 fd)
TEXT runtime·closeonexec(SB),NOSPLIT,$0
MOVW fd+0(FP), R0 // fd
MOVW R0, ret+48(FP)
RET
+// func fcntl(fd, cmd, arg int32) int32
+TEXT runtime·fcntl(SB),NOSPLIT,$0
+ MOVW fd+0(FP), R0 // fd
+ MOVW cmd+4(FP), R1 // cmd
+ MOVW arg+8(FP), R2 // arg
+ SVC $SYS_fcntl
+ BCC ok
+ NEG R0, R0 // caller expects negative errno
+ok:
+ MOVW R0, ret+16(FP)
+ RET
+
// void runtime·closeonexec(int32 fd)
TEXT runtime·closeonexec(SB),NOSPLIT,$0
MOVW fd+0(FP), R0 // arg 1 - fd
MOVL CX, 8(SP) // arg 3 - arg
MOVL $0, 12(SP) // vararg
CALL libc_fcntl(SB)
+ CMPL AX, $-1
+ JNE noerr
+ CALL libc_errno(SB)
+ MOVL (AX), AX
+ NEGL AX // caller expects negative errno
+noerr:
MOVL BP, SP
POPL BP
RET
MOVL 0(DI), DI // arg 1 fd
XORL AX, AX // vararg: say "no float args"
CALL libc_fcntl(SB)
+ TESTL AX, AX
+ JGE noerr
+ CALL libc_errno(SB)
+ MOVL (AX), AX
+ NEGL AX // caller expects negative errno value
+noerr:
POPQ BP
RET
MOVW R2, 0(R13)
MOVW 0(R0), R0 // arg 1 fd
BL libc_fcntl(SB)
+ CMP $-1, R0
+ BNE noerr
+ BL libc_errno(SB)
+ MOVW (R0), R0
+ RSB.CS $0, R0 // caller expects negative errno
+noerr:
MOVW R9, R13
RET
MOVW 0(R0), R0 // arg 1 - fd
MOVD $0, R3 // vararg
CALL libc_fcntl(SB)
+ CMP $-1, R0
+ BNE noerr
+ CALL libc_errno(SB)
+ MOVW (R0), R0
+ NEG R0, R0 // caller expects negative errno value
+noerr:
RET
TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
MOVW R2, ret+48(FP)
RET
+// func fcntl(fd, cmd, arg int32) int32
+TEXT runtime·fcntl(SB),NOSPLIT,$0
+ MOVW fd+0(FP), R4 // fd
+ MOVW cmd+4(FP), R5 // cmd
+ MOVW arg+8(FP), R6 // arg
+ MOVV $92, R2 // sys_fcntl
+ SYSCALL
+ BEQ R7, 2(PC)
+ SUBVU R2, R0, R2 // caller expects negative errno
+ MOVW R2, ret+16(FP)
+ RET
+
// func closeonexec(fd int32)
TEXT runtime·closeonexec(SB),NOSPLIT,$0
MOVW fd+0(FP), R4 // arg 1 - fd