Интерфейс K & R для чтения каталогов: лишняя структура DIR? - PullRequest
5 голосов
/ 17 сентября 2010

Во 2-м издании "Язык программирования C" Кернигана и Ричи они реализуют упрощенную версию команды UNIX ls (раздел 8.6 "Пример - список каталогов" , стр. 179). Для этого они создают следующий интерфейс, который обеспечивает системно-независимый доступ к имени и номеру индекса файлов, хранящихся в каталоге.

#define NAME_MAX 14   /* longest filename component; */
                              /* system dependent */

typedef struct {      /* portable director-entry */
    long ino;                 /* inode number */
    char name[NAME_MAX+1];    /* name + '\0' terminator */
} Dirent;

typedef struct {      /* minimal DIR: no buffering, etc. */
    int fd;                   /* file descriptor for directory */
    Dirent d;                 /* the directory entry */
} DIR;

DIR *opendir(char *dirname);
Dirent *readdir(DIR *dfd);
void closedir(DIR *dfd);

Затем они реализуют этот интерфейс для систем UNIX Версии 7 и System V.

  • opendir() в основном использует систему позвоните open(), чтобы открыть каталог и malloc() чтобы выделить место для DIR структура. Дескриптор файла возвращается open() затем сохраняется в переменной fd этого DIR. Ничего не хранится в Dirent компонент.

  • readdir() использует системный вызов read() чтобы получить следующий (системно-зависимая) запись каталога открытый каталог и копирует так полученный номер инода и имя файла в статическую Dirent структуру (для который указатель возвращается). только информация, необходимая readdir() - дескриптор файла хранится в структуре DIR.

Теперь на мой вопрос : Какой смысл иметь DIR структуру? Если я правильно понимаю эту программу, компонент Dirent в DIR никогда не используется, так почему бы не заменить всю структуру дескриптором файла и напрямую использовать open() и close()?

Спасибо.

PS: я знаю, что в современных системах UNIX read() больше нельзя использовать в каталогах (я опробовал эту программу на Ubuntu 10.04), но я все же хочу убедиться, что я не пропустил что-то важное в этот пример.

Ответы [ 2 ]

4 голосов
/ 17 сентября 2010

От K & R:

К сожалению, формат и точное содержание каталога не одинаковы для всех версии системы. Итак, мы разделим задачу на две части, чтобы попытаться изолировать непереносимые части. Внешний уровень определяет структуру, называемую Dirent и тремя подпрограммами opendir , readdir и closedir , чтобы обеспечить независимый от системы доступ к имя и номер индекса в записи каталога.

Так что причина в мобильности. Они хотят определить интерфейс, который может существовать в системах с различными структурами статистики или нестандартными open() и close(). Они продолжают создавать кучу многократно используемых инструментов, которые даже не заботятся о том, находятся ли они в Unix-подобных системах. В этом суть обертки.

Может быть, он не используется, потому что они начали с определения своих структур данных (с Dirent внутри DIR), но в итоге не использовали его. Хранение структур данных, сгруппированных таким образом, является хорошим дизайном.

0 голосов
/ 17 сентября 2010

Поэтому им не нужно выделять память для структуры Dirent, которая возвращается readdir.Таким образом, они могут повторно использовать Dirent между последующими вызовами readdir.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...