Linux通过libudev获取挂载路径、监控U盘热拔插事件、U盘文件系统类型

news2025/4/8 19:18:21

文章目录

  • 获取挂载路径
  • 监控U盘热拔插事件
    • libusb
  • 文件系统类型
  • 通过挂载点获取挂载路径
  • 添libudev加库

获取挂载路径

#include <stdio.h>
#include <libudev.h>
#include <string.h>

int main() {
    struct udev *udev;
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices, *entry;

    // 创建udev上下文和设备枚举器
    udev = udev_new();
    if (!udev) {
        printf("Failed to create udev context\n");
        return 1;
    }

    enumerate = udev_enumerate_new(udev);
    if (!enumerate) {
        printf("Failed to create udev enumerate\n");
        udev_unref(udev);
        return 1;
    }

    // 添加匹配过滤器以选择块设备(U盘)
    udev_enumerate_add_match_subsystem(enumerate, "block");
    udev_enumerate_scan_devices(enumerate);
    devices = udev_enumerate_get_list_entry(enumerate);

    // 遍历设备列表并获取设备信息
    udev_list_entry_foreach(entry, devices) {
        const char *sys_path = udev_list_entry_get_name(entry);
        struct udev_device *dev = udev_device_new_from_syspath(udev, sys_path);
        const char *devnode = udev_device_get_devnode(dev);

        printf("Device node path: %s\n", udev_device_get_devnode(dev));
#if 0
        // 检查设备是否是U盘,可以根据需求添加其他判断条件
        if (udev_device_get_devtype(dev) && strcmp(udev_device_get_devtype(dev), "disk") == 0) {
            printf("U盘挂载路径:%s\n", devnode);
        }
#endif
        udev_device_unref(dev);
    }
    
  

    // 清理资源
    udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return 0;
}

编译指令

gcc your_code.c -o your_executable -ludev

在这里插入图片描述
在这里插入图片描述

监控U盘热拔插事件

#include <stdio.h>
#include <libudev.h>
#include <string.h>

int main() {
    struct udev *udev;
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices, *entry;

    // 创建udev上下文和设备枚举器
    udev = udev_new();
    if (!udev) {
        printf("Failed to create udev context\n");
        return 1;
    }

struct udev_monitor *mon = udev_monitor_new_from_netlink(udev, "udev");
int fd = udev_monitor_get_fd(mon);

udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL);
udev_monitor_enable_receiving(mon);

while (1) {
    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(fd, &fds);

    // 使用select函数等待设备事件
    if (select(fd+1, &fds, NULL, NULL, NULL) > 0) {
        if (FD_ISSET(fd, &fds)) {
            struct udev_device *dev = udev_monitor_receive_device(mon);
            if (dev) {
                const char *action = udev_device_get_action(dev);

                // 判断事件类型,处理U盘插入和移除事件
                if (strcmp(action, "add") == 0) {
                    printf("U盘插入\n");
                } else if (strcmp(action, "remove") == 0) {
                    printf("U盘移除\n");
                }

                udev_device_unref(dev);
            }
        }
    }
}

    // 清理资源
    udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return 0;
}

在这里插入图片描述

libusb

#include <stdio.h>
#include "/home/hty/Project/oneway_qt5/ui/oneway/onewaysendui_socket.new/libusb.h"
#include <assert.h>

#define VENDOR_ID        LIBUSB_HOTPLUG_MATCH_ANY  // U盘的厂商ID
#define PRODUCT_ID       LIBUSB_HOTPLUG_MATCH_ANY  // U盘的产品ID

#if 1
static int LIBUSB_CALL  usb_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data) 
{
   printf("\n\n12345235235\n\n");
   if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {
            printf("U盘已插入\n");
            // 在这里执行U盘插入时的操作
        } else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) {
            printf("U盘已拔出\n");
            // 在这里执行U盘拔出时的操作
        }
}


static int LIBUSB_CALL  usb_callback_in(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
   printf("\n\n12___________\n\n");

            printf("U盘已插入\n");
            // 在这里执行U盘插入时的操作
	fflush(stdout);
}

static int LIBUSB_CALL  usb_callback_out(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
   printf("\n\n12----------\n\n");

            printf("U盘已拔出\n");
            // 在这里执行U盘拔出
	fflush(stdout);
}

