繁体   English   中英

如何使用设备的文件描述符获取设备的devnode

[英]How can I get the devnode of a device using its file descriptor

例如,我在一组设备中打开了2个设备。

NODES是/ dev / ttyUSB0,/ dev / ttyUSB1等。

#define MAXDEV 4
devlist[MAXDEV];
const char *devices[] = {"/dev/ttyUSB0","/dev/ttyUSB1");


for(loop =0; loop<sizeof(devices); loop++){

    fd= open(devices[loop]);

}

现在,我将它们添加到fds列表中;

for(i=0; i<MAXDEV; i++){

if(devlist[i] != 0){
devlist[i] = fd;
fd = -1;
}

}

现在,我在设备上阅读数据。

    for(iter=0; iter<MAXDEV; iter++){

if(FD_ISSET(devlist[iter],&fds)){

if ((nbytes = read(devlist[iter], buf, sizeof(buf)-1)) > 0 && nbytes != 0)
                    {

                 buf[nbytes] = '\0';

                     printf("Data Received on Node ???");

                    }
                if(nbytes < 0){
                            printf("connection reset\n");
                            FD_CLR(devlist[iter], &fds);
                            close(devlist[iter]);
                            devlist[iter] = 0;

                        }
                        if(nbytes ==0){
                            printf("Device Removed on Node ???\n");


                        FD_CLR(devlist[iter], &fds);
                            close(devlist[iter]);
                            devlist[iter] = 0;

                        }
    }
}

现在如何使用其fd获取设备节点?

正确的方法是自己做簿记。 这样一来,您就可以准确记录用户提供的设备节点名称,而不用提供一个等效但令人困惑的名称。

例如,您可以使用哈希表 ,将文件描述符号与具有用于相应open()调用的设备名称的char数组相关联。

一个更简单但更脆弱且绝对建议使用的解决方案可能涉及使用指向char的简单指针数组,且其大小特别大,以期希望您可能会遇到的任何文件描述符值都可以用作适当索引的索引。字符串而不会超出数组范围。 这比哈希表更容易编码,但是如果文件描述符值超过字符串数组中允许的最大索引, 它将导致程序严重死亡。

如果您的程序仍然绑定到Linux平台,则可以使用/dev/fd目录或/proc文件系统(更具体地说是/dev/fd/proc/self/fd目录)来作弊通常是一个符号链接)。 两者都包含符号链接,这些符号链接将文件描述符值与用于打开相应文件的路径的规范版本相关联。 例如,考虑以下记录:

$ ls -l /proc/self/fd
total 0
lrwx------ 1 user user 64 Nov  9 23:21 0 -> /dev/pts/10
l-wx------ 1 user user 64 Nov  9 23:21 1 -> /dev/pts/10
lrwx------ 1 user user 64 Nov  9 23:21 2 -> /dev/pts/10
lr-x------ 1 user user 64 Nov  9 23:21 3 -> /proc/16437/fd/

您可以使用readlink()系统调用来检索与目标文件描述符相对应的链接目标。

您需要fstat(2) syscall,也许还需要fstatfs(2) 检查是否成功。

  struct stat st;
  memset (&st, 0, sizeof(st));
  if (fstat (fd, &st))
    perror("fstat");
  else {
    // use st, notably st.st_rdev
  }

请记住,您可以在/dev之外使用设备。 如果确定设备在其中,则可以对其中的每个条目进行stat(2)并比较其st_rdev

另请阅读Advanced Linux Programming (它是在免费许可证下在线提供的,但您可能需要购买此书)。

好吧,我可以看到这个问题大约是1岁。 但是现在我正在寻找一种方法。 我找到了。 为了使用文件描述符获取设备节点,可以将statlibudev结合使用,这里是一个示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <libudev.h>
#include <iostream>
#include <fcntl.h>


int main(int argc, char *argv[])
{
    struct stat sb;

    // Get a file descriptor to the file.
    int fd = open(argv[1], O_RDWR);

    // Get stats for that file descriptor.
    if (fstat(fd, &sb) == -1) {
        perror("stat");
        exit(EXIT_FAILURE);
    }

    // Create the udev context.
    struct udev *udev;
    udev = udev_new();

    // Create de udev_device from the dev_t obtained from stat.
    struct udev_device *dev;
    dev = udev_device_new_from_devnum(udev, 'b', sb.st_dev);

    // Finally obtain the node.
    const char* node  = udev_device_get_devnode(dev);

    udev_unref(udev);

    std::cout << "The file is in:    " << node << std::endl;

    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM