我有一个打开的设备描述符,我不知道设备名称和选项 传递到开放(...)。 我想打开一个新的设备描述符,并将相同的选项传递给open。
int newFd = copy(referenceFd);
副本可以完成这项工作。 dup()肯定是错误的选择,因为newFd上的另一个ioctl()也会改变referenceFd,因此我想打开一个新的描述符。
是否有提供此类功能的系统调用?
我还没有找到一些东西。
答案 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发行版)中都支持它。