Linux программирование в примерах
После удаления ссылки создание еще одного файла с прежним именем создает новый файл:
$ <b>rm message</b> /* Удалить старое имя */$ <b>echo "What's happenin?" > message</b> /* Повторно использовать имя */$ <b>ls -il msg message</b> /* Отобразить сведения */228794 -rw-r--r-- 1 arnold devel 17 May 4 15:58 message228786 -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 отражает ошибку. Важным-случаем ошибки является тот, когда
уже существует. Система не удалит его для вас, поскольку попытка сделать это может вызвать несовместимости в файловой системе.newpath5.1.3.1. Программа GNU link
Программа
сложная и большая. Однако, GNU Coreutils содержит несложную программуln, которая просто вызываетlinkсо своими двумя аргументами. Следующий пример показывает код из файлаlink(), не относящиеся к делу части удалены. Номера строк относятся к действительному файлу.link.с20 /* Обзор реализации:2122 Просто вызывает системную функцию 'link' */23/* ...Операторы #include для краткости опущены... */3435 /* Официальное имя этой программы (например, нет префикса 'g'). */36 #define PROGRAM_NAME "link"3738 #define AUTHORS "Michael Stone"3940 /* Имя, под которым была запущена данная программа. */41 char *program_name;4243 void44 usage(int status)45 {/* ... для краткости опущено... */62 }6364 int65 main(int argc, char **argv)66 {67 program_name = argv[0];68 setlocale(LC_ALL, "");69 bindtextdomain(PACKAGE, LOCALEDIR);70 textdomain(PACKAGE);7172 atexit(close_stdout);7374 parse_long_options(argc, argv, PROGRAM_NAME, GNU_PACKAGE,75 VERSION, AUTHORS, usage);7677 /* Вышеприведенное обрабатывает --help и --version.78 Поскольку других вызовов getopt нет, обработать здесь '--'. */79 if (1 < argc && STREQ(argv[1], "--"))80 {81 --argc;82 ++argv;83 }8485 if (argc < 3)86 {87 error(0, 0, _("too few arguments"));88 usage(EXIT_FAILURE);89 }9091 if (3 < argc)92 {93 error(0, 0, _("too many arguments"));94 usage(EXIT_FAILURE);95 }9697 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]));100101 exit(EXIT_SUCCESS);102 }Строки 67–75 являются типичным шаблоном Coreutils, устанавливающими интернациональные настройки, выход по завершении и анализ аргументов. Строки 79–95 гарантируют, что
вызывается лишь с двумя аргументами. Сам системный вызовlinkосуществляется в строке 97 (Функцияlink()обеспечивает отображение аргументов в стиле, подходящем для текущей локали; подробности сейчас несущественны.)quote_n()5.1.3.2. Точка и точка-точка
Завершая обсуждение ссылок, давайте взглянем на то, как обрабатываются специальные имена '
' и '.'. На самом деле они просто являются прямыми ссылками. В первом случае '..' является прямой ссылкой на каталог, содержащий ее, а '.' — прямой ссылкой на родительский каталог. Операционная система создает для вас эти ссылки; как упоминалось ранее, код уровня пользователя не может создать прямую ссылку на каталог. Этот пример иллюстрирует ссылки:..$ <b>pwd</b> /* Отобразить текущий каталог *//tmp$ <b>ls -ldi /tmp</b> /* Показать номер его индекса */225345 drwxrwxrwt 14 root root 4096 May 4 16:15 /tmp$ <b>mkdir x</b> /* Создать новый каталог */$ <b>ls -ldi x</b> /* И показать номер его индекса */