libusb_hotplug_callback_fn fn = usb_callback;
int main(void) 
{
    libusb_context *ctx = NULL;
    libusb_context *context = NULL;
    int rc = 0;

    rc = libusb_init(&ctx);

    assert(rc == 0);

    rc = libusb_has_capability( LIBUSB_CAP_HAS_HOTPLUG);

    if(rc!=0)
    {
     printf("capability\n");
    }
    //libusb_hotplug_callback_handle handle;
    //rc=libusb_hotplug_register_callback(ctx,  LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE,VENDOR_ID, PRODUCT_ID, LIBUSB_HOTPLUG_MATCH_ANY, (libusb_hotplug_callback_fn)usb_callback, NULL, &handle);
    //rc=libusb_hotplug_register_callback(ctx,  LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE,VENDOR_ID, PRODUCT_ID, 0, (libusb_hotplug_callback_fn)usb_callback, NULL, &handle);
      
      libusb_hotplug_callback_handle handle_in;
      libusb_hotplug_callback_handle handle_out;
      rc=libusb_hotplug_register_callback(ctx,  LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_NO_FLAGS,LIBUSB_HOTPLUG_MATCH_ANY,LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, (libusb_hotplug_callback_fn)usb_callback_in, NULL, &handle_in);
      rc=libusb_hotplug_register_callback(ctx,  LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_NO_FLAGS, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, (libusb_hotplug_callback_fn)usb_callback_out, NULL, &handle_out);
//    libusb_exit(context);
    //    rc = libusb_hotplug_register_callback(handle);
    if (rc != 0) {
        fprintf(stderr, "Failed to register hotplug callback\n");
        libusb_exit(ctx);
        return rc;
    }
    printf("正在监听 U盘插拔事件...\n");

    while (1) 
    {
	rc =  libusb_handle_events(ctx);
	if (rc != LIBUSB_SUCCESS) 
	{
            fprintf(stderr, "libusb_handle_events() 出错:%s\n", libusb_strerror(rc));
            break;
        }
	printf("新事件产生了...\n");
     }
     //libusb_hotplug_deregister_callback(NULL,handle);
     libusb_hotplug_deregister_callback(NULL,handle_in);
     libusb_hotplug_deregister_callback(NULL,handle_out);
    return 0;
}

#else

static int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{
        printf("device insert  \n");
}
int main(int argc, char **argv)
{
        libusb_hotplug_callback_handle hp;
        libusb_init (NULL);
        libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY,
                LIBUSB_HOTPLUG_MATCH_ANY, 0, hotplug_callback, NULL, &hp);
        while(1)
        {
                libusb_handle_events(NULL);
        }
        libusb_hotplug_deregister_callback(NULL,hp);
}

#endif

文件系统类型

#include <stdio.h>
#include <libudev.h>
#include <stdlib.h>
#include <string.h>

int main() {
    struct udev *udev = udev_new();
    if (!udev) {
        printf("Failed to initialize udev\n");
        return 1;
    }

    struct udev_enumerate *enumerate = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(enumerate, "block");
    udev_enumerate_scan_devices(enumerate);

    struct udev_list_entry *devices = udev_enumerate_get_list_entry(enumerate);
    struct udev_list_entry *entry;
    udev_list_entry_foreach(entry, devices) {
        const char *path = udev_list_entry_get_name(entry);
        struct udev_device *dev = udev_device_new_from_syspath(udev, path);
        const char *devnode = udev_device_get_devnode(dev);
/*********************************************************************************/
        const char *fs_type = udev_device_get_property_value(dev, "ID_FS_TYPE");

        // Output the device node and file system type
        if (devnode && fs_type) {
            printf("Device: %s\n", devnode);
            printf("File System Type: %s\n", fs_type);
        }
/**********************************************************************************/
        udev_device_unref(dev);
    }

    udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return 0;
}

在这里插入图片描述
这段代码使用 libudev 库,通过遍历 U 盘设备列表获取设备节点和文件系统类型。首先,使用 udev_new()函数初始化 udev 上下文,然后创建一个 udev_enumerate 对象,并设置匹配子系统为 “block”。接下来,使用 udev_enumerate_scan_devices() 函数扫描设备。然后,获取设备列表,并使用 udev_list_entry_foreach() 函数遍历列表。在遍历过程中,通过调用 udev_device_new_from_syspath() 函数根据设备的 syspath 创建一个 udev_device 对象。然后,使用 udev_device_get_devnode() 函数获取设备节点和 udev_device_get_property_value() 函数获取文件系统类型。最后,输出设备节点和文件系统类型。

通过挂载点获取挂载路径

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_PATH 256

char* get_usb_device_path(const char* mount_point) {
    FILE* fp;
    char* line = NULL;
    size_t len = 0;
    ssize_t read;
    char* device_path = NULL;

    // 打开 /proc/mounts 文件
    fp = fopen("/proc/mounts", "r");
    if (fp == NULL) {
        printf("Failed to open /proc/mounts\n");
        return NULL;
    }

    // 逐行读取 /proc/mounts 文件
    while ((read = getline(&line, &len, fp)) != -1) {
        char* token;
        char* saveptr = NULL;
        char* mount;
        char* device;

        // 解析挂载点和设备路径
        token = strtok_r(line, " ", &saveptr);
        mount = token;
        
        token = strtok_r(NULL, " ", &saveptr);
        device = token;

        // 如果挂载点匹配,保存设备路径
        if (strcmp(mount, mount_point) == 0) {
            device_path = strdup(device); // 保存设备路径的副本
            break;
        }
    }

    // 关闭文件和释放资源
    fclose(fp);
    if (line) {
        free(line);
    }

    return device_path;
}

