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

时间:2012-11-09 18:59:26

标签: c linux

例如,我在一系列设备中打开了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获取设备节点?谢谢。

3 个答案:

答案 0 :(得分:1)

正确的方法是做自己的簿记。这将允许您完全按照用户提供的方式记录设备节点名称,而不是提供等效但容易混淆的设备节点名称。

例如,您可以使用hash table将文件描述符编号与char数组关联,并使用用于相应open()调用的设备名称。

一个更简单但更脆弱且肯定推荐的解决方案可能涉及使用一个指向char的简单指针数组,其大小非常大,希望任何文件描述符您可能遇到的值可以用作相应字符串的索引,而不会超出数组边界。这比哈希表稍微容易编码,但如果文件描述符值超过字符串数组中允许的最大索引,导致程序死亡。

如果您的程序无论如何都绑定到Linux平台,您可以使用/dev/fd目录或/proc文件系统(更具体地说)作弊 /proc/self/fd通常是符号链接的/dev/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()系统调用来检索与感兴趣的文件描述符对应的链接目标。

答案 1 :(得分:0)

您需要fstat(2)系统调用,也许还需要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(在免费许可的情况下在线,但您可能想购买该书)。

答案 2 :(得分:0)

我可以看到这个问题大约是1岁。但是现在我正在寻找一种方法。我发现了它。要使用文件descritor获取设备节点,您可以合并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;
}