Это может быть серьезным ограничением. Многие системные службы запускаются как
Для решения этой проблемы System III предложила идею о FIFO.
Рассмотрите спулер печати. Демон спулера управляет физическими принтерами, создавая задания для печати и печатая по одному заданию за раз. Для добавления в очередь задания программное обеспечение принтера на уровне пользователя должно сообщаться с демоном спулера. Одним способом для осуществления этого является создание спулером FIFO с хорошо известным именем файла. Программа пользователя может затем открыть FIFO, записать в него запрос и снова закрыть. Спулер находится в цикле, читая запросы из FIFO и обрабатывая их.
Функция mkfifo() создает файлы FIFO:
#include
#include
int mkfifo(const char *pathname, mode_t mode);
Аргумент pathname
является именем создаваемого FIFO, a mode
является данными ему правами доступа, аналогичными второму аргументу функции creat()
или третьему аргументу функции open()
(см. раздел 4.6 «Создание файлов»). Файлы FIFO удаляются, как любые другие, с помощью remove()
или unlink()
(см. раздел 5.1.5.1 «Удаление открытых файлов»).
Справочная страница GNU/Linux
Команда mkfifo
доставляет этот системный вызов на командный уровень. Это упрощает показ файла FIFO в действии:
$ mkfifo afifo /* Создание файла FIFO */
$ ls -l afifo
/* Показать тип и права доступа, обратите внимание на 'p' впереди */
prw-r--r-- 1 arnold devel 0 Oct 23 15:49 afifo
$ cat < afifo & /* Запустить читателя в фоновом режиме */
[1] 22100
$ echo It was a Blustery Day > afifo /* Послать данные в FIFO */
$ It was a Blustery Day /* Приглашение оболочки, cat выводит данные */
/* Нажмите ENTER, чтобы увидеть статус завершения задания */
[1]+ Done cat
9.4. Управление дескрипторами файлов
На данный момент части загадки почти полностью составлены, fork()
и exec()
создают процессы и запускают в них программы, pipe()
создает канал, который может использоваться для IPC. Чего до сих пор не хватает, так это способа помещения дескрипторов канала на место стандартных ввода и вывода для производителя и потребителя канала.
Системные вызовы dup()
и dup2()
, совместно с close()
дают вам возможность поместить (скопировать) открытый дескриптор файла на другой номер. Системный вызов fcntl()
дает вам возможность то же самое и управлять несколькими важными атрибутами открытых файлов.
9.4.1. Дублирование открытых файлов: dup()
и dup2()
Два системных вызова создают копию открытого дескриптора файла:
#include
int dup(int oldfd);
int dup2(int oldfd, int newfd);
Функции следующие:
int dup(int oldfd)
Возвращает наименьшее значение неиспользуемого дескриптора файла; это копия oldfd
. dup()
возвращает неотрицательное целое в случае успеха и -1 при неудаче.
int dup2(int oldfd, int newfd)
Делает newfd
копией oldfd
; если newfd
открыт, он сначала закрывается, как при использовании close()
. dup2()
возвращает новый дескриптор или -1, если была проблема. Помните рис. 9.1, в котором два процесса разделяли общие указатели на один и тот же элемент файла в таблице файлов ядра? dup()
и dup2()
создают ту же ситуацию внутри одного процесса. См. рис. 9.4.
Рис. 9.4. Разделение дескриптора файла как результат 'dup2(1, 3)
'