0

私は opendir / readdir / closedir を使用して ls に似たプログラムを再現しています。再帰オプションを使用して「/dev/fd/」になると、「/dev/」を ls しようとするまではうまくいきました。ファイルが実際に存在するよりも多く、それらは隠しファイルではありません (「.」ファイルの開始を意味します)。本当の ls は私に : "/dev/fd/ :" "0 1 2 3" 私もそうです。しかし、問題は、gdb で、4、5、6 の 3 つのファイルをさらに見つけることです。gdb は独自の環境を作成すると聞いたので、これは忘れましょう。ls "/dev/fd/" -R を試すと、真の ls はすぐにリストを停止し、プログラムは次のようになります。

「/dev/fd/3:」

「/dev/fd/3/3/」

「/dev/fd/3/3/......../10」

stat は、少なくとも 40 個のファイルの後に -1 を返しますが、実行は継続します: セグメンテーション違反。

私のコンピューターでは、「/dev/fd/3/」とシンボリックリンクがあり、マクロ「S_ISDIR」は既存のファイルでは0を返しますが、「/dev/fd/6/」のような存在しないファイルでは返します1...

本当の ls はそうではないのに、なぜ私のプログラムがうまくいかないのか知りたかったのですが、ls は自分のコンピューターで stat64 を使用していることに気付きましたが、それでもうまくいかないことに気付きました.. fstat64、futex など、私が使用していない syscall も使用します知る。

コードのサンプルや詳細をお見せできますが、説明するのが本当に難しいので、申し訳ありません。

ありがとうございます。

PS : readdir マンページでそのステートメントを取得しません:「readdir によって返されたデータは、同じディレクトリ ストリームの readdir への後続の呼び出しによって上書きされる可能性があります」

4

1 に答える 1

1

PS : readdir マンページでそのステートメントを取得しません:「readdir によって返されたデータは、同じディレクトリ ストリームの readdir への後続の呼び出しによって上書きされる可能性があります」

彼らが基本的に言っていることは、関数は再入可能ではなく、返されたポインタはreaddir単純に一意の値としてキャッシュされるべきではないということです。readdir. 基本的に、関数によって再利用できる静的に割り当てられたデータ、または OS によって管理される動的メモリのいずれかを実装で定義できるようになっているため、 の呼び出し元はreaddirの戻り値が指すメモリの管理について心配する必要がありませんreaddir。たとえば、次のようなサンプル関数の場合:

int* my_sample_increment()
{
    static int val = 0;
    val++;

    return &val;
}

あなたが次のようなことをするなら

int* int_ptr_1 = my_sample_increment();
int* int_ptr_2 = my_sample_increment();

次に、int_ptr_1との両方int_ptr_2が同じ値を指し、この場合は value になります1。各ポインターは、一意の整数値を指しているわけではありません。

したがって、同じことが当てはまりますreaddir。ポインターを保存してから使用するまでの間に、readdirへの後続の呼び出しによってポイントされているデータが変更されることなく、後日それを使用することを期待して、返されたポインターを単純に呼び出して保存することはできません。readdirそのような機能が必要な場合、それが再入可能バージョンのreaddir_r目的です。

于 2011-08-03T04:27:12.990 に答える