
- •Часть вторая. Подсистема управления файлами
- •Глава 3. Файловый ввод-вывод 2
- •Глава 4. Файлы и каталоги 21
- •Глава 5. Стандартная библиотека ввода-вывода 56
- •Глава 6. Информация о системе и файлы данных 72
- •Глава 3. Файловый ввод-вывод
- •3.1. Введение
- •3.2. Дескрипторы файлов
- •3.3. Функция open
- •3.4. Функция creat
- •3.5. Функция close
- •3.6. Функция lseek
- •3.7. Функция read
- •3.8. Функция write
- •3.9. Совместное использование файлов
- •3.10. Атомарные операции
- •3.11. Функции dup и dup2
- •3.12. Функции sync, fsync и fdatasync
- •3.13. Функция fcntl
- •3.14. Функция ioctl
- •3.15. Каталог /dev/fd
- •3.16. Выводы по главе 3
- •3.17. Упражнения по главе 3
- •Глава 4. Файлы и каталоги
- •4.1. Введение
- •4.2. Функции stat, fstat и lstat
- •4.3. Типы файлов
- •4.4. Set-user-id и set-group-id
- •4.5. Права доступа к файлу
- •4.6. Принадлежность новых файлов и каталогов
- •4.7. Функция access
- •4.8. Функция umask
- •4.9. Функции chmod и fchmod
- •4.10. Бит sticky
- •4.11. Функции chown, fchown и lchown
- •4.12. Размер файла
- •4.13. Усечение файлов
- •4.14. Файловые системы unix-подобных ос
- •4.14.1. Обзор построения файловых систем
- •4.14.2. Основные компоненты файловой системы ext2 ос Linux
- •4.14.3. Основные компоненты группы блоков
- •4.14.4. Структура индексного узла
- •4.14.5. Структура обычного файла
- •4.14.6. Структура каталогов
- •4.15. Функции link, unlink и rename
- •4.16. Символические ссылки
- •4.17. Функции symlink и readlink
- •4.18. Временные характеристики файлов
- •4.19. Функция utime
- •4.20. Функции mkdir и rmdir
- •4.21. Чтение каталогов
- •4.22. Функции chdir, fchdir, getcwd и chroot
- •4.23. Специальные файлы устройств
- •4.24. Выводы по главе 4
- •4.25. Упражнения по главе 4
- •Глава 5. Стандартная библиотека ввода-вывода
- •5.1. Введение
- •5.2. Потоки и объекты file
- •5.3. Стандартные потоки ввода, вывода и вывода сообщений об ошибках
- •5.4. Буферизация
- •5.5. Открытие и закрытие потока
- •5.6. Чтение из потока и запись в поток
- •5.6.1. Ввод-вывод символов
- •5.6.2. Построчный ввод-вывод
- •5.6.3. Ввод-вывод двоичных данных
- •5.7. Позиционирование в потоке
- •5.8. Форматированный ввод-вывод
- •5.9. Подробности реализации
- •5.10. Временные файлы
- •5.11. Выводы по главе 5
- •5.12. Упражнения по главе 5
- •Глава 6. Информация о системе и файлы данных
- •6.1. Введение
- •6.2. Файл паролей
- •6.3. Теневые пароли
- •6.4. Файл групп
- •6.5. Идентификаторы дополнительных групп
- •6.6. Прочие файлы данных
- •6.7. Учет входов в систему
- •6.8. Информация о системе
- •6.9. Функции даты и времени
- •6.10. Выводы по главе 6
- •6.11. Упражнения по главе 6
4.16. Символические ссылки
Символическая ссылка представляет собой косвенную ссылку на файл, в отличие от жесткой ссылки, которая является прямым указателем на индексный узел файла. Символические ссылки были введены с целью обхода ограничений, присущих жестким ссылкам.
Символические ссылки не имеют ограничений, связанных с файловой системой, кроме того, можно создать символическую ссылку на каталог.
Работая с функциями, которые обращаются к файлам по именам, всегда нужно знать, как функция обрабатывает символические ссылки. Если функция следует по символической ссылке, то она будет воздействовать на файл, на который указывает символическая ссылка. В противном случае операция будет производиться над самой символической ссылкой, а не над файлом, на который она указывает. В табл. 4.9 приводится перечень описываемых в этой главе функций, которые следуют по символическим ссылкам. В этом списке отсутствуют функции mkdir, mkfifo, mknod и rmdir – они возвращают признак ошибки, если им в качестве аргумента передается имя символической ссылки. Кроме того, функции, которые принимают в качестве аргумента дескриптор файла, такие как fstat и fchmod, также не были включены в этот список, поскольку в этом случае обработка символических ссылок производится функциями, возвращающими файловые дескрипторы. ОС Linux предоставляет функцию lchown для изменения владельца самих символических ссылок.
Существует одно исключение, не отмеченное в табл. 4.9, – когда функция open вызывается с одновременно установленными флагами O_CREAT и O_EXCL. Если в этом случае аргумент pathname содержит имя символической ссылки, то функция будет завершаться ошибкой с кодом EEXIST. Сделано это с целью закрытия бреши в системе безопасности и предотвращения возможности “обмана” привилегированных процессов путем подмены файлов символическими ссылками.
Таблица 4.9
Интерпретация символических ссылок различными функциями
Функция |
Не следует по ссылке |
Следует по ссылке |
access |
|
* |
chdir |
|
* |
chmod |
|
* |
chown |
|
* |
creat |
|
* |
exec |
|
* |
lchown |
* |
|
link |
|
* |
lstat |
* |
|
open |
|
* |
opendir |
|
* |
pathconf |
|
* |
readlink |
* |
|
rename |
* |
|
stat |
|
* |
truncate |
|
* |
unlink |
* |
|
С помощью символической ссылки можно создать замкнутую петлю в файловой системе. Большинство функций, анализирующих путь к файлу, обнаружив такую петлю, возвращают код ошибки ELOOP. Чтобы предотвратить зацикливание при обходе дерева каталогов, при получении информации о файле следует использовать функцию lstat, а не stat.
4.17. Функции symlink и readlink
Символические ссылки создаются с помощью функции symlink.
#include <unistd.h>
int symlink (const char *actualpath, const char *sympath);
/* возвращает 0 в случае успеха, -1 – в случае ошибки */
В каталоге создается новая запись с именем sympath, которая указывает на файл с именем actualpath. Функция не требует существования файла с именем actualpath в момент создания символической ссылки. Кроме того, не требуется, чтобы оба файла находились в одной и той же файловой системе.
Поскольку функция open следует по символическим ссылкам, нам необходим инструмент, с помощью которого можно было бы открыть саму символическую ссылку, чтобы прочитать имя файла, на который она ссылается. Эти действия выполняет функция readlink.
#include <unistd.h>
ssize_t readlink (const char *pathname, char *buf, size_t bufsize);
/* возвращает количество прочитанных байт в случае успеха, -1 – в случае ошибки */
Эта функция совмещает в себе функции open, read и close. В случае успеха она возвращает количество прочитанных байт, помещенных в области памяти, на которую указывает buf. Строка, содержащаяся в буфере buf, не завершается нулевым символом.