Linux系统下,怎样用C语言判断U盘插入和拔出,并获取U盘路径?

在 Linux 系统中,使用 C 语言判断 U 盘的插入和拔出事件并获取 U 盘路径涉及与系统的设备管理交互。以下是一个详细的指南,包括实现方法、示例代码和相关工具的使用。

1. 使用 udev

udev 是 Linux 系统下的设备管理器,它可以处理设备事件。你可以使用 libudev 库来检测 U 盘的插入和拔出事件,并获取 U 盘的路径。

1.1 安装 libudev

确保系统中安装了 libudev 库及其开发包:

bash
sudo apt-get install libudev-dev

1.2 编写 C 代码

以下是一个示例程序,演示如何使用 libudev 监听 U 盘的插入和拔出事件,并获取 U 盘路径。

c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <libudev.h> int main() { struct udev *udev; struct udev_monitor *mon; struct udev_device *dev; int fd; // 创建 udev 对象 udev = udev_new(); if (!udev) { fprintf(stderr, "Failed to create udev object\n"); return 1; } // 创建一个 udev 监视器,监听设备添加和移除事件 mon = udev_monitor_new_from_netlink(udev, "udev"); if (!mon) { fprintf(stderr, "Failed to create udev monitor\n"); udev_unref(udev); return 1; } // 监听 "add" 和 "remove" 事件 udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", NULL); udev_monitor_enable_receiving(mon); fd = udev_monitor_get_fd(mon); while (1) { // 等待事件 int ret = poll(&(struct pollfd){fd, POLLIN, 0}, 1, -1); if (ret > 0) { // 读取事件 dev = udev_monitor_receive_device(mon); if (dev) { const char *action = udev_device_get_action(dev); const char *path = udev_device_get_devnode(dev); if (action && path) { if (strcmp(action, "add") == 0) { printf("U盘插入: %s\n", path); } else if (strcmp(action, "remove") == 0) { printf("U盘拔出: %s\n", path); } } udev_device_unref(dev); } } } // 清理 udev_monitor_unref(mon); udev_unref(udev); return 0; }

解释

  • udev_new():创建 udev 对象。
  • udev_monitor_new_from_netlink(udev, "udev"):创建监视器对象。
  • udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", NULL):设置过滤器,监听 USB 设备。
  • udev_monitor_enable_receiving(mon):启用事件接收。
  • udev_monitor_receive_device(mon):接收设备事件。
  • udev_device_get_action(dev):获取设备动作(插入或拔出)。
  • udev_device_get_devnode(dev):获取设备路径。

2. 使用 inotify

inotify 是 Linux 内核的文件系统监视机制。虽然 inotify 更适合用于监视文件系统的变化(如文件或目录的创建、删除),也可以用于监视 /sys/dev 目录中的变化,以检测 U 盘的插入和拔出。

2.1 编写 C 代码

以下示例代码演示了如何使用 inotify 监视 /dev 目录来检测设备变化。

c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/inotify.h> #include <limits.h> int main() { int inotify_fd, wd; char buffer[BUF_LEN] __attribute__((aligned(8))); ssize_t len, i = 0; inotify_fd = inotify_init(); if (inotify_fd < 0) { perror("inotify_init"); exit(EXIT_FAILURE); } wd = inotify_add_watch(inotify_fd, "/dev", IN_CREATE | IN_DELETE); if (wd == -1) { perror("inotify_add_watch"); exit(EXIT_FAILURE); } while (1) { len = read(inotify_fd, buffer, sizeof(buffer)); if (len < 0) { perror("read"); exit(EXIT_FAILURE); } while (i < len) { struct inotify_event *event = (struct inotify_event *) &buffer[i]; if (event->len) { if (event->mask & IN_CREATE) { printf("创建: %s\n", event->name); } if (event->mask & IN_DELETE) { printf("删除: %s\n", event->name); } } i += sizeof(struct inotify_event) + event->len; } i = 0; } close(inotify_fd); return 0; }

解释

  • inotify_init():初始化 inotify
  • inotify_add_watch(inotify_fd, "/dev", IN_CREATE | IN_DELETE):监视 /dev 目录的创建和删除事件。
  • read(inotify_fd, buffer, sizeof(buffer)):读取事件。
  • event->mask & IN_CREATEevent->mask & IN_DELETE:检测设备的创建和删除。

3. 总结

在 Linux 系统中,可以通过 libudev 库来检测 U 盘的插入和拔出事件,获取 U 盘路径。另一种方法是使用 inotify 监视 /dev 目录中的变化。libudev 提供了更高层次的设备管理功能,而 inotify 更适合于监视文件系统变化。选择适合的工具取决于具体需求和系统配置。

关键字

Linux, C语言, U盘, libudev, 设备管理, udev, inotify, /dev 目录, 设备事件, 插入, 拔出, poll, inotify_init, inotify_add_watch, read