Skip to content

Commit 547aed1

Browse files
ianlancetaylorgopherbot
authored andcommitted
runtime: consistently define fcntl
Clean up and consolidate on a single consistent definition of fcntl, which takes three int32 arguments and returns either a positive result or a negative errno value. Change-Id: Id9505492712db4b0aab469c6bd15e4fce3c9ff6e Reviewed-on: https://go-review.googlesource.com/c/go/+/495075 Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Tobias Klauser <[email protected]> Reviewed-by: Michael Pratt <[email protected]>
1 parent 6d1c507 commit 547aed1

34 files changed

+209
-86
lines changed

src/runtime/export_aix_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@
44

55
package runtime
66

7-
var Fcntl = syscall_fcntl1
87
var SetNonblock = setNonblock

src/runtime/export_darwin_test.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,4 @@
44

55
package runtime
66

7-
func Fcntl(fd, cmd, arg uintptr) (uintptr, uintptr) {
8-
r := fcntl(int32(fd), int32(cmd), int32(arg))
9-
if r < 0 {
10-
return ^uintptr(0), uintptr(-r)
11-
}
12-
return uintptr(r), 0
13-
}
14-
157
var SetNonblock = setNonblock

src/runtime/export_openbsd_test.go

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/runtime/export_solaris_test.go

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/runtime/export_unix_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package runtime
99
import "unsafe"
1010

1111
var NonblockingPipe = nonblockingPipe
12+
var Fcntl = fcntl
1213

1314
func sigismember(mask *sigset, i int) bool {
1415
clear := *mask

src/runtime/nbpipe_fcntl_libc_test.go

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/runtime/nbpipe_fcntl_unix_test.go

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/runtime/nbpipe_test.go

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,29 @@ import (
1414
)
1515

1616
func TestNonblockingPipe(t *testing.T) {
17-
t.Parallel()
18-
1917
// NonblockingPipe is the test name for nonblockingPipe.
2018
r, w, errno := runtime.NonblockingPipe()
2119
if errno != 0 {
2220
t.Fatal(syscall.Errno(errno))
2321
}
24-
defer func() {
25-
runtime.Close(r)
26-
runtime.Close(w)
27-
}()
22+
defer runtime.Close(w)
2823

2924
checkIsPipe(t, r, w)
3025
checkNonblocking(t, r, "reader")
3126
checkCloseonexec(t, r, "reader")
3227
checkNonblocking(t, w, "writer")
3328
checkCloseonexec(t, w, "writer")
29+
30+
// Test that fcntl returns an error as expected.
31+
if runtime.Close(r) != 0 {
32+
t.Fatalf("Close(%d) failed", r)
33+
}
34+
val := runtime.Fcntl(r, syscall.F_GETFD, 0)
35+
if val >= 0 {
36+
t.Errorf("Fcntl succeeded unexpectedly")
37+
} else if syscall.Errno(-val) != syscall.EBADF {
38+
t.Errorf("Fcntl failed with error %v, expected %v", -val, syscall.EBADF)
39+
}
3440
}
3541

3642
func checkIsPipe(t *testing.T, r, w int32) {
@@ -49,19 +55,19 @@ func checkIsPipe(t *testing.T, r, w int32) {
4955

5056
func checkNonblocking(t *testing.T, fd int32, name string) {
5157
t.Helper()
52-
flags, errno := fcntl(uintptr(fd), syscall.F_GETFL, 0)
53-
if errno != 0 {
54-
t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(errno))
58+
flags := runtime.Fcntl(fd, syscall.F_GETFL, 0)
59+
if flags < 0 {
60+
t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(-flags))
5561
} else if flags&syscall.O_NONBLOCK == 0 {
5662
t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags)
5763
}
5864
}
5965

6066
func checkCloseonexec(t *testing.T, fd int32, name string) {
6167
t.Helper()
62-
flags, errno := fcntl(uintptr(fd), syscall.F_GETFD, 0)
63-
if errno != 0 {
64-
t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(errno))
68+
flags := runtime.Fcntl(fd, syscall.F_GETFD, 0)
69+
if flags < 0 {
70+
t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(flags))
6571
} else if flags&syscall.FD_CLOEXEC == 0 {
6672
t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags)
6773
}

src/runtime/netpoll_solaris.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@ func errno() int32 {
9696
return *getg().m.perrno
9797
}
9898

99-
func fcntl(fd, cmd, arg int32) int32 {
100-
return int32(sysvicall3(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg)))
101-
}
102-
10399
func port_create() int32 {
104100
return int32(sysvicall0(&libc_port_create))
105101
}

