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

文章目录

  • 获取挂载路径
  • 监控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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库备份和Shell基础测试及AWK(运维)

第一题&#xff1a;简述一下如何用mysql命令进行备份和恢复&#xff0c;请以test库为例&#xff0c;创建一个备份&#xff0c;并再用此备份恢复备份 备份步骤&#xff1a; 备份test库&#xff1a;使用mysqldump命令备份test库&#xff0c;并将备份写入一个.sql文件中。命令示例…

【第1章 数据结构概述】

目录 一. 基本概念 1. 数据、数据元素、数据对象 2. 数据结构 二. 数据结构的分类 1. 数据的逻辑结构可分为两大类&#xff1a;a. 线性结构&#xff1b;b. 非线性结构 2. 数据的存储结构取决于四种基本的存储方法&#xff1a;顺序存储、链接存储、索引存储、散列存储 3. …

【力扣每日一题】2023.8.24 统计参与通信的服务器

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目顾名思义&#xff0c;要我们统计参与通信的服务器&#xff0c;给我们一个二维矩阵&#xff0c;元素为1的位置则表示是一台服务器。 …

学习Linux基础知识与命令行操作

开始学习Linux系统前&#xff0c;首先要掌握计算机基础知识&#xff0c;了解硬件、操作系统、文件系统、网络和安全等概念。对这些基础知识的了解能够帮助理解Linux系统的概念和功能。 在Linux系统中&#xff0c;文件和目录是数据管理的基本单位。每个文件和目录都有一个称为&…

OAuth2.0 知识点梳理

文章目录 OAuth2.0 知识点梳理一、四种角色二、四种模式的概述三、四种模式的图解 OAuth2.0 知识点梳理 一、四种角色 为了能够更好的理解本文中后续的内容&#xff0c;这里我先说下&#xff0c;OAuth2.0 中相关的四种角色&#xff0c;如下&#xff1a; 资源拥有者资源服务客…

内网实战1

1、信息收集&#xff1a; 使用nmap做端口扫描&#xff1a; nmap -sV -Pn -T4 192.168.26.174重要端口&#xff1a;80、445、139、135、3306 目录扫描&#xff1a; 访问80端口&#xff1a;发现一个网站是phpstudy搭建的&#xff1b; 发现一个mysql数据库&#xff0c;那我们…

[QT]设置程序仅打开一个,再打开就唤醒已打开程序的窗口

需求&#xff1a;speedcrunch 这个软件是开源的计算器软件。配合launch类软件使用时&#xff0c;忘记关闭就经常很多窗口&#xff0c;强迫症&#xff0c;从网上搜索对版本进行了修改。 #include "gui/mainwindow.h"#include <QCoreApplication> #include <…

CocosCreator3.8研究笔记(一)windows环境安装配置

一、安装Cocos 编辑器 &#xff08;1&#xff09;、下载Cocos Dashboard安装文件 Cocos 官方网站Cocos Dashboard下载地址 &#xff1a; https://www.cocos.com/creator-download9下载完成后会得到CocosDashboard-v2.0.1-win-082215.exe 安装文件&#xff0c;双击安装即可。 …

智能工厂移动式作业轻薄加固三防平板数据采集终端

在这个高度自动化和数字化的环境中&#xff0c;数据采集变得尤为重要。为了满足这个需求&#xff0c;工业三防平板数据采集终端应运而生。工业三防平板数据采集终端采用了轻量级高强度镁合金材质&#xff0c;这使得它在保持轻薄的同时具有更强的坚固性。这种材质还具有耐磨防损…

机器学习笔记之核函数再回首:Nadarya-Watson核回归python手写示例

机器学习笔记之核函数再回首——Nadaraya-Watson核回归手写示例 引言回顾&#xff1a; Nadaraya-Watson \text{Nadaraya-Watson} Nadaraya-Watson核回归通过核函数描述样本之间的关联关系使用 Softmax \text{Softmax} Softmax函数对权重进行划分将权重与相应标签执行加权运算 N…

自动化测试(三):接口自动化pytest测试框架

