使用与引用描述符相同的选项打开新设备描述符

时间:2012-08-27 15:15:59

标签: c linux

我有一个打开的设备描述符,我不知道设备名称和选项 传递到开放(...)。 我想打开一个新的设备描述符,并将相同的选项传递给open。

int newFd = copy(referenceFd);

副本可以完成这项工作。 dup()肯定是错误的选择,因为newFd上的另一个ioctl()也会改变referenceFd,因此我想打开一个新的描述符。

是否有提供此类功能的系统调用?
我还没有找到一些东西。

2 个答案:

答案 0 :(得分:3)

您可以使用一系列fcntl calls

来执行此操作
  

F_GETFD - 获取与文件描述符fildes关联的文件描述符标记。

     

F_GETFL - 获取与fildes相关的文件描述中定义的文件状态标志和文件访问模式。

我链接了上面的SUSv4页面;您可能也对the Linux version感兴趣。

答案 1 :(得分:1)

首先,使用

获取文件描述符fd的描述符标志
    int flags = fcntl(fd, F_GETFL);

然后,使用特定于Linux的/proc/self/fd/ fd 条目重新打开描述符:

    int  newfd;
    char buffer[32];

    if (snprintf(buffer, sizeof buffer, "/proc/self/fd/%d", fd) < sizeof buffer) {
        do {
            newfd = open(buffer, flags & ~(O_TRUNC | O_EXCL), 0666);
        } while (newfd == -1 && errno == EINTR);
        if (newfd == -1) {
            /* Error: Cannot reopen file. Error in errno. */
        }
    } else {
        /* Error: the path does not fit in the buffer. */
    }

然后重新打开的文件描述符在newfd

请注意,您很可能希望确保O_TRUNC(截断文件)并且O_EXCL(如果存在则失败)不在标志中,以避免使用完全原始标志重新打开的情况会导致不必要的结果。

想要使用lstat(),因为这会打开与重命名相关的竞争条件 - 用户在lstat()和之间重命名目标文件上面代码中的open()。以上完全避免了这一点。

如果您不想特定于Linux,请添加与/dev/fd/ fd 相同的代码(如果上述操作失败)。在一些Unix系统(以及大多数Linux发行版)中都支持它。