$ 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' */
23
/* ...Операторы #include для краткости опущены... */
34
35 /* Официальное имя этой программы (например, нет префикса 'g'). */
36 #define PROGRAM_NAME "link"
37
38 #define AUTHORS "Michael Stone"
39
40 /* Имя, под которым была запущена данная программа. */
77 /* Вышеприведенное обрабатывает --help и --version.
78 Поскольку других вызовов getopt нет, обработать здесь '--'. */
79 if (1 < argc && STREQ(argv[1], "--"))
80 {
81 --argc;
82 ++argv;
83 }
84
85 if (argc < 3)
86 {
87 error(0, 0, _("too few arguments"));
88 usage(EXIT_FAILURE);
89 }
90
91 if (3 < argc)
92 {
93 error(0, 0, _("too many arguments"));
94 usage(EXIT_FAILURE);
95 }
96
97 if (link(argv[1], argv[2]) != 0)
98 error(EXIT_FAILURE, errno, _("cannot create link %s to %s"),
99 quote_n(0, argv[2]), quote_n(1, argv[1]));
100
101 exit(EXIT_SUCCESS);
102 }
Строки 67–75 являются типичным шаблоном Coreutils, устанавливающими интернациональные настройки, выход по завершении и анализ аргументов. Строки 79–95 гарантируют, что
link
вызывается лишь с двумя аргументами. Сам системный вызов
link
осуществляется в строке 97 (Функция
quote_n
обеспечивает отображение аргументов в стиле, подходящем для текущей локали; подробности сейчас несущественны.)