如何使用C程序查找可移动设备的序列号

How to find the serial number of removable devices using C program

我正在使用 bash 脚本为我的另一个应用程序获取可移动设备(如笔式驱动器)的序列号。 是否可以在本机 C 中执行,有人可以将此 bash 转换为 C。

#!/bin/bash
for C in `ls /sys/block/`; do 
    RE=`cat /sys/block/$C/removable`
        if [ $RE == "1" ] ;then 
            #VENDOR=`/bin/udevadm info --name=/dev/$C | grep ID_VENDOR=|awk -F"=" ' { print }'`
            #MODEL=`/bin/udevadm info --name=/dev/$C | grep ID_MODEL=|awk -F"=" ' { print }'`
            #SERIAL=`/bin/udevadm info --name=/dev/$C | grep SERIAL_SHORT|awk -F"=" ' { print }'`
            #echo $VENDOR-$MODEL"-"$SERIAL #print as per your taste
            USB_SERIAL=`/bin/udevadm info --name=/dev/$C | grep ID_SERIAL=|awk -F"=" ' { print }'|awk -F"-" ' { print }'`
            echo  $USB_SERIAL #or just the default one
        fi 
done

我不想使用系统调用。想要纯C程序

这里的关键挑战是,因为您不想使用 system(),所以要模仿 udevadm info 的工作方式。下面的程序通过读取 /run/udev/data/b<i>MAJOR</i>:<i>MINOR</i> 中的信息来做到这一点(至少在我的系统上是这样) ,其中 MAJORMINOR 是我们从 /sys/block/<i>NAME</i>/dev,其中NAME是块设备名称。

#include <dirent.h>
#include <stdio.h>

int main()
{
    struct dirent *entry;           // read thru the entries in "/sys/block"
    for (DIR *dirp = opendir("/sys/block"); entry = readdir(dirp); )
    if (entry->d_type == DT_LNK)    // the relevant files are symbolic links
    {
        char path[277];
        sprintf(path, "/sys/block/%s/removable", entry->d_name);
        FILE *fp = fopen(path, "r"); if (!fp) return perror(path), 1;
        int re;                     // read the /sys/block/%s/removable flag
        fscanf(fp, "%d", &re), fclose(fp);
        if (re)
        {                           // read the device's MAJOR:MINOR numbers
            sprintf(path, "/sys/block/%s/dev", entry->d_name);
            fp = fopen(path, "r"); if (!fp) return perror(path), 1;
            fscanf(fp, "%s", path+sprintf(path, "/run/udev/data/b")),
            fclose(fp);
            fp = fopen(path, "r"); if (!fp) return perror(path), 1;
            char USB_serial[NAME_MAX];  // scan the udev/data for ID_SERIAL=
            while (fgets(path, sizeof path, fp))
                if (sscanf(path, "E:ID_SERIAL=%[^-]", USB_serial) > 0)
                    puts(USB_serial);
            fclose(fp);
        }
    }
}