1
0
mirror of https://github.com/golang/go synced 2024-11-26 04:58:00 -07:00

internal/poll, internal/syscall/unix, net: move and export fcntl syscall wrapper

This will allow to use the fcntl syscall in packages other than
internal/poll.

For #60181

Change-Id: I76703766a655f2343c61dad95faf81aad58e007f
Reviewed-on: https://go-review.googlesource.com/c/go/+/494916
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Tobias Klauser 2023-05-17 09:57:34 +02:00 committed by Gopher Robot
parent 6ed8474317
commit 27906bb74a
14 changed files with 52 additions and 142 deletions

View File

@ -1,14 +0,0 @@
// 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 poll
import _ "unsafe" // for go:linkname
// Implemented in the syscall package.
//
//go:linkname fcntl syscall.fcntl
func fcntl(fd int, cmd int, arg int) (int, error)

View File

@ -1,20 +0,0 @@
// 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 poll
import (
"internal/syscall/unix"
"syscall"
)
func fcntl(fd int, cmd int, arg int) (int, error) {
r, _, e := syscall.Syscall(unix.FcntlSyscall, uintptr(fd), uintptr(cmd), uintptr(arg))
if e != 0 {
return int(r), syscall.Errno(e)
}
return int(r), nil
}

View File

@ -1,14 +0,0 @@
// 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 (js && wasm) || wasip1
package poll
import "syscall"
// fcntl not supported on js/wasm or wasip1/wasm.
func fcntl(fd int, cmd int, arg int) (int, error) {
return 0, syscall.ENOSYS
}

View File

@ -4,7 +4,10 @@
package poll package poll
import "syscall" import (
"internal/syscall/unix"
"syscall"
)
// Fsync invokes SYS_FCNTL with SYS_FULLFSYNC because // Fsync invokes SYS_FCNTL with SYS_FULLFSYNC because
// on OS X, SYS_FSYNC doesn't fully flush contents to disk. // on OS X, SYS_FSYNC doesn't fully flush contents to disk.
@ -15,7 +18,7 @@ func (fd *FD) Fsync() error {
} }
defer fd.decref() defer fd.decref()
return ignoringEINTR(func() error { return ignoringEINTR(func() error {
_, err := fcntl(fd.Sysfd, syscall.F_FULLFSYNC, 0) _, err := unix.Fcntl(fd.Sysfd, syscall.F_FULLFSYNC, 0)
return err return err
}) })
} }

View File

