Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用设备文件symlink查找总线号和设备号_C++_C_Linux_Device - Fatal编程技术网

C++ 使用设备文件symlink查找总线号和设备号

C++ 使用设备文件symlink查找总线号和设备号,c++,c,linux,device,C++,C,Linux,Device,我有一个由udev规则生成的设备文件(SYMLINK)/dev/CDMAModem。我想找到实际设备的总线号和设备号。实际上,我想在C++的程序中执行 UBDEVFSsRead < /Cord> IOCTL在设备 /DEV/BUS/USB/BuSUNO/DeVice ION/COD>。 ----乌代夫法则---- 我认为stat()。。。与libusb一起。您可以在符号链接/dev/CDMAModem表示的文件上执行ioctl,就像在/dev/bus/结构下的文件上一样 #include <

我有一个由
udev
规则生成的设备文件(
SYMLINK
/dev/CDMAModem
。我想找到实际设备的总线号和设备号。实际上,我想在C++的程序中执行<代码> UBDEVFSsRead < /Cord> IOCTL在设备<代码> /DEV/BUS/USB/BuSUNO/DeVice ION/COD>。 ----乌代夫法则----


我认为
stat()。。。与libusb一起。

您可以在符号链接
/dev/CDMAModem
表示的文件上执行
ioctl
,就像在
/dev/bus/
结构下的文件上一样

#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>

int f = open("/dev/CDMAModem", O_RDWR);
ioctl(f, USBDEVFS_RESET);

我想libudev会告诉你:

#include <libudev.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>

int main(int argc, char **argv)
{

    struct udev *udev;
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices, *dev_list_entry;
    struct udev_device *dev;

    udev = udev_new();

    enumerate = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(enumerate, "CDMAModem");
    udev_enumerate_scan_devices(enumerate);
    devices = udev_enumerate_get_list_entry(enumerate);

    udev_list_entry_foreach(dev_list_entry, devices) {
        const char *path;

        path = udev_list_entry_get_name(dev_list_entry);
        dev = udev_device_new_from_syspath(udev, path);

        fprintf(stderr, "devnum: %s\n",
            udev_device_get_sysattr_value(dev, "devnum"));
        fprintf(stderr, "busnum: %s\n",
            udev_device_get_sysattr_value(dev, 'busnum:));
        udev_device_unref(dev);
    }

    udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return 0;
}

如果您只想解析链接,那么以后可以使用字符串函数来解析信息

函数:ssize\u t readlink(常量字符*文件名,字符*缓冲区,大小)

readlink函数获取符号链接文件名的值。链接指向的文件名将复制到缓冲区中。此文件名字符串不以null结尾;readlink通常返回复制的字符数。size参数指定要复制的最大字符数,通常是缓冲区的分配大小


虽然这是丑陋的,但工作。从C++程序调用<代码> UDEADADM<代码>,并对代码进行过滤>代码> BunUM< /C>和<代码> DeVNUM< /COD>属性。我希望参与
libudev
开发的开发人员能够提供帮助,并且可能是
udev
邮件列表的开发人员也会提供帮助。

使用
stat()
将按照符号链接到最后的设备(或文件),并从那里报告信息。主设备号和次设备号可能对所需信息进行编码。我肯定至少应该使用
libusb
,因为
/dev/CDMAModem
是调制解调器驱动程序创建的inode的
SYMLINK
。我明天会悬赏的。不,你不能那样做
/dev/CDMAModem
不是
bus/usb/bus/dev
的符号链接。您说该文件是由udev规则(可能是您编写的)创建的,该规则通常会生成符号链接。显然情况并非如此,您能否发布udev文件,或者至少发布
文件
命令的输出?首先,我尝试在
/dev/CDMAModem
上执行ioctl,这导致了发布此问题。我用
udev
规则更新了这个问题。
file/dev/CDMAModem/dev/CDMAModem:ttyUSB0的符号链接
file/dev/ttyUSB0/dev/ttyUSB0:character special
它看起来很有希望,我明天会执行它。坦克!我遗漏了几个细节,但是这个默认情况应该会引导我们朝着正确的方向发展。
udev\u enumerate\u get\u list\u entry(enumerate)
返回
NULL
。我还尝试了
“/dev/CDMAModem”
“/dev/ttyUSB0”
;没用
udevadm info-a-p$(sudo udevadm info-q path-n/dev/ttyUSB0)
给出了总线和设备号,因此我肯定应该使用
libudev
+1是否从udev_new()调用中获得有效的udev结构?如果是这样,请尝试调用
udev\u enumerate\u add\u match\u subsystem(enumerate,“usb”)
udev\u enumerate\u add\u match\u subsystem(enumerate,“usb设备”)
或使用适当的CDMAModem
/sys/class
条目。是的,我在所有情况下都得到了udev结构<代码>“usb”
提供了所有已连接的usb设备;是输出。但是我需要找到
/dev/CDMAModem
的总线和设备号。
> file /dev/CDMAModem
/dev/CDMAModem: symbolic link to `bus/usb/BUS/DEV'
#include <libudev.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>

int main(int argc, char **argv)
{

    struct udev *udev;
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices, *dev_list_entry;
    struct udev_device *dev;

    udev = udev_new();

    enumerate = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(enumerate, "CDMAModem");
    udev_enumerate_scan_devices(enumerate);
    devices = udev_enumerate_get_list_entry(enumerate);

    udev_list_entry_foreach(dev_list_entry, devices) {
        const char *path;

        path = udev_list_entry_get_name(dev_list_entry);
        dev = udev_device_new_from_syspath(udev, path);

        fprintf(stderr, "devnum: %s\n",
            udev_device_get_sysattr_value(dev, "devnum"));
        fprintf(stderr, "busnum: %s\n",
            udev_device_get_sysattr_value(dev, 'busnum:));
        udev_device_unref(dev);
    }

    udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return 0;
}
[charles@localhost 2-1]$ cd /sys/class/mem/random
[charles@localhost 2-1]$echo $PWD
/sys/devices/pci0000:00/0000:00:11.0/0000:02:00.0/usb2/2-1
~$ sudo udevadm info -a -p $(sudo udevadm info -q path -n /dev/CDMAModem)
[sudo] password for gowtham:

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/ttyUSB0/tty/ttyUSB0':
    KERNEL=="ttyUSB0"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/ttyUSB0':
    KERNELS=="ttyUSB0"
    SUBSYSTEMS=="usb-serial"
    DRIVERS=="zte_ev"
    ATTRS{port_number}=="0"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0':
    KERNELS=="2-1.2:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="zte_ev"
    ATTRS{bInterfaceClass}=="ff"
    ATTRS{bInterfaceSubClass}=="ff"
    ATTRS{bInterfaceProtocol}=="ff"
    ATTRS{bNumEndpoints}=="03"
    ATTRS{supports_autosuspend}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{interface}=="Data Interface"

  looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2':
    KERNELS=="2-1.2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{devpath}=="1.2"
    ATTRS{idVendor}=="19d2"
    ATTRS{speed}=="12"
    ATTRS{bNumInterfaces}==" 6"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{busnum}=="2"
    ATTRS{devnum}=="8"
  ATTRS{busnum}=="2"
  ATTRS{devnum}=="8"