Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

#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
.

  • Читать дальше
  • 1
  • ...
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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