readdir (3) странное поведение: поиск несуществующих файлов в / dev / - PullRequest
0 голосов
/ 03 августа 2011

Я использую opendir / readdir / closedir для воспроизведения программы, аналогичной ls, она работала довольно хорошо, пока я не попытался ls "/ dev /", когда дело доходит до "/ dev / fd /" с рекурсивными опциями, он находит больше файлов, чем есть на самом деле, это не скрытые файлы (я имею в виду начинающиеся файлы с «.»). Истинное дается мне: "/ dev / fd /:" «0 1 2 3» Мой тоже. Но дело в том, что в GDB он находит еще 3 файла, которые имеют размер 4,5 и 6. Я слышал, что GDB создает свою собственную среду, так что давайте забудем об этом. Когда я пытаюсь выполнить команду ls "/ dev / fd /" -R, истинное значение ls немедленно останавливает листинг, в то время как моя программа выдает:

"/ DEV / FD / 3:"

"/ DEV / FD / 3/3 /"

"/ DEV / FD / 3/3 /......../ 10"

stat возвращает -1, по крайней мере, после 40 файлов, но выполнение продолжается: ошибка сегментации.

На моем компьютере "/ dev / fd / 3 /" и т. Д. Являются символическими ссылками, макрос "S_ISDIR" возвращает мне 0 для существующих файлов, но для несуществующих файлов, таких как: "/ dev / fd / 6 / "вернись 1 ...

Я хотел знать, почему моя программа работает неправильно, в то время как истинная ls этого не делает, я заметил, что ls использует stat64 на моем компьютере, но когда я делаю это, он все равно работает неправильно .. он также использует fstat64, futex и другие системные вызовы не знаю.

Я могу показать вам некоторые примеры моих кодов или подробности, которые мне действительно сложно объяснить, извините за это.

Спасибо.

PS: я не получаю этого утверждения на man-странице readdir: «Данные, возвращаемые readdir, могут быть перезаписаны последующими вызовами readdir для того же потока каталога»

1 Ответ

1 голос
/ 03 августа 2011

PS: я не получаю этого утверждения на странице readdir: «Данные возвращенный readdir может быть перезаписан последующими вызовами readdir для того же потока каталогов "

В сущности, они говорят, что функция не является входящей, и указатель, возвращаемый readdir, не должен просто кэшироваться как уникальное значение, поскольку базовые данные, на которые указывают, изменят в следующий раз вы вызываете функцию readdir. По сути, они позволяют реализациям определять статически распределенные данные, которые могут быть переработаны функцией, или динамическую память, управляемую ОС, так что вызывающему 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 будут указывать на одно и то же значение, и в этом случае это будет значение 1. Каждый указатель не будет указывать на уникальное целочисленное значение.

То же самое относится и к readdir. Вы не можете просто позвонить по номеру readdir и сохранить возвращаемый указатель, ожидая его использования позднее, без указания данных, которые будут изменены при любых последующих вызовах readdir между временем сохранения указателя и раз вы используете это. Если вам нужна такая функциональность, то именно для этого нужна новая версия, readdir_r.

...