src/runtime/os3_solaris.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,15 @@ func pipe2(flags int32) (r, w int32, errno int32) {
569569
return p[0], p[1], int32(e)
570570
}
571571

572+
//go:nosplit
573+
func fcntl(fd, cmd, arg int32) int32 {
574+
r1, err := sysvicall3Err(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))
575+
if r := int32(r1); r >= 0 {
576+
return r
577+
}
578+
return -int32(err)
579+
}
580+
572581
//go:nosplit
573582
func closeonexec(fd int32) {
574583
fcntl(fd, _F_SETFD, _FD_CLOEXEC)

src/runtime/os_aix.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,10 @@ func walltime() (sec int64, nsec int32) {
353353

354354
//go:nosplit
355355
func fcntl(fd, cmd, arg int32) int32 {
356-
r, _ := syscall3(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))
356+
r, errno := syscall3(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))
357+
if int32(r) < 0 {
358+
return -int32(errno)
359+
}
357360
return int32(r)
358361
}
359362

src/runtime/os_dragonfly.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func kqueue() int32
6363
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
6464

6565
func pipe2(flags int32) (r, w int32, errno int32)
66+
func fcntl(fd, cmd, arg int32) int32
6667
func closeonexec(fd int32)
6768

6869
// From DragonFly's <sys/sysctl.h>

src/runtime/os_freebsd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func kqueue() int32
4848
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
4949

5050
func pipe2(flags int32) (r, w int32, errno int32)
51+
func fcntl(fd, cmd, arg int32) int32
5152
func closeonexec(fd int32)
5253

5354
// From FreeBSD's <sys/sysctl.h>

