Опубликован: 15.06.2004 | Доступ: свободный | Студентов: 2557 / 712 | Оценка: 4.35 / 3.96 | Длительность: 27:47:00
ISBN: 978-5-9556-0011-6
Лекция 4:

Организация файловой системы

Создать новые ссылки ( жесткие или символьные) на файл позволяют служебная программа ln:

ln  [-fs] исходный_файл целевой_файл
ln  [-fs] исходный_файл ... целевой_каталог

а также функции link() и symlink() (см. листинг 4.38).

#include <unistd.h>
int link (const char *source_path, 
          const char *target_path);
#include <unistd.h>
int symlink (const char *link_contents, 
             const char *link_name);
Листинг 4.38. Описание функций link() и symlink().

При помощи указанных утилиты и функций существующему файлу можно дать любое имя - полезная возможность, когда какая-либо программа обращается к нужному ей файлу по фиксированному имени.

Утилита ln без опций создает новые жесткие ссылки на заданные исходные файлы. В первой форме - одну ссылку с именем целевой_файл, во второй - несколько новых ссылок в существующем целевом каталоге, имена которых задаются последними компонентами маршрутных имен исходных файлов. Мобильное приложение должно считать, что исходные и целевой файлы обязаны принадлежать одной файловой системе и создать новую жесткую ссылку на каталог или символьную ссылку нельзя.

Функция link() аналогична служебной программе ln в первой форме, без опций. Ее нормальным результатом служит 0; в случае ошибки возвращается -1. Важно отметить, что с точки зрения файловой системы образование нового элемента каталога и увеличение счетчика жестких ссылок на исходный файл осуществляется функцией link() как неделимое действие.

Утилита ln с опцией -s и функция symlink() создают новые символьные ссылки. Исходные файлы не обязаны существовать; соответствующие аргументы трактуются как цепочки символов и задают содержимое ссылок.

Опция -f позволяет замещать существующие элементы каталогов новыми (по умолчанию задание существующего файла в качестве целевого считается ошибкой).

Примером смены содержимого символьной ссылки посредством служебной программы ln с опциями -s и -f может служить фрагмент действий при загрузке ОС Linux, приведенный в листинге 4.39.

if [ -n "$mver" ]; then
 ln -sf /lib/modules/$mver\
        /lib/modules/default
fi
Листинг 4.39. Использование утилиты ln для формирования содержимого символьной ссылки

Для удаления файлов служат утилиты

rm  [-fiRr] файл ...

и

rmdir  [-p] файл ...

а также функции unlink(), rmdir() и remove() (см. листинг 4.40).

#include <unistd.h>
int unlink (const char *path);
#include <unistd.h>
int rmdir (const char *path);
#include <stdio.h>
int remove (const char *path);
Листинг 4.40. Описание функций unlink(), rmdir() и remove().

Строго говоря, перечисленные утилиты и функции удаляют не файлы, а указанные ссылки на них, содержащиеся в каталогах - маршрутных префиксах, и, соответственно, уменьшают на единицу число жестких ссылок на эти файлы. файл удаляется и занятое им пространство освобождается, только если других ссылок на него не остается. Мы, однако, для краткости будем употреблять не совсем точное словосочетание " удаление файлов ".

Опишем опции утилиты rm. Опция -i означает удаление файлов с предварительным запросом подтверждения.

Опция -f предписывает не запрашивать подтверждений и не выдавать диагностических сообщений, если удаляемый файл не существует. Опция полезна, когда нет уверенности в существовании удаляемого файла и его отсутствие не является ошибкой.

Для удаления файла желательно иметь право на запись в него (обязательным является наличие права на запись в каталог, содержащий удаляемую ссылку). Если такого права нет, то утилита rm   запрашивает подтверждение.

В общем случае подтверждение на удаление запрашивается при выполнении следующего условия:

  • (не задана опция -f) И
  • (((отсутствует право на запись в файл) И
  • (стандартный ввод назначен на терминал)) ИЛИ
  • (задана опция -i)))

Наконец, две эквивалентные "сверхмощные" опции -R и -r (первая предусмотрена стандартом POSIX, вторая поддерживается по историческим причинам) позволяют удалять каталоги со всем их содержимым (если, конечно, хватает прав). Так, в процессе загрузки некоторых Unix -систем выполняется команда, которая удаляет каталог   /tmp и все содержащиеся в нем файлы и подкаталоги:

rm -rf /tmp

Разумеется, пользоваться опцией -R следует крайне осторожно, но без нее удалить каталог с помощью утилиты rm невозможно (по умолчанию удаляемый файл не может быть каталогом ). Отметим также, что rm удаляет символьные ссылки, а не указуемые файлы.

Для удаления каталогов (правда, только пустых) рекомендуется использовать служебную программу rmdir (или одноименную функцию). Опция -p предписывает удалять всю цепочку каталогов, составляющих заданное маршрутное имя. Например, если в текущем каталоге есть подкаталог a, содержащий только пустой подкаталог b, то команда, показанная в листинге 4.41, удалит и b, и a.

rm -p a/b
Листинг 4.41. Пример команды удаления цепочки каталогов.

Функция unlink() предназначена для удаления файлов, не являющихся каталогами, а функция remove(), имеющая в стандарте C99 [5], объединяет возможности функций rmdir() и unlink().

В листинге 4.42 приведен пример программы, которая с помощью функций link() и unlink() осуществляет ответственную обработку файлов с сохранением копии текущей версии.

#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/stat.h>
/* Программа выполняет обработку */
/* с осторожным замещением       */
/* основного файла рабочим       */
#define MAIN_FILE "/home/galat/garb/temp/mfile"
#define OLD_FILE  "/home/galat/garb/temp/ofile"
#define WORK_FILE "/home/galat/garb/temp/wfile"
int main (void) {
 /* Необходимые описания */
 /* . . .                */
 int work_success = 1;

 /* Выполнение операций над рабочим файлом */
 /* . . .                                  */

 /* В случае неудачи выдадим диагностическое сообщение и удалим рабочий файл */
 if (! work_success) {
   fprintf (stderr, "\nНеудачное завершение операций над рабочим файлом %s\n", WORK_FILE);
   unlink (WORK_FILE);
   return (-1);
 }

 /* Установим режим доступа к рабочему файлу,  */
 /* подходящие для последующего использования  */
 /* Пусть, например, это будет доступ для всех */
 /* только на чтение                           */
 chmod (WORK_FILE, S_IRUSR | S_IRGRP | S_IROTH);

 /* Удалим ранее сохраненную старую версию основного файла */
 unlink (OLD_FILE);

 /* Сохраним текущую версию основного файла */
 if (link (MAIN_FILE, OLD_FILE)) {
   perror ("Не удалось сохранить текущую версию основного файла");
   return (-1);
 }

 /* Удалим текущую версию основного файла */
 unlink (MAIN_FILE);

 /* Сделаем рабочий файл основным */
 if (link (WORK_FILE, MAIN_FILE)) {
   perror ("Не удалось сделать рабочий файл основным");
   /* Восстановим основной файл */
   link (OLD_FILE, MAIN_FILE);
   return (-1);
 }

 /* Удалим рабочий файл */
 unlink (WORK_FILE);

 return 0;
}
Листинг 4.42. Пример программы, использующей функции link() и unlink().
Антон Коновалов
Антон Коновалов

В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13
Планируется ли актуализация материалов данного очень полезного курса?