-
Notifications
You must be signed in to change notification settings - Fork 18.9k
os: add a function to construct *File with non-blocking file descriptor #22939
Copy link
Copy link
Closed
Labels
FrozenDueToAgeNeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.Feedback is required from experts, contributors, and/or the community before a change can be made.ProposalProposal-Accepted
Milestone
Description
Change
Add a new function to construct a *File with a file descriptor, set non blocking and put it into runtime poller. A naive but working diff:
--- a/src/os/file_unix.go
+++ b/src/os/file_unix.go
@@ -74,14 +74,17 @@ func (f *File) Fd() uintptr {
// NewFile returns a new File with the given file descriptor and
// name. The returned value will be nil if fd is not a valid file
// descriptor.
func NewFile(fd uintptr, name string) *File {
return newFile(fd, name, kindNewFile)
}
+func NewFileNonBlocking(fd uintptr, name string) *File {
+ return newFile(fd, name, kindOpenFile)
+}Benefit
With this, I can make use of the runtime poller and have SetDeadline method on custom network interfaces.
An example (on Linux):
package main
import (
"os"
"syscall"
"time"
"unsafe"
)
const IFF_TUN = 0x0001
func main() {
f, err := syscall.Open("/dev/net/tun", os.O_RDWR, 0)
if err != nil { panic(err) }
fd := uintptr(f)
var req ifreq
req.flags = IFF_TUN
copy(req.name[:], "tun0")
ioctl(fd, syscall.TUNSETIFF, uintptr(unsafe.Pointer(&req)))
conn := os.NewFileNonBlocking(fd, "tun0")
packet := make([]byte, 2000)
for {
err := conn.SetDeadline(time.Now().Add(time.Second * 2))
if err != nil { panic(err) }
n, err := conn.Read(packet)
if err != nil {
println(err.Error())
} else {
println("read a packet with length", n)
}
}
}
func ioctl(fd uintptr, request uintptr, ifreq uintptr) {
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, request, ifreq)
if errno != 0 { panic(errno) }
}
type ifreq struct {
name [16]byte
flags uint16
}Related issue
#15021
It looks like the main motivations of #15021 are runtime poller and SetDeadline.
Both of them can be solved by this very simple function.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeNeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.Feedback is required from experts, contributors, and/or the community before a change can be made.ProposalProposal-Accepted