0

例如,我在设备阵列中打开了 2 个设备..

节点是 /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 获取设备节点?...谢谢。

4

3 回答 3

1

做到这一点的正确方法是自己记账。这将允许您完全按照用户提供的方式记录设备节点名称,而不是提供等效但令人困惑的不同名称。

例如,您可以使用哈希表,将文件描述符编号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()系统调用来检索与感兴趣的文件描述符相对应的链接目标。

于 2012-11-09T21:24:29.827 回答
0

好吧,我可以看到这个问题大约有 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;
}
于 2014-05-08T15:13:34.080 回答
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

另请阅读高级 Linux 编程(它在免费许可下在线,但您可能想购买这本书)。

于 2012-11-09T19:24:06.417 回答