src/runtime/os_linux.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,16 @@ func osyield_no_g() {
466466

467467
func pipe2(flags int32) (r, w int32, errno int32)
468468

469+
//go:nosplit
470+
func fcntl(fd, cmd, arg int32) int32 {
471+
r, _, errno := syscall.Syscall6(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
472+
ri := int32(r)
473+
if ri < 0 {
474+
return -int32(errno)
475+
}
476+
return ri
477+
}
478+
469479
const (
470480
_si_max_size = 128
471481
_sigev_max_size = 64

src/runtime/os_netbsd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ func kqueue() int32
7979
func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
8080

8181
func pipe2(flags int32) (r, w int32, errno int32)
82+
func fcntl(fd, cmd, arg int32) int32
8283
func closeonexec(fd int32)
8384

8485
const (

src/runtime/os_openbsd_syscall2.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ func nanotime1() int64
9595
//go:noescape
9696
func sigaltstack(new, old *stackt)
9797

98+
func fcntl(fd, cmd, arg int32) int32
9899
func closeonexec(fd int32)
99100

100101
func walltime() (sec int64, nsec int32)

src/runtime/os_solaris.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr {
149149
//go:cgo_unsafe_args
150150

151151
// sysvicall3Err returns both the system call result and the errno value.
152-
// This is used by sysicall3 and write1.
152+
// This is used by sysvicall3 and write1.
153153
func sysvicall3Err(fn *libcFunc, a1, a2, a3 uintptr) (r1, err uintptr) {
154154
// Leave caller's PC/SP around for traceback.
155155
gp := getg()

src/runtime/sys_darwin_amd64.s

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,12 @@ TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
369369
MOVL 0(DI), DI // arg 1 fd
370370
XORL AX, AX // vararg: say "no float args"
371371
CALL libc_fcntl(SB)
372+
TESTL AX, AX
373+
JGT noerr
374+
CALL libc_error(SB)
375+
MOVL (AX), AX
376+
NEGL AX // caller expects negative errno value
377+
noerr:
372378
RET
373379

374380
// mstart_stub is the first function executed on a new thread started by pthread_create.

src/runtime/sys_darwin_arm64.s

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,13 @@ TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
314314
MOVW R2, (RSP) // arg 3 is variadic, pass on stack
315315
MOVW 0(R0), R0 // arg 1 fd
316316
BL libc_fcntl(SB)
317+
MOVD $-1, R1
318+
CMP R0, R1
319+
BNE noerr
320+
BL libc_error(SB)
321+
MOVW (R0), R0
322+
NEG R0, R0 // caller expects negative errno value
323+
noerr:
317324
ADD $16, RSP
318325
RET
319326

src/runtime/sys_dragonfly_amd64.s

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,18 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
385385
MOVL AX, ret+48(FP)
386386
RET
387387

388+
// func fcntl(fd, cmd, arg int32) int32
389+
TEXT runtime·fcntl(SB),NOSPLIT,$0
390+
MOVL fd+0(FP), DI // fd
391+
MOVL cmd+4(FP), SI // cmd
392+
MOVL arg+8(FP), DX // arg
393+
MOVL $92, AX // fcntl
394+
SYSCALL
395+
JCC 2(PC)
396+
NEGL AX // caller expects negative errno
397+
MOVL AX, ret+16(FP)
398+
RET
399+
388400
// void runtime·closeonexec(int32 fd);
389401
TEXT runtime·closeonexec(SB),NOSPLIT,$0
390402
MOVL fd+0(FP), DI // fd

src/runtime/sys_freebsd_386.s

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,15 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
451451
MOVL AX, ret+24(FP)
452452
RET
453453

454+
// func fcntl(fd, cmd, arg int32) int32
455+
TEXT runtime·fcntl(SB),NOSPLIT,$-4
456+
MOVL $SYS_fcntl, AX
457+
INT $0x80
458+
JAE 2(PC)
459+
NEGL AX // caller expects negative errno
460+
MOVL AX, ret+12(FP)
461+
RET
462+
454463
// int32 runtime·closeonexec(int32 fd);
455464
TEXT runtime·closeonexec(SB),NOSPLIT,$32
456465
MOVL $SYS_fcntl, AX

src/runtime/sys_freebsd_amd64.s

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,18 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
548548
MOVL AX, ret+48(FP)
549549
RET
550550

551+
// func fcntl(fd, cmd, arg int32) int32
552+
TEXT runtime·fcntl(SB),NOSPLIT,$0
553+
MOVL fd+0(FP), DI // fd
554+
MOVL cmd+4(FP), SI // cmd
555+
MOVL arg+8(FP), DX // arg
556+
MOVL $SYS_fcntl, AX
557+
SYSCALL
558+
JCC 2(PC)
559+
NEGQ AX // caller expects negative errno
560+
MOVL AX, ret+16(FP)
561+
RET
562+
551563
// void runtime·closeonexec(int32 fd);
552564
TEXT runtime·closeonexec(SB),NOSPLIT,$0
553565
MOVL fd+0(FP), DI // fd

src/runtime/sys_freebsd_arm.s

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,17 @@ TEXT runtime·kevent(SB),NOSPLIT,$0
387387
MOVW R0, ret+24(FP)
388388
RET
389389

390+
// func fcntl(fd, cmd, arg int32) int32
391+
TEXT runtime·fcntl(SB),NOSPLIT,$0
392+
MOVW fd+0(FP), R0 // fd
393+
MOVW cmd+4(FP), R1 // cmd
394+
MOVW arg+8(FP), R2 // arg
395+
MOVW $SYS_fcntl, R7
396+
SWI $0
397+
RSB.CS $0, R0 // caller expects negative errno
398+
MOVW R0, ret+12(FP)
399+
RET
400+
390401
// void runtime·closeonexec(int32 fd)
391402
TEXT runtime·closeonexec(SB),NOSPLIT,$0
392403
MOVW fd+0(FP), R0 // fd

src/runtime/sys_freebsd_arm64.s

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,19 @@ ok:
439439
MOVW R0, ret+48(FP)
440440
RET
441441

442+
// func fcntl(fd, cmd, arg int32) int32
443+
TEXT runtime·fcntl(SB),NOSPLIT,$0
444+
MOVW fd+0(FP), R0
445+
MOVW cmd+4(FP), R1
446+
MOVW arg+8(FP), R2
447+
MOVD $SYS_fcntl, R8
448+
SVC
449+
BCC ok
450+
NEG R0, R0 // caller expects negative errno
451+
ok:
452+
MOVW R0, ret+16(FP)
453+
RET
454+
442455
// func closeonexec(fd int32)
443456
TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
444457
MOVW fd+0(FP), R0

src/runtime/sys_freebsd_riscv64.s

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,19 @@ ok:
420420
MOVW A0, ret+48(FP)
421421
RET
422422

423+
// func fcntl(fd, cmd, arg int32) int32
424+
TEXT runtime·fcntl(SB),NOSPLIT,$0
425+
MOVW fd+0(FP), A0
426+
MOVW cmd+4(FP), A1
427+
MOVW arg+8(FP), A2
428+
MOV $SYS_fcntl, T0
429+
ECALL
430+
BEQ T0, ZERO, ok
431+
NEG A0, A0 // caller expects negative errno
432+
ok:
433+
MOVW A0, ret+16(FP)
434+
RET
435+
423436
// func closeonexec(fd int32)
424437
TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
425438
MOVW fd+0(FP), A0

0 commit comments

Comments
 (0)