From 5d0ec8c62bfe0f4a6649b98ee3602266c1e878fc Mon Sep 17 00:00:00 2001 From: Song Gao Date: Sun, 6 Jan 2019 20:50:07 +0000 Subject: [PATCH] use syscall.Open with O_NONBLOCK flag and os.NewFile after ioctls so that the file is pollable. --- ipv4_test.go | 2 +- syscalls_linux.go | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/ipv4_test.go b/ipv4_test.go index 52dbe3a..8b3886c 100644 --- a/ipv4_test.go +++ b/ipv4_test.go @@ -88,7 +88,7 @@ func TestCloseUnblockPendingRead(t *testing.T) { close(c) }() - // make sure ifce.Close() happens after ifce.Read() + // make sure ifce.Close() happens after ifce.Read() blocks time.Sleep(1 * time.Second) ifce.Close() diff --git a/syscalls_linux.go b/syscalls_linux.go index 56c062b..e7106c6 100644 --- a/syscalls_linux.go +++ b/syscalls_linux.go @@ -31,50 +31,52 @@ func ioctl(fd uintptr, request uintptr, argp uintptr) error { } func newTAP(config Config) (ifce *Interface, err error) { - file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0) + fdInt, err := syscall.Open("/dev/net/tun", os.O_RDWR|syscall.O_NONBLOCK, 0) if err != nil { return nil, err } + fd := uintptr(fdInt) var flags uint16 flags = cIFFTAP | cIFFNOPI if config.PlatformSpecificParams.MultiQueue { flags |= cIFFMULTIQUEUE } - name, err := createInterface(file.Fd(), config.Name, flags) + name, err := createInterface(fd, config.Name, flags) if err != nil { return nil, err } - if err = setDeviceOptions(file.Fd(), config); err != nil { + if err = setDeviceOptions(fd, config); err != nil { return nil, err } - ifce = &Interface{isTAP: true, ReadWriteCloser: file, name: name} + ifce = &Interface{isTAP: true, ReadWriteCloser: os.NewFile(fd, "tun"), name: name} return } func newTUN(config Config) (ifce *Interface, err error) { - file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0) + fdInt, err := syscall.Open("/dev/net/tun", os.O_RDWR|syscall.O_NONBLOCK, 0) if err != nil { return nil, err } + fd := uintptr(fdInt) var flags uint16 flags = cIFFTUN | cIFFNOPI if config.PlatformSpecificParams.MultiQueue { flags |= cIFFMULTIQUEUE } - name, err := createInterface(file.Fd(), config.Name, flags) + name, err := createInterface(fd, config.Name, flags) if err != nil { return nil, err } - if err = setDeviceOptions(file.Fd(), config); err != nil { + if err = setDeviceOptions(fd, config); err != nil { return nil, err } - ifce = &Interface{isTAP: false, ReadWriteCloser: file, name: name} + ifce = &Interface{isTAP: false, ReadWriteCloser: os.NewFile(fd, "tun"), name: name} return }