14

OSはlinuxだとします。書き込み用にファイルを開き、ファイル記述子を取得したとしますfdwfdr再度呼び出さずにファイルへの読み取り専用アクセスを使用して、別のファイル記述子を取得することは可能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


幸いなことに、別のプロセスによってまだ追加されているいくつかの重要なファイルを削除したときに、このトリックを教えてくれた古い上司のアナトリーに感謝します!

于 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 に答える