1

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

int newFd = copy(referenceFd);

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

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

4

2 回答 2

3

您可能可以通过一系列fcntl调用来做到这一点:

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

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

我链接了上面的SUSv4页面;您可能还对Linux 版本感兴趣。

于 2012-08-27T15:18:18.623 回答
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(truncate the file) 和O_EXCL(fail if exists) 不在标志中,以避免使用确切的原始标志重新打开会导致不需要的结果的情况。

不想使用lstat(),因为这会引发关于重命名的竞争条件——用户在上述代码中的lstat()和之间重命名目标文件。open()以上完全避免了这种情况。

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

于 2012-08-27T16:31:11.820 回答