Go语言学习日记【十六】go语言实现通过netlink监控usb热插拔

package main
 
 
import (
        "fmt"
        "syscall"
        "strings"
        "github.com/kr/pretty"
)
 
 
func main() {
        l, _ := ListenNetlink()
        for {
                _, err := l.ReadMsgs()
                if err != nil {
                        fmt.Println("=========   ",err)
                }
        }
}
 
type NetlinkListener struct {
        fd int
        sa *syscall.SockaddrNetlink
}
func ListenNetlink() (*NetlinkListener, error) {
        groups := syscall.RTNLGRP_LINK |
                syscall.RTNLGRP_IPV4_IFADDR |
                syscall.RTNLGRP_IPV6_IFADDR
 
        s, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_DGRAM,
                syscall.NETLINK_KOBJECT_UEVENT)
        if err != nil {
                return nil, fmt.Errorf("socket: %s", err)
        }
 
        saddr := &syscall.SockaddrNetlink{
                Family: syscall.AF_NETLINK,
                Pid:    uint32(0),
                Groups: uint32(groups),
        }
        err = syscall.Bind(s, saddr)
        if err != nil {
                return nil, fmt.Errorf("bind: %s", err)
        }
        return &NetlinkListener{fd: s, sa: saddr}, nil
}
func (l *NetlinkListener) ReadMsgs() (string, error) {
        defer func() {
                recover()
        }()
        pkt := make([]byte, 2048)
                _, err := syscall.Read(l.fd, pkt)
        if err != nil {
                return "null", fmt.Errorf("read: %s", err)
        }
        fmt.Println(pretty.Sprint(string(pkt)))
        outMsg := string(pkt)
        if find := strings.Contains(outMsg,"DEVTYPE=partition") && strings.Contains(outMsg,"SUBSYSTEM=block") ;find {
            action := strings.Split(outMsg,"@")[0]
            tmp := strings.Split(outMsg,"ACTION")[0]
            name := strings.Split(tmp,"/")[len(strings.Split(tmp,"/"))-1]
            fmt.Println("ACTION:",action,";","DEVICE:",name)
        }
        return string(pkt), nil
}
 
 
// github相关项目链接:https://github.com/pilebones/go-udev