В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13 |
Организация файловой системы
Создать новые ссылки ( жесткие или символьные) на файл позволяют служебная программа 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().