请使用netlink获取usb设备插拔事件,并提取出设备类型,名字,pid vid 文件路径等信息,使用inotify 监听,请用C语言写出程序
时间: 2024-02-27 15:53:44 浏览: 172
好的,我会尽力回答您的问题。首先,您需要了解一些基本概念和工具,例如Linux的netlink和inotify机制,以及C语言的基本语法。
Netlink是Linux内核中用于内核和用户空间进程之间通信的一种机制。可以使用Netlink来获取有关网络、路由、设备和进程等信息。通过Netlink,我们可以监听USB设备插拔事件并提取设备信息。
Inotify是Linux内核用于监视文件系统事件的一种机制。可以使用inotify API来监听文件系统中的特定文件或目录的事件。通过inotify,我们可以监听USB设备的挂载和卸载事件,并获取文件路径信息。
下面是一个简单的C语言程序,演示如何使用Netlink和inotify来获取USB设备插拔事件,并提取设备类型、名字、PID、VID和文件路径等信息。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <sys/inotify.h>
#define UEVENT_BUFFER_SIZE 2048
#define MAX_NAME_SIZE 256
int main(int argc, char* argv[]) {
int sockfd, inotify_fd, watch_fd;
char buf[UEVENT_BUFFER_SIZE];
char name[MAX_NAME_SIZE];
struct sockaddr_nl sa;
struct inotify_event event;
socklen_t len = sizeof(sa);
ssize_t n;
// create netlink socket
sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
if (sockfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;
sa.nl_groups = NETLINK_KOBJECT_UEVENT;
// bind netlink socket
if (bind(sockfd, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
perror("bind");
close(sockfd);
exit(EXIT_FAILURE);
}
// initialize inotify
inotify_fd = inotify_init();
if (inotify_fd == -1) {
perror("inotify_init");
close(sockfd);
exit(EXIT_FAILURE);
}
// add watch for mountpoint
watch_fd = inotify_add_watch(inotify_fd, "/dev", IN_CREATE | IN_DELETE);
if (watch_fd == -1) {
perror("inotify_add_watch");
close(inotify_fd);
close(sockfd);
exit(EXIT_FAILURE);
}
while (1) {
// receive netlink message
n = recv(sockfd, buf, sizeof(buf), 0);
if (n == -1) {
perror("recv");
continue;
}
// parse netlink message
for (char* ptr = buf; ptr < buf + n;) {
struct nlmsghdr* nh = (struct nlmsghdr*)ptr;
if (nh->nlmsg_type == NLMSG_DONE) {
break;
}
if (nh->nlmsg_type == NLMSG_ERROR) {
perror("netlink error");
break;
}
if (nh->nlmsg_type == UDEV_MONITOR_KERNEL) {
struct udev_device* dev = udev_device_new_from_syspath(udev, "/sys" + nlmsg_ptr(nh), "usb_device");
if (dev != NULL) {
const char* action = udev_device_get_action(dev);
if (strcmp(action, "add") == 0) {
const char* devpath = udev_device_get_devpath(dev);
const char* subsystem = udev_device_get_subsystem(dev);
const char* devtype = udev_device_get_devtype(dev);
const char* id_vendor = udev_device_get_sysattr_value(dev, "idVendor");
const char* id_product = udev_device_get_sysattr_value(dev, "idProduct");
const char* serial = udev_device_get_sysattr_value(dev, "serial");
const char* devname = udev_device_get_devnode(dev);
printf("USB device added:\n");
printf(" DevPath: %s\n", devpath);
printf(" Subsystem: %s\n", subsystem);
printf(" DevType: %s\n", devtype);
printf(" Vendor ID: %s\n", id_vendor);
printf(" Product ID: %s\n", id_product);
printf(" Serial: %s\n", serial);
printf(" Device Name: %s\n", devname);
}
udev_device_unref(dev);
}
}
ptr += NLMSG_ALIGN(nh->nlmsg_len);
}
// receive inotify event
n = read(inotify_fd, &event, sizeof(event));
if (n == -1) {
perror("read");
continue;
}
// check inotify event
if (event.mask & IN_CREATE) {
// device is mounted
snprintf(name, MAX_NAME_SIZE, "/dev/%s", event.name);
printf("USB device mounted: %s\n", name);
} else if (event.mask & IN_DELETE) {
// device is unmounted
snprintf(name, MAX_NAME_SIZE, "/dev/%s", event.name);
printf("USB device unmounted: %s\n", name);
}
}
// cleanup
inotify_rm_watch(inotify_fd, watch_fd);
close(inotify_fd);
close(sockfd);
return 0;
}
```
需要注意的是,这个程序只是一个简单的示例,可能需要根据实际情况进行修改和优化。例如,需要添加错误处理、异常情况处理等功能。
阅读全文