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