Чтение онлайн

на главную - закладки

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

Буфер, на который указывает

buf
, наполняется содержимым символической ссылки
pathname
до тех пор, пока хватает длины
buf
, указанной в
bufsize
в байтах. Обычно константы
PATH_MAX
применяется в качестве размера буфера, поскольку она должна быть достаточно большой, чтобы уместить содержимое любой символической ссылки [49] . Одна странность функции
readlink
связана с тем, что она не завершает строку, которую записывает в
buf
, символом
'\0'
, поэтому
buf
не содержит корректную строку С, даже если
readlink
выполняется успешно. Вместо этого она возвращает количество байт, записанных в
buf
в случае успеха и
– 1
— при неудаче. Из-за этой особенности код, использующий
readlink
, часто выглядит так, как показано ниже.

49

Хотя не гарантировано, что

PATH_MAX
будет достаточно велик, но для большинства практических целей она подходит. Если вы имеете дело с патологическими случаями, то должны вызывать
readlink
последовательно, увеличивая буфер, до тех пор, пока
readlink
не вернет значение меньше чем
bufsiz
.

char buf[PATH_MAX + 1];

int bytes;

if ( (bytes = readlink (pathname, buf, sizeof (buf) - 1)) < 0) {

 perror("ошибка в readlink");

} else {

 buf[bytes]= '\0';

}

11.4.4. Удаление файлов

Удаление файла — это удаление указателя на его inode и удаление содержимого файла, если не остается ни одой жесткой ссылки на него. Если любой процесс держит файл открытым, то inode этого файла предохраняется до тех пор, пока финальный процесс не закроет его, после чего и inode, и содержимое файла уничтожаются. Поскольку нет способа принудительно удалить файл немедленно, эта операция называется разъединением (unlinking) файла, поскольку она удаляет связь между именем файла и inode.

#include <unistd.h>

int unlink(char *pathname);

11.4.5. Переименование файлов

Имя файла может быть изменено на любое другое до тех пор, пока оба имени относятся к одному и тому же физическому носителю (это то же ограничение, что и касается создания жестких ссылок). Если новое имя уже ссылается на файл, то такое имя разъединяется перед тем, как произойдет переименование. Атомарность системного вызова

rename
гарантируется. Другие процессы в системе всегда видят существование файла под тем или иным именем, но не под обеими сразу. Поскольку открытые файлы не связаны с именами (а только с inode), то переименование файла, который открыт в других процессах, никак не влияет на их работу. Ниже показано, как выглядит системный вызов для переименования файлов.

#include <unistd.h>

int rename(const char *oldpath, const char *newpath);

После вызова файл, на который ссылалось имя

oldpath
, получает ссылку
newpath
вместо
oldpath
.

11.5. Манипуляции файловыми дескрипторами

Почти все связанные с файлами системные вызовы, о которых мы говорили, за исключением

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

#include <unistd.h>

int fcntl (int fd, int command, long arg);

Для

многих команд
arg
не используется. Ниже мы обсудим большую часть применений
fcntl
. Этот вызов используется для блокировки файлов, аренды файлов, неблокирующего ввода-вывода, который рассматривается в главе 13, а также уведомления об изменениях каталогов, представленного в главе 14.

11.5.1. Изменение режима доступа к открытому файлу

Режим добавления (указываемый флагом

O_APPEND
при открытии файла) и неблокирующий режим (флаг
O_NONBLOCK
), могут быть включены и отключены уже после того, как файл был открыт, с помощью команды
F_SETFL
в
fcntl
. Параметр
arg
при этом должен содержать флаги, которые нужно установить — если какой-то из флагов не указан для
fd
, он отключается.

F_GETFL
можно использовать для запроса текущих установленных флагов файла. Это возвращает все флаги, включая режим чтения/записи для открытого файла.
F_SETFL
позволяет только устанавливать упомянутые выше флаги — любые другие флаги, представленные в аргументе
arg
, игнорируются.

fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_RDONLY);

Такой вызов абсолютно правильный, но он не делает ничего. Включение режима добавления для открытого файлового дескриптора выглядит так, как показано ниже.

fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_APPEND);

Следует отметить, что это предохраняет установку

O_NONBLOCK
. Отключение режима добавления выглядит похоже.

fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_APPEND);

11.5.2. Модификация флага "закрыть при выполнении"

Во время системного вызова

exec
дескрипторы файлов обычно остаются открытыми для использования в новых программах. В некоторых случаях может потребоваться, чтобы файлы закрывались, когда вызывается
exec
. Вместо закрытия их вручную вы можете попросить систему закрыть соответствующий файловый дескриптор при вызове
exec
с помощью команд
F_GETFD
и
F_SETFD
в
fcntl
. Если флаг "закрыть при выполнении" (close-on-exec) установлен, когда применяется
F_GETFD
, возвращается ненулевое значение, в противном случае возвращается ноль. Флаг "закрыть при выполнении" устанавливается командой
F_SETFD
; он отключается, если
arg
равно 0, в противном случае он включается.

Ниже показано, как можно заставить

fd
закрываться, когда процесс вызывает
exec
.

fcntl(fd, F_SETFD, 1);

11.5.3. Дублирование файловых дескрипторов

Иногда процессам требуется создать новый файловый дескриптор, который ссылается на ранее открытый файл. Командные оболочки используют эту функциональность для перенаправления стандартного ввода, вывода и потока ошибок по запросу пользователя. Если процессу не важно, какой файловый дескриптор будет использован для новой ссылки, он должен использовать

dup
.

#include <unistd.h>

int dup(int oldfd);

dup
возвращает файловый дескриптор, который ссылается на тот же inode, что и
oldfd
, или
– 1
в случае ошибки,
oldfd
остается корректным дескриптором, по-прежнему ссылающимся на исходный файл. Новый файловый дескриптор — это всегда наименьший доступный файловый дескриптор. Если процессу нужно получить новый файловый дескриптор с определенным значением (например,
0
, чтобы перенаправить стандартный ввод), то он должен использовать
dup2
.

Поделиться:
Популярные книги

Ретроградный меркурий

Рам Янка
4. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ретроградный меркурий

Я еще не барон

Дрейк Сириус
1. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще не барон

Полковник Империи

Ланцов Михаил Алексеевич
3. Безумный Макс
Фантастика:
альтернативная история
6.58
рейтинг книги
Полковник Империи

Бремя империи

Афанасьев Александр
Бремя империи - 1.
Фантастика:
альтернативная история
9.34
рейтинг книги
Бремя империи

Инферно

Кретов Владимир Владимирович
2. Легенда
Фантастика:
фэнтези
8.57
рейтинг книги
Инферно

Адмирал южных морей

Каменистый Артем
4. Девятый
Фантастика:
фэнтези
8.96
рейтинг книги
Адмирал южных морей

Защитник

Астахов Евгений Евгеньевич
7. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Защитник

Я – Орк. Том 3

Лисицин Евгений
3. Я — Орк
Фантастика:
юмористическое фэнтези
попаданцы
5.00
рейтинг книги
Я – Орк. Том 3

Мир-о-творец

Ланцов Михаил Алексеевич
8. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Мир-о-творец

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Я – Орк. Том 4

Лисицин Евгений
4. Я — Орк
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я – Орк. Том 4

Хозяйка лавандовой долины

Скор Элен
2. Хозяйка своей судьбы
Любовные романы:
любовно-фантастические романы
6.25
рейтинг книги
Хозяйка лавандовой долины

Разбуди меня

Рам Янка
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Разбуди меня

Курсант: назад в СССР 9

Дамиров Рафаэль
9. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: назад в СССР 9