Linux uses libudev to obtain the mounting path, monitor U disk hot plug events, and U disk file system type

Article directory

  • Get mount path
  • Monitor U disk hot plug events
    • libusb
  • File system type
  • Get the mount path through the mount point
  • Tim libudev plus library

Get the mount path

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

int main() {<!-- -->
    struct udev *udev;
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices, *entry;

    //Create udev context and device enumerator
    udev = udev_new();
    if (!udev) {<!-- -->
        printf("Failed to create udev context\
");
        return 1;
    }

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

    //Add matching filter to select block devices (USB drives)
    udev_enumerate_add_match_subsystem(enumerate, "block");
    udev_enumerate_scan_devices(enumerate);
    devices = udev_enumerate_get_list_entry(enumerate);

    // Traverse the device list and obtain device information
    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\
", udev_device_get_devnode(dev));
#if 0
        // Check whether the device is a USB flash drive. You can add other judgment conditions according to needs.
        if (udev_device_get_devtype(dev) & amp; & amp; strcmp(udev_device_get_devtype(dev), "disk") == 0) {<!-- -->
            printf("U disk mounting path: %s\
", devnode);
        }
#endif
        udev_device_unref(dev);
    }
    
  

    // Clean up resources
    udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return 0;
}

Compilation directives

gcc your_code.c -o your_executable -ludev


Monitor U disk hot plug events

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

int main() {<!-- -->
    struct udev *udev;
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices, *entry;

    //Create udev context and device enumerator
    udev = udev_new();
    if (!udev) {<!-- -->
        printf("Failed to create udev context\
");
        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( & amp;fds);
    FD_SET(fd, & amp;fds);

    // Use the select function to wait for device events
    if (select(fd + 1, & amp;fds, NULL, NULL, NULL) > 0) {<!-- -->
        if (FD_ISSET(fd, & amp;fds)) {<!-- -->
            struct udev_device *dev = udev_monitor_receive_device(mon);
            if (dev) {<!-- -->
                const char *action = udev_device_get_action(dev);

                // Determine the event type and handle U disk insertion and removal events
                if (strcmp(action, "add") == 0) {<!-- -->
                    printf("U disk inserted\
");
                } else if (strcmp(action, "remove") == 0) {<!-- -->
                    printf("U disk removed\
");
                }

                udev_device_unref(dev);
            }
        }
    }
}

    // Clean up resources
    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 // The manufacturer ID of the USB flash drive
#define PRODUCT_ID LIBUSB_HOTPLUG_MATCH_ANY // Product ID of USB flash drive

#if 1
static int LIBUSB_CALL usb_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{<!-- -->
   printf("\
\
12345235235\
\
");
   if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {<!-- -->
            printf("U disk has been inserted\
");
            //Perform the operation when the U disk is inserted here
        } else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) {<!-- -->
            printf("The USB disk has been removed\
");
            //Perform the operation when the U disk is pulled out here
        }
}


static int LIBUSB_CALL usb_callback_in(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{<!-- -->
   printf("\
\
12___________\
\
");

            printf("U disk has been inserted\
");
            //Perform the operation when the U disk is inserted here
fflush(stdout);
}

static int LIBUSB_CALL usb_callback_out(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data)
{<!-- -->
   printf("\
\
12----------\
\
");

            printf("The USB disk has been removed\
");
            // Execute U disk removal here
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( & amp;ctx);

    assert(rc == 0);

    rc = libusb_has_capability( LIBUSB_CAP_HAS_HOTPLUG);

    if(rc!=0)
    {<!-- -->
     printf("capability\
");
    }
    //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\
");
        libusb_exit(ctx);
        return rc;
    }
    printf("Listening for U disk insertion and removal events...\
");

    while (1)
    {<!-- -->
rc = libusb_handle_events(ctx);
if (rc != LIBUSB_SUCCESS)
{<!-- -->
            fprintf(stderr, "libusb_handle_events() error: %s\
", libusb_strerror(rc));
            break;
        }
printf("A new event occurred...\
");
     }
     //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 \
");
}
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

File system type

#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\
");
        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 & amp; & amp; fs_type) {<!-- -->
            printf("Device: %s\
", devnode);
            printf("File System Type: %s\
", fs_type);
        }
/****************************************************** *********************************/
        udev_device_unref(dev);
    }

    udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return 0;
}

This code uses the libudev library to obtain the device node and file system type by traversing the USB device list. First, use the udev_new() function to initialize the udev context, then create a udev_enumerate object and set the matching subsystem to “block”. Next, use the udev_enumerate_scan_devices() function to scan for devices. Then, get the list of devices and use the udev_list_entry_foreach() function to iterate through the list. During the traversal process, a udev_device object is created based on the syspath of the device by calling the udev_device_new_from_syspath() function. Then, use the udev_device_get_devnode() function to get the device node and the udev_device_get_property_value() function to get the file system type. Finally, the device node and file system type are output.

Get the mount path through the mount point

#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;

    //Open /proc/mounts file
    fp = fopen("/proc/mounts", "r");
    if (fp == NULL) {<!-- -->
        printf("Failed to open /proc/mounts\
");
        return NULL;
    }

    //Read the /proc/mounts file line by line
    while ((read = getline( & amp;line, & amp;len, fp)) != -1) {<!-- -->
        char* token;
        char* saveptr = NULL;
        char* mount;
        char* device;

        //Resolve mount point and device path
        token = strtok_r(line, " ", & amp;saveptr);
        mount = token;
        
        token = strtok_r(NULL, " ", & amp;saveptr);
        device = token;

        // If the mount points match, save the device path
        if (strcmp(mount, mount_point) == 0) {<!-- -->
            device_path = strdup(device); // Save a copy of the device path
            break;
        }
    }

    //Close file and release resources
    fclose(fp);
    if (line) {<!-- -->
        free(line);
    }

    return device_path;
}

int main() {<!-- -->
    const char* mount_point = "/dev/sdb1"; // Replace with your mount point

    char* device_path = get_usb_device_path(mount_point);

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

    return 0;
}

Add libudev library

sudo apt-get install libudev-dev