文章目录 1. 接口自动化的实现2. 知识要点及实践2.1 requests.post传递的参数本质2.2 pytest单元测试框架2.2.1 pytest框架简介2.2.2 pytest装饰器2.2.3 断言、allure测试报告2.2.4 接口关联、封装改进YAML动态传参&#xff08;热加载&#xff09; 2.3 pytest接口封装&#xff…

Android 绘制之文字测量

drawText() 绘制文字 绘制进度条:paint.strokeCap Paint.CAP.RONUD 线条两边样式 设置文字字体:paint.typeFace Resources.Compat.getFont(context,font) 设置加粗 paint.isFakeBoldText 设置居中: paint.setTextAlign Paint.Align.CENTER //居中, 并不是真正的居中 往…

农村农产品信息展示网站的设计与实现(论文+源码)_kaic

摘 要 随着软件技术的迅速发展,农产品信息展示的平台越来越多,传统的农产品显示方法将被计算机图形技术取代。这种网站技术主要把农产品的描述、农产品价格、农产品图片等内容&#xff0c;通过计算机网络的开发技术&#xff0c;在互联网上进行展示&#xff0c;然后通过计算机网…

Win11共享文件,能发现主机但无法访问,提示找不到网络路径

加密长度选择如下&#xff1a; 参考以下链接&#xff1a; Redirectinghttps://answers.microsoft.com/zh-hans/windows/forum/all/win11%E8%AE%BE%E7%BD%AE%E6%96%87%E4%BB%B6%E5%A4%B9/554343a9-d963-449a-aa59-ce1e6f7c8982?tabAllReplies#tabs

小研究 - Android 字节码动态分析分布式框架(五)

安卓平台是个多进程同时运行的系统&#xff0c;它还缺少合适的动态分析接口。因此&#xff0c;在安卓平台上进行全面的动态分析具有高难度和挑战性。已有的研究大多是针对一些安全问题的分析方法或者框架&#xff0c;无法为实现更加灵活、通用的动态分析工具的开发提供支持。此…

linux字符串处理

目录 1 C 截取字符串,截取两个子串中间的字符串2 获取该字符串后面的字符串用 strstr() 函数查找需要提取的特定字符串&#xff0c;然后通过指针运算获取该字符串后面的字符串用 strtok() 函数分割字符串&#xff0c;找到需要提取的特定字符串后&#xff0c;调用 strtok() 传入…

十四五双碳双控时代下的“低碳认证”

目录 前言 十四五双碳双控时代下的“低碳认证” 一、关于“低碳认证” 二、低碳认证优势 三、环境产品认证EPD 四、EPD相关运营机构 五、碳中和相关机构 六、EPD的认证流程 七、低碳产品认证认证流程和要求 八、相关机构认证证书样例 九、证书附件表 前言 通过本篇文…

DOCKER 部署 webman项目

# 设置基础镜像 FROM php:8.2-fpm# 安装必要的软件包和依赖项 RUN apt-get update && apt-get install -y \nginx \libzip-dev \libpng-dev \libjpeg-dev \libfreetype6-dev \&& rm -rf /var/lib/apt/lists/*# 安装 PHP 扩展 RUN docker-php-ext-configure gd …

探讨C#、C++和Java这三门语言在嵌入式的地位

我理解对于初入嵌入式领域的担忧。你是想选择一款通用性最广的语言专心学习&#xff0c;但是不知如何选择&#xff0c;视频后方提供了免费的嵌入式学习资源&#xff0c;内容涵盖入门到进阶&#xff0c;需要的到后方免费获取。因为我也曾是一名计算机专业毕业生。通过一段时间的…

无涯教程-Python机器学习 - Analysis of Silhouette Score函数

剪影得分的范围是[-1,1]。其分析如下- 1分数-接近1 剪影分数表示样本距离其邻近簇很远。 0分数-0 剪影分数表示样本在将两个相邻聚类分隔开的决策边界上或非常接近。 -1分数-1 剪影分数表示样本已分配给错误的聚类。 Silhouette得分的计算可以使用以下公式完成 $$剪影得…