int main() {
    const char* mount_point = "/dev/sdb1"; // 替换为你的挂载点

    char* device_path = get_usb_device_path(mount_point);

    if (device_path) {
        printf("USB Device Path: %s\n", device_path);
        free(device_path);
    } else {
        printf("USB device not found\n");
    }

    return 0;
}

在这里插入图片描述

添libudev加库

sudo apt-get install libudev-dev

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/945206.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++--动态规划背包问题(1)

1. 【模板】01背包_牛客题霸_牛客网 你有一个背包&#xff0c;最多能容纳的体积是V。 现在有n个物品&#xff0c;第i个物品的体积为vivi​ ,价值为wiwi​。 &#xff08;1&#xff09;求这个背包至多能装多大价值的物品&#xff1f; &#xff08;2&#xff09;若背包恰好装满&a…

AMD即将上市大量中端显卡,为新显卡支付过高价格的日子可能结束

​AMD在本周末&#xff08;8月25日&#xff09;的德国Gamescom活动中展示了两款新显卡和一些新的升级技术&#xff0c;这些新GPU的定价将与英伟达的GeForce RTX 4000卡竞争。 这是一件大事&#xff0c;因为新的Radeon RX 7700 XT和7800 XT卡占据了AMD Radeon RX 7000系列产品线…

nlp系列(7)三元组识别(Bert+CRF)pytorch

模型介绍 在实体识别中&#xff1a;使用了Bert模型&#xff0c;CRF模型 在关系识别中&#xff1a;使用了Bert模型的输出与实体掩码&#xff0c;进行一系列变化&#xff0c;得到关系 Bert模型介绍可以查看这篇文章&#xff1a;nlp系列&#xff08;2&#xff09;文本分类&…

springboot实现 伪微信登录

众所周知&#xff0c;微信扫码登陆的功能&#xff0c;个人网站是无法申请的&#xff0c;我们想在本地想测一下微信登录也是无法实现。 要实现微信登录&#xff0c;首先你得是一个企业单位&#xff0c;有公章才能申请&#xff0c;申请还要花费300块大洋。 如果我们只是想学习和…

司徒理财:8.29黄金高空思路不变已盈利

黄金周五在鲍威尔的讲话中上蹿下跳&#xff0c;上探1922压制下跌&#xff0c;在1903一线探底回升&#xff0c;日线双十字K。昨日周一震荡上行&#xff0c;美盘还是冲高回落&#xff0c;日线小阳。 当前黄金走势趋于震荡&#xff0c;单从技术面来讲还是偏多&#xff0c;但是鲍威…

小白必看:期权行权前必须了解的问题。

期权的本质是一个买权或是卖权&#xff0c;也就是说你是权利方的话&#xff0c;你拥有以约定价格向对手方买入&#xff08;买权&#xff09;或卖出&#xff08;卖权&#xff09;一定数量标的的权利。期权行权就是从对手方买入&#xff0c;或向其卖出标的&#xff01;下文介绍小…

【实训项目】“魔法”APP-模型爱好者线上线下交流平台

1.设计摘要 自从2018年万代把翻模厂商龙桃子&#xff0c;后国内的模型厂商就开始逐渐慢慢的从单纯的翻模转向做魔改合金模型&#xff0c;一是由于单纯的出翻模的利润太低&#xff0c;二是由于翻模被万代查水表的风险很大。于是&#xff0c;国内的一些厂商把眼光转向合金成品&a…

网卡抓不到带Tag的数据包

Tag抓取修改注册表 用于解决网卡抓不到带Tag的数据包 一、修改查看网卡信息 1、打开网络适配器选项&#xff0c;右键需要修改的网卡–属性 2、在配置–高级中&#xff0c;找到优先级和VLAN&#xff0c;选择优先级和VLAN关闭&#xff0c;确认。 3、确认网卡驱动关键字 网卡右…

vue2 组件库之vetur提示

当我们开发完自定义UI组件库后&#xff0c;在项目中使用时&#xff0c;想要达到以下提示效果&#xff0c;组件提示与属性提示&#xff0c;有什么解决方案呢&#xff1a; 事实上&#xff0c;这是vetur的功能&#xff0c;原文如下&#xff1a; Component Data | Vetur If a pac…

