Чтение онлайн

ЖАНРЫ

Linux программирование в примерах
Шрифт:

5.1.2. Содержимое каталога

Каталоги устанавливают связь между именем файла и индексом. Элементы каталога содержат номер индекса и имя файла. Они содержат также дополнительную учетную информацию, которая нам здесь не интересна. См. рис. 5.2.

Рис. 5.2. Концептуальное содержание каталога

На ранних Unix-системах были двухбайтные номера индексов, а имена файлов — до 14 байтов. Вот полное содержание файла V7

/usr/include/sys/dir.h
:

#ifndef DIRSIZ

#define DIRSIZ 14

#endif

struct direct {

 ino_t d_ino;

 char d_name[DIRSIZ];

};

ino_t
определен в V7
<sys/types.h>
как '
typedef unsigned int into_t;
'. Поскольку на PDP-11
int
является 16-разрядным, таким же является и
ino_t
. Такая организация упрощала непосредственное чтение каталогов; поскольку размер элемента был фиксирован, код был простым. (Единственно, за чем нужно было следить, это то, что полное 14-символьное
d_name
не завершалось символом NUL.)

Управление содержанием каталога для системы также было простым. Когда файл удалялся из каталога, система заменяла номер индекса двоичным нулем, указывая, что элемент каталога не используется. Новые файлы могли потом использовать пустой элемент повторно. Это помогало поддерживать размер самих файлов каталогов в приемлемых рамках. (По соглашению, номер индекса 1 не используется; первым используемым индексом всегда является 2. Дополнительные сведения приведены в разделе 8.1 «Монтирование и демонтирование файловых систем».)

Современные системы предоставляют длинные имена файлов. Каждый элемент каталога имеет различную длину, с обычным ограничением для компонента имени файла каталога в 255 байтов. Далее мы увидим, как читать на современных системах содержимое каталога. Также в современных системах номера индексов 32 (или даже 64!) разрядные.

5.1.3. Прямые ссылки

Когда файл создается с помощью

open
или
creat
, система находит не использующийся индекс и присваивает его новому файлу. Она создает для файла элемент каталога с именем файла и номером индекса. Опция
– i
команды
ls
отображает номер индекса.

$ echo hello, world > message /* Создать новый файл */

$ ls -il message /* Показать также номер индекса */

228786 -rw-r--r-- 1 arnold devel 13 May 4 15:43 message

Поскольку элементы каталога связывают имена файлов с индексами, у одного файла может быть несколько имен. Каждый элемент каталога, ссылающийся на один и тот же индекс, называется ссылкой (link) или прямой ссылкой (hard link) на файл. Ссылки создаются с помощью команды

ln
. Она используется следующим образом: '
ln старый_файл новый_файл
'.

$ ln message msg /* Создать ссылку */

$ cat msg /* Показать содержание нового имени */

hello, world

$ ls -il msg message /* Показать номера индексов */

228786 -rw-r--r-- 2 arnold devel 13 May 4 15:43 message

228786 -rw-r--r-- 2 arnold devel 13 May 4 15:43 msg

Вывод

показывает, что номера индексов двух файлов одинаковые, а третье поле расширенного вывода теперь равно 2. Это поле показывает счетчик ссылок, указывающий, сколько имеется ссылок (элементов каталога, ссылающихся на данный индекс) на данный файл.

Нельзя не подчеркнуть: прямые ссылки все относятся к одному и тому же файлу. Если вы измените один файл, изменятся и все остальные:

$ echo "Hi, how ya doin' ?" > msg /* Изменить файл через новое имя */

$ cat message /* Показать содержание через старое имя */

Hi, how ya doin' ?

$ ls -il message msg /* Отобразить сведения. Размер изменился */

228786 -rw-r--r-- 2 arnold devel 19 May 4 15:51 message

228786 -rw-r--r-- 2 arnold devel 19 May 4 15:51 msg

Хотя мы создали две ссылки на один файл в одном каталоге, прямые ссылки не обязательно должны находиться в одном и том же каталоге; они могут находиться в любом каталоге в той же самой файловой системе. (Несколько подробнее это обсуждается в разделе 5.1.6 «Символические ссылки».)

Вдобавок, вы можете создать ссылку на файл, который вам не принадлежит, если у вас есть право записи в каталоге, в котором вы создаете ссылку. (Такой файл сохраняет все атрибуты первоначального файла: владельца, права доступа и т.д. Это потому, что это и есть оригинальный файл; просто он получил дополнительное имя.) Код уровня пользователя не может создать прямую ссылку на каталог.

После удаления ссылки создание еще одного файла с прежним именем создает новый файл:

$ rm message /* Удалить старое имя */

$ echo "What's happenin?" > message /* Повторно использовать имя */

$ ls -il msg message /* Отобразить сведения */

228794 -rw-r--r-- 1 arnold devel 17 May 4 15:58 message

228786 -rw-r--r-- 1 arnold devel 19 May 4 15:51 msg

Обратите внимание, что теперь счетчик ссылок каждого из файлов равен 1. На уровне С ссылки создаются с помощью системного вызова

link
:

#include <unistd.h> /* POSIX */

int link(const char *oldpath, const char *newpath);

При успешном создании ссылки возвращается 0, в противном случае (-1), при этом errno отражает ошибку. Важным-случаем ошибки является тот, когда

newpath
уже существует. Система не удалит его для вас, поскольку попытка сделать это может вызвать несовместимости в файловой системе.

5.1.3.1. Программа GNU link

Программа

ln
сложная и большая. Однако, GNU Coreutils содержит несложную программу
link
, которая просто вызывает
link
со своими двумя аргументами. Следующий пример показывает код из файла
link.с
, не относящиеся к делу части удалены. Номера строк относятся к действительному файлу.

20 /* Обзор реализации:

21

22 Просто вызывает системную функцию 'link' */

Поделиться с друзьями: