github.com/jshiv/can-go@v0.2.1-0.20210224011015-069e90e90bdf/pkg/socketcan/dialraw_linux.go (about)

     1  // +build linux
     2  // +build go1.12
     3  
     4  package socketcan
     5  
     6  import (
     7  	"fmt"
     8  	"net"
     9  	"os"
    10  
    11  	"golang.org/x/sys/unix"
    12  )
    13  
    14  func dialRaw(device string) (conn net.Conn, err error) {
    15  	defer func() {
    16  		if err != nil {
    17  			err = &net.OpError{Op: "dial", Net: canRawNetwork, Addr: &canRawAddr{device: device}, Err: err}
    18  		}
    19  	}()
    20  	ifi, err := net.InterfaceByName(device)
    21  	if err != nil {
    22  		return nil, fmt.Errorf("interface %s: %w", device, err)
    23  	}
    24  	fd, err := unix.Socket(unix.AF_CAN, unix.SOCK_RAW, unix.CAN_RAW)
    25  	if err != nil {
    26  		return nil, fmt.Errorf("socket: %w", err)
    27  	}
    28  	// put fd in non-blocking mode so the created file will be registered by the runtime poller (Go >= 1.12)
    29  	if err := unix.SetNonblock(fd, true); err != nil {
    30  		return nil, fmt.Errorf("set nonblock: %w", err)
    31  	}
    32  	if err := unix.Bind(fd, &unix.SockaddrCAN{Ifindex: ifi.Index}); err != nil {
    33  		return nil, fmt.Errorf("bind: %w", err)
    34  	}
    35  	return &fileConn{ra: &canRawAddr{device: device}, f: os.NewFile(uintptr(fd), "can")}, nil
    36  }