RT_Thread内核机制学习(六)信号量

要传输较大数据时&#xff0c;使用队列。 传输较小数值时&#xff0c;使用邮箱。 队列、邮箱用来传递数据。 如果只是用来传递资源的个数&#xff0c;可以使用信号量。 A车与B车只需要传递信号量&#xff08;代表资源&#xff09;。 信号量 获取信号量 如果value>0&…

PDF可以修改内容吗?有什么注意的事项?

PDF是一种跨平台的电子文档格式&#xff0c;可以在各种设备上轻松阅读和共享。许多人喜欢将文档转换为PDF格式以确保格式的一致性和易读性。但是&#xff0c;PDF文件一般被认为是“只读”文件&#xff0c;即无法编辑。那么&#xff0c;PDF文件是否可以修改呢&#xff1f; 答案是…

CCF HPC China2023|澎峰科技:使能先进计算,赋能行业应用

CCF HPC China2023圆满落幕&#xff01; 桂秋八月&#xff0c;为期三天的中国高性能计算领域最高规格盛会——2023CCF全球高性能计算学术年会&#xff08;HPC China&#xff09;在青岛红岛国际展览中心圆满落幕。行业超算大咖、顶级学界精英、先锋企业领袖参会者齐聚山东青岛&a…

photoshop2022安装教程

安装教程 点击set-up.exe 点击确认&#xff0c;开始安装&#xff0c;需要等待一段时间 出现这个表示安装成功&#xff0c;点击关闭即可 查看版本&#xff1a;打开菜单栏中的“帮助”选项&#xff0c;点击"系统信息" 成功演示 安装包下载 https://ziby0nwxdov.feishu.…

VMware vCenter Server 7.0.3 安装

VMware vCenter Server 7.0.3 安装 文章目录 VMware vCenter Server 7.0.3 安装1. 安装 vcenter1.1 第一阶段1.2 第二阶段 2. exsi 查看 vcenter3. 部署 DNS server3.1 安装 unbound3.2 配置 unbound3.3 vcenter 配置域名访问 1. 安装 vcenter 1.1 第一阶段 双击 192.168.2…

从零开始探索C语言(一)----C语言程序结构、基本语法与数据类型

文章目录 1. 程序结构1.1 Hello World示例1.2 编译并执行C程序 2. 基本语法2.1 C 标记2.2 分号2.3 注释2.4 标识符2.5 关键字2.6 C中的空格 3. 数据类型3.1 整数类型3.2 浮点类型3.3 void类型 从第一次学习C语言到现在已经时隔五年了&#xff0c;大部分知识都还给老师了&#x…

C++day7(封装一个学生的类,定义一个学生这样类的vector容器, 里面存放学生对象【保存+读取】、实现与list相关的函数 )

1.封装一个学生的类&#xff0c;定义一个学生这样类的vector容器, 里面存放学生对象 再把该容器中的对象&#xff0c;保存到文件中。&#xff08;至少3个&#xff09; 再把这些学生从文件中读取出来&#xff0c;放入另一个容器中并且遍历输出该容器里的学生。 #include <…

STM32f103入门(5)定时器中断

STM32 TIM&#xff08;定时器/计数器&#xff09;模块的中断流程如下&#xff1a; 配置TIM寄存器&#xff1a;首先&#xff0c;通过配置TIM相关的寄存器来设置计时器的基本参数&#xff0c;例如预分频系数、计数模式、计数器周期等。 使能TIM中断&#xff1a;使用TIM_ITConfig函…

时序预测 | MATLAB实现基于QPSO-BiLSTM、PSO-BiLSTM和BiLSTM时间序列预测

时序预测 | MATLAB实现基于QPSO-BiLSTM、PSO-BiLSTM和BiLSTM时间序列预测 目录 时序预测 | MATLAB实现基于QPSO-BiLSTM、PSO-BiLSTM和BiLSTM时间序列预测效果一览基本描述程序设计参考资料 效果一览 基本描述 1.Matlab实现QPSO-BiLSTM、PSO-BiLSTM和BiLSTM神经网络时间序列预测…

王老吉与加多宝共同的课题:受困于第二招牌

王老吉曾经凭借凉茶单品反超可口可乐&#xff0c;却在2015年后面临增速下滑、市场规模逐年缩小的增长困境。事实上&#xff0c;王老吉所在的凉茶市场现已成为存量市场&#xff0c;甚至在不断激化的竞争中逐年萎缩。为了打破原有业务的局限&#xff0c;王老吉曾推出过许多新品&a…

网站应用微信登录

准备工作 | 微信开放文档 <template><wxloginid"wxLoginForm"self_redirect"false":appid"appid":scope"scope":state"state":redirect_uri"redirect_uri"></wxlogin> </template><…