14

假设操作系统是 linux。假设我打开一个文件进行写入并获得一个文件描述符fdw。是否可以获得另一个文件描述符fdr,对文件具有只读访问权限而无需open再次调用?我不想调用的原因open是底层文件可能已被其他进程在文件系统中移动甚至取消链接,因此重复使用相同的文件名对于此类操作是不可靠的。所以我的问题是:如果只给定一个文件描述符,是否仍然可以打开具有不同访问权限的文件描述符? dup或者dup2不改变访问权限,我想。

4

2 回答 2

18

是的!诀窍是通过/proc/self/fd/n. 据我所知,这是一个仅限 linux 的技巧。

运行这个程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    FILE* out_file;
    FILE* in_file;
    char* dev_fd_path;
    char buffer[128];

    /* Write “hi!” to test.txt */
    out_file = fopen("test.txt", "w");
    fputs("hi!\n", out_file);
    fflush(out_file);

    /* Delete the file */
    unlink("test.txt");

    /* Verify that the file is gone */
    system("ls test.txt");

    /* Reopen the filehandle in read-mode from /proc */
    asprintf(&dev_fd_path, "/proc/self/fd/%d", fileno(out_file));
    in_file = fopen(dev_fd_path, "r");
    if (!in_file) {
        perror("in_file is NULL");
        exit(1);
    }
    printf("%s", fgets(buffer, sizeof(buffer), in_file));

    return 0;
}

它将一些文本写入文件,将其删除,但保持文件描述符打开,然后通过不同的路径重新打开它。直到持有最后一个文件描述符的最后一个进程将其关闭,文件才真正被删除,在此之前,您可以通过/proc.


感谢我的老老板 Anatoly 在我删除了一些重要文件时教我这个技巧,幸运的是这些文件仍然被另一个进程附加!

于 2013-01-25T04:42:13.743 回答
6

不,fcntl调用不允许您在打开的文件描述符上设置读/写位,从现有文件描述符获取新文件描述符的唯一方法是使用重复功能。对dup/dup2/dup3(和)的调用fcntl不允许您更改文件访问模式。

注意:这适用于 Linux,但一般不适用于其他 Unix。例如,在 HP-UX 中,[参见(1)(2) ],您可以fcntl使用 F_SETFL 在打开的文件描述符上更改读/写位。然而,由于创建的文件描述符dup共享相同的状态标志,因此更改其中一个的访问模式必然会更改另一个的访问模式。

于 2013-01-25T04:05:01.220 回答