@ -653,18 +653,18 @@ var dupCloexecUnsupported atomic.Bool
// DupCloseOnExec dups fd and marks it close-on-exec. // DupCloseOnExec dups fd and marks it close-on-exec.
func DupCloseOnExec(fd int) (int, string, error) { func DupCloseOnExec(fd int) (int, string, error) {
if syscall.F_DUPFD_CLOEXEC != 0 && !dupCloexecUnsupported.Load() { if syscall.F_DUPFD_CLOEXEC != 0 && !dupCloexecUnsupported.Load() {
r0, e1 := fcntl(fd, syscall.F_DUPFD_CLOEXEC, 0) r0, err := unix.Fcntl(fd, syscall.F_DUPFD_CLOEXEC, 0)
if e1 == nil { if err == nil {
return r0, "", nil return r0, "", nil
} }
switch e1.(syscall.Errno) { switch err {
case syscall.EINVAL, syscall.ENOSYS: case syscall.EINVAL, syscall.ENOSYS:
// Old kernel, or js/wasm (which returns // Old kernel, or js/wasm (which returns
// ENOSYS). Fall back to the portable way from // ENOSYS). Fall back to the portable way from
// now on. // now on.
dupCloexecUnsupported.Store(true) dupCloexecUnsupported.Store(true)
default: default:
return -1, "fcntl", e1 return -1, "fcntl", err
} }
} }
return dupCloseOnExecOld(fd) return dupCloseOnExecOld(fd)

View File

@ -5,6 +5,7 @@
package poll package poll
import ( import (
"internal/syscall/unix"
"runtime" "runtime"
"sync" "sync"
"syscall" "syscall"
@ -220,7 +221,7 @@ func newPipe() *splicePipe {
// Set the pipe buffer size to maxSpliceSize to optimize that. // Set the pipe buffer size to maxSpliceSize to optimize that.
// Ignore errors here, as a smaller buffer size will work, // Ignore errors here, as a smaller buffer size will work,
// although it will require more system calls. // although it will require more system calls.
fcntl(fds[0], syscall.F_SETPIPE_SZ, maxSpliceSize) unix.Fcntl(fds[0], syscall.F_SETPIPE_SZ, maxSpliceSize)
return &splicePipe{splicePipeFields: splicePipeFields{rfd: fds[0], wfd: fds[1]}} return &splicePipe{splicePipeFields: splicePipeFields{rfd: fds[0], wfd: fds[1]}}
} }

View File

@ -1,16 +0,0 @@
// 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.
// On 32-bit Linux systems, use SYS_FCNTL64.
// If you change the build tags here, see syscall/flock_linux_32bit.go.
//go:build (linux && 386) || (linux && arm) || (linux && mips) || (linux && mipsle)
package unix
import "syscall"
func init() {
FcntlSyscall = syscall.SYS_FCNTL64
}

View File

@ -0,0 +1,25 @@
// Copyright 2023 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 unix
package unix
import (
"syscall"
_ "unsafe" // for go:linkname
)
// Implemented in the runtime package.
//
//go:linkname fcntl runtime.fcntl
func fcntl(fd int32, cmd int32, arg int32) int32
func Fcntl(fd int, cmd int, arg int) (int, error) {
val := fcntl(int32(fd), int32(cmd), int32(arg))
if val < 0 {
return 0, syscall.Errno(-val)
}
return int(val), nil
}

View File

@ -0,0 +1,11 @@
// Copyright 2023 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 unix
import "syscall"
func Fcntl(fd int, cmd int, arg int) (int, error) {
return 0, syscall.ENOSYS
}

View File

@ -1,25 +0,0 @@
// Copyright 2018 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 unix
import "syscall"
// FcntlSyscall is the number for the fcntl system call. This is
// usually SYS_FCNTL, but can be overridden to SYS_FCNTL64.
var FcntlSyscall uintptr = syscall.SYS_FCNTL
func IsNonblock(fd int) (nonblocking bool, err error) {
flag, _, e1 := syscall.Syscall(FcntlSyscall, uintptr(fd), uintptr(syscall.F_GETFL), 0)
if e1 != 0 {
return false, e1
}
return flag&syscall.O_NONBLOCK != 0, nil
}
func HasNonblockFlag(flag int) bool {
return flag&syscall.O_NONBLOCK != 0
}

View File

@ -2,17 +2,14 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build aix || darwin || (openbsd && !mips64) || solaris //go:build unix
package unix package unix
import ( import "syscall"
"syscall"
_ "unsafe" // for go:linkname
)
func IsNonblock(fd int) (nonblocking bool, err error) { func IsNonblock(fd int) (nonblocking bool, err error) {
flag, e1 := fcntl(fd, syscall.F_GETFL, 0) flag, e1 := Fcntl(fd, syscall.F_GETFL, 0)
if e1 != nil { if e1 != nil {
return false, e1 return false, e1
} }
@ -22,8 +19,3 @@ func IsNonblock(fd int) (nonblocking bool, err error) {
func HasNonblockFlag(flag int) bool { func HasNonblockFlag(flag int) bool {
return flag&syscall.O_NONBLOCK != 0 return flag&syscall.O_NONBLOCK != 0
} }
// Implemented in the syscall package.
//
//go:linkname fcntl syscall.fcntl
func fcntl(fd int, cmd int, arg int) (int, error)

View File

@ -1,14 +0,0 @@
// Copyright 2021 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 net
import _ "unsafe" // for go:linkname
// Implemented in the syscall package.
//
//go:linkname fcntl syscall.fcntl
func fcntl(fd int, cmd int, arg int) (int, error)

View File

@ -1,20 +0,0 @@
// Copyright 2021 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 net
import (
"internal/syscall/unix"
"syscall"
)
func fcntl(fd int, cmd int, arg int) (int, error) {
r, _, e := syscall.Syscall(unix.FcntlSyscall, uintptr(fd), uintptr(cmd), uintptr(arg))
if e != 0 {
return int(r), syscall.Errno(e)
}
return int(r), nil
}

View File

@ -7,6 +7,7 @@
package net package net
import ( import (
"internal/syscall/unix"
"os" "os"
"syscall" "syscall"
"testing" "testing"
@ -94,7 +95,7 @@ func TestUnixConnReadMsgUnixSCMRightsCloseOnExec(t *testing.T) {
} }
}() }()
flags, err := fcntl(gotFDs[0], syscall.F_GETFD, 0) flags, err := unix.Fcntl(gotFDs[0], syscall.F_GETFD, 0)
if err != nil { if err != nil {
t.Fatalf("Can't get flags of fd:%#v, with err:%v", gotFDs[0], err) t.Fatalf("Can't get flags of fd:%#v, with err:%v", gotFDs[0], err)
} }