原文链接
#include <stdio.h>#include <string.h>#include <sys/socket.h>#include <linux/netlink.h>#define MAX_RECV_SIZE1024static int Init_USB_Monitor( void ){// 本函数返回值int iResult = 0;// 接收内核发来的消息缓冲区大小const unsigned int uiRecvBuffSize = MAX_RECV_SIZE;// 套接字地址struct sockaddr_nl snl;// 套接字文件描述符int sfd = -1;// 1.添写套接字地址snl.nl_family = AF_NETLINK;snl.nl_pad = 0;// 如果希望内核处理消息或多播消息,就把该字段设置为 0,// 否则设置为处理消息的进程ID。snl.nl_pid = getpid();snl.nl_groups = 1;// 2.创建套接字// NETLINK_KOBJECT_UEVENT - 内核消息到用户空间,出现在 Linux 2.6.10sfd = socket( PF_NETLINK, // 使用 netlinkSOCK_DGRAM, // 使用不连续不可信赖的数据包连接NETLINK_KOBJECT_UEVENT );// 如果 创建套接字失败 的话,则if ( -1 == sfd ){return -1;}// 3.设置套接字接收缓冲区大小setsockopt( sfd,SOL_SOCKET, // 存取 socket 层SO_RCVBUF, // 设置接收缓冲区大小&uiRecvBuffSize,sizeof( uiRecvBuffSize ) );// 4.将套接字加入指定的多播组iResult = bind( sfd,(struct sockaddr*)&snl,sizeof( snl ) );// 如果 将套接字加入指定的多播组失败 的话,则if ( -1 == iResult ){return -2;}return sfd;}int USB_Monitoring(int fd){// 接收内核发来的消息字符串char caKernelMsgBuff[MAX_RECV_SIZE];if(fd <= 0){return -1;}// 接收内核消息recv(fd, &caKernelMsgBuff, sizeof( caKernelMsgBuff ), 0);printf( "Kernel Message:\n%s\n", caKernelMsgBuff );#if 0// USB 设备的插入时,会出现以 add@/devices/ 开头,含 usb 的字符串if( 0 == memcmp( caKernelMsgBuff,"add@",4 )&&NULL != strstr( caKernelMsgBuff,"usb" ) ){printf( "Add USB Device\n" );//break;}// USB 设备的拔除时,会出现以 remove@/devices/ 开头,含 usb 的字符串if( 0 == memcmp( caKernelMsgBuff,"remove@",7 )&&NULL != strstr( caKernelMsgBuff,"usb" ) ){printf( "Remove USB Device\n" );//break;}#endifreturn 0;}int main(int argc, char* argv[]){int fd = Init_USB_Monitor();while(1){USB_Monitoring(fd);}if (fd > 0){close(fd);fd = -1;}return 0;}