C++ 尝试使用cpp程序在Linux中装载usb分区

C++ 尝试使用cpp程序在Linux中装载usb分区,c++,usb,mount,partition,udev,C++,Usb,Mount,Partition,Udev,我想检测usb连接并挂载其相应的分区。 我尝试使用udev。我能够在/dev/bus/usb/001或/002中找到设备。但是从这里我找不到它使用的分区。因此,我使用udev搜索块分区,并在添加分区时挂载。例如/dev/sda1。但这是一个临时解决方案。 我想要的是使用udev或其他东西检测usb连接,找到它拥有的分区并挂载它 我的代码: #include <libudev.h> #include <stdio.h> #include "dmutil.h" #includ

我想检测usb连接并挂载其相应的分区。 我尝试使用udev。我能够在/dev/bus/usb/001或/002中找到设备。但是从这里我找不到它使用的分区。因此,我使用udev搜索块分区,并在添加分区时挂载。例如/dev/sda1。但这是一个临时解决方案。 我想要的是使用udev或其他东西检测usb连接,找到它拥有的分区并挂载它

我的代码:

#include <libudev.h>
#include <stdio.h>
#include "dmutil.h"
#include <pthread.h>

#include <unistd.h>

/*
 Thread which detects devices.
 */
void *  udev_listener(void * i)
{

    struct udev *udev;
    udev = udev_new();
    if (!udev) {
        printf("Can't create udev\n");
        exit(1);
    }

    std::string mount_path_for_udev_listner = DEFAULT_MOUNT_PATH;
    printf("\n\n **********\nUdev_listner is asked to mount usb to %s ....",mount_path_for_udev_listner.c_str());

    struct udev_device *dev;
    struct udev_monitor *mon;   
    mon = udev_monitor_new_from_netlink(udev, "udev");
    assert(mon != NULL);
    /*  int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor,const char *subsystem, const char *devtype);
        filters to select messages that get delivered to a listener.
        On Success it returns an integer greater than, or equal to, 0. On failure, a negative error code is returned.
    */
    assert(udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL) >=0);
    udev_monitor_enable_receiving(mon);
    /* Get the file descriptor (fd) for the monitor.
       This fd will get passed to select() */

    int fd = udev_monitor_get_fd(mon);
    /* Begin polling for udev events. Events occur when devices attached to the system are added, removed, or change state. 
       udev_monitor_receive_device() will return a device object representing the device which changed and what type of change occured.

       The select() system call is used to ensure that the call to udev_monitor_receive_device() will not block.

       This section will run continuously, calling usleep() at the end of each pass. This is to  use  udev_monitor in a non-blocking way. */
    while (1) 
    {
        /*
            int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

            select()  allows  a  program  to  monitor  multiple  file descriptors,  waiting  until one or more of the file descriptors 
            become "ready" for some class of I/O operation.

            Set up the call to select(). In this case, select() will only operate on a single file descriptor, the one associated 
            with our udev_monitor. Note that the timeval object is set to 0, which will cause select() to not block. */
        fd_set fds;
        struct timeval tv;
        int ret;

        FD_ZERO(&fds); //clear fds
        FD_SET(fd, &fds);// Add fd to fds
        /*
            The timeout argument specifies the interval that select() should block waiting for a file descriptor to become ready. 
            This interval will be rounded up to the system  clock  granularity, and kernel scheduling delays mean that the 
            blocking interval may overrun by a small amount.  If both fields of the timeval structure are zero, then select() 
            returns immediately. (This is useful for polling.)If timeout is NULL (no timeout), select() can block indefinitely.
        */  
        tv.tv_sec = 0;
        tv.tv_usec = 0;
        /*
          nfds specifies how big the list of file descriptors is because the total number can be vast.
          So, if you want to monitor file descriptors 24-31, you'd set nfds to 32. 
          man - nfds is the highest-numbered file descriptor in any of the three sets, plus 1.
        */
        ret = select(fd+1, &fds, NULL, NULL, &tv);

        /* Check if our file descriptor has received data. */
        if (ret > 0 && FD_ISSET(fd, &fds)) {
            printf("\nselect() says there should be data\n");

            /* Make the call to receive the device.
               select() ensured that this will not block. */
            dev = udev_monitor_receive_device(mon);
            if (dev) {
                printf("Got Device\n");
                printf("   Node: %s\n", udev_device_get_devnode(dev));
                printf("   Subsystem: %s\n", udev_device_get_subsystem(dev));
                printf("   Devtype: %s\n", udev_device_get_devtype(dev));
                printf("   syspath:%s\n",udev_device_get_syspath(dev));
                printf("   sysname:%s\n",udev_device_get_sysname(dev));
                printf("   devpath:%s\n",udev_device_get_devpath(dev));
                printf("   subsystem:%s\n",udev_device_get_subsystem(dev));
                printf("   Action: %s\n", udev_device_get_action(dev));
                std::string devtype=udev_device_get_devtype(dev);
                std::string action=udev_device_get_action(dev);
                std::string devnode=udev_device_get_devnode(dev);
                if(devtype.compare("partition")==0 && action.compare("add") == 0)
                {
                    printf("A new partition detected at %s\nTrying to mount to %s",devnode.c_str(),mount_path_for_udev_listner.c_str());
                    int ret = mount_disk(devnode,mount_path_for_udev_listner);
                    if(ret == 0)
                    {
                        printf("\nSystem returns %d, Mounting success\n",ret);
                    }
                    else{
                            printf("\n*****Error no %d\n",errno);
                    }
                }
                if(devtype.compare("partition")==0 && action.compare("remove") == 0)
                {
                    printf("Partition removal detected, trying to unmount...\n");
                    int ret=umount_disk();
                    if(ret==0){
                        printf("\nSystem returns %d\n",ret);
                        printf("unmount successfull\n");
                    }
                    else{
                        printf("\nThe partition unmounting FAILED:\n ");
                    }
                }
                udev_device_unref(dev);
            }
            else {
                printf("No Device from receive_device(). An error occured.\n");
            }                   
        }
        usleep(250*1000);
        printf(".");
        fflush(stdout);
    }
    pthread_exit(NULL);
}
#包括
#包括
#包括“dmutil.h”
#包括
#包括
/*
检测设备的线程。
*/
void*udev\u侦听器(void*i)
{
结构udev*udev;
udev=udev_new();
如果(!udev){
printf(“无法创建udev\n”);
出口(1);
}
std::string mount\u path\u for\u udev\u listner=默认的\u mount\u路径;
printf(“\n\n************\nUdev\u listner被要求将usb挂载到%s…”,挂载udev\u listner.c\u str()的路径);
结构udev_设备*dev;
结构udev_监视器*mon;
mon=udev_监视器_新_来自网络链接(udev,udev”);
断言(mon!=NULL);
/*int udev_monitor_filter_add_match_subsystem_devtype(结构udev_monitor*udev_monitor,常量字符*子系统,常量字符*devtype);
筛选以选择传递给侦听器的消息。
成功时返回大于或等于0的整数。失败时返回负错误代码。
*/
断言(udev\u监视器\u过滤器\u添加\u匹配\u子系统\u devtype(mon,“block”,NULL)>=0);
udev_监视器_启用_接收(mon);
/*获取监视器的文件描述符(fd)。
此fd将传递给select()*/
int fd=udev\u monitor\u get\u fd(周一);
/*开始轮询udev事件。添加、删除或更改连接到系统的设备状态时会发生事件。
udev_monitor_receive_device()将返回一个设备对象,表示已更改的设备以及发生的更改类型。
select()系统调用用于确保对udev\u monitor\u receive\u device()的调用不会被阻塞。
此部分将连续运行,在每次传递结束时调用usleep()。这是以非阻塞方式使用udev_监视器*/
而(1)
{
/*
int-select(int-nfds、fd_集*readfds、fd_集*writefds、fd_集*exceptfds、struct-timeval*timeout);
select()允许程序监视多个文件描述符,等待一个或多个文件描述符
为某种类型的I/O操作做好“准备”。
设置对select()的调用。在这种情况下,select()将仅对单个文件描述符(关联的文件描述符)进行操作
注意,timeval对象被设置为0,这将导致select()不被阻塞*/
fd_集fds;
结构时间值电视;
int ret;
FD_ZERO(&fds);//清除fds
FD_集(FD,&fds);//将FD添加到fds
/*
timeout参数指定select()在等待文件描述符就绪时应阻止的间隔。
这个间隔将被四舍五入到系统时钟粒度,内核调度延迟意味着
阻塞间隔可能会超出一小部分。如果timeval结构的两个字段都为零,则选择()
立即返回。(这对于轮询很有用。)如果超时为NULL(无超时),则select()可以无限期地阻止。
*/  
tv.tv_sec=0;
tv.tv_usec=0;
/*
nfds指定文件描述符列表的大小,因为总数可能很大。
因此,如果您想24-31监视文件描述符,您应该将nfds设置为32。
man-nfds是三个集合中编号最高的文件描述符,加上1。
*/
ret=选择(fd+1和fds、NULL、NULL和tv);
/*检查文件描述符是否接收到数据*/
如果(ret>0和FD_设置(FD和fds)){
printf(“\n选择()表示应该有数据\n”);
/*拨打电话以接收设备。
select()确保此操作不会阻塞*/
dev=udev\u监视器\u接收设备(mon);
如果(开发){
printf(“获取设备\n”);
printf(“节点:%s\n”,udev_设备_获取_devnode(dev));
printf(“子系统:%s\n”,udev_设备_get_子系统(dev));
printf(“Devtype:%s\n”,udev_设备_get_Devtype(dev));
printf(“系统路径:%s\n”,udev\u设备\u获取\u系统路径(dev));
printf(“系统名:%s\n”,udev\u设备\u获取\u系统名(dev));
printf(“devpath:%s\n”,udev_device_get_devpath(dev));
printf(“子系统:%s\n”,udev_设备_get_子系统(dev));
printf(“操作:%s\n”,udev\u设备获取操作(dev));
std::string devtype=udev_device_get_devtype(dev);
std::string action=udev\u device\u get\u action(dev);
std::string devnode=udev_device_get_devnode(dev);
if(devtype.compare(“partition”)=0和&action.compare(“add”)=0)
{
printf(“在%s处检测到一个新分区\n要装载到%s”,devnode.c_str(),mount_path_for_udev_listner.c_str());
int-ret=挂载磁盘(devnode,挂载路径,用于挂载列表器);
如果(ret==0)
{
printf(“\n系统返回%d,装载成功”,ret);
}
否则{
printf(“\n****错误号%d\n”,errno);
}
}
if(devtype.compare(“partition”)=0和&action.compare(“remove”)=0)
{
printf(“检测到分区删除,正在尝试卸载…\n”);
int ret=umount_disk();
如果(ret==0){
printf(“\n系统返回%d\n”,ret);
 assert(udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL)>=0);
 assert(udev_monitor_filter_add_match_subsystem_devtype(mon, "usb","usb-device") >=0);