Системная функция dup копирует
дескриптор файла в первое
свободное место в таблице
пользовательских дескрипторов
файла, возвращая новый дескриптор
пользователю. Она действует для
всех типов файла. Синтаксис вызова
функции: где fd - дескриптор файла,
копируемый функцией, а newfd - новый
дескриптор, ссылающийся на файл.
Поскольку функция dup дублирует
дескриптор файла, она увеличивает
значение счетчика в
соответствующей записи таблицы
файлов - записи, на которую
указывают связанные с ней точки
входа в таблице файловых
дескрипторов, которых теперь стало
на одну больше. Например, обзор
структур данных, изображенных на
Рисунке 5.20, показывает, что процесс
вызывает следующую
последовательность функций: он
открывает (open) файл с именем
"/etc/passwd" (файловый дескриптор
3), затем открывает файл с именем
"local" (файловый дескриптор 4),
снова файл с именем "/etc/passwd"
(файловый дескриптор 5) и, наконец,
дублирует (dup) файловый дескриптор 3,
возвращая дескриптор 6. Возможно, dup - функция, не
отличающаяся изяществом, поскольку
она предполагает, что пользователь
знает о том, что система возвратит
свободную точку входа в таблице
пользовательских дескрипторов,
имеющую наименьший номер. Однако,
она служит важной задаче
конструирования сложных программ
из более простых конструкционных
блоков, что, в частности, имеет
место при создании конвейеров,
составленных из командных
процессоров. Рассмотрим программу,
приведенную на Рисунке 5.21.
В переменной i хранится дескриптор
файла, возвращаемый в результате
открытия файла "/etc/passwd", а в
переменной j - дескриптор файла,
возвращаемый системой в результате
дублирования дескриптора i с
помощью функции dup. В адресном
пространстве процесса оба
пользовательских дескриптора,
представленные переменными i и j,
ссылаются на одну и ту же запись в
таблице файлов и поэтому
используют одно и то же значение
смещения внутри файла. Таким
образом, первые два вызова
процессом функции read реализуют
последовательное считывание
данных, и в буферах buf1 и buf2 будут
располагаться разные данные.
Совсем другой результат
получается, когда процесс
открывает один и тот же файл дважды
и читает дважды одни и те же данные (раздел 5.2). Процесс
может освободить с помощью функции
close любой из файловых дескрипторов
по своему желанию, и ввод-вывод
получит нормальное продолжение по
другому дескриптору, как показано
на примере. В частности, процесс
может "закрыть" дескриптор
файла стандартного вывода
(файловый дескриптор 1), снять с него
копию, имеющую то же значение, и
затем рассматривать новый файл в
качестве файла стандартного
вывода. В главе 7
будет представлен более
реалистический пример
использования функций pipe и dup при
описании особенностей реализации
командного процессора. Рисунок 5.21.
Программа на языке Си,
иллюстрирующая использование
функции dup
5.13 DUР
newfd = dup(fd);
Рисунок 5.20. Структуры данных
после выполнения функции dup
#include <fcntl.h>
main()
{
int i,j;
char buf1[512],buf2[512];
i = open("/etc/passwd",O_RDONLY);
j = dup(i);
read(i,buf1,sizeof(buf1));
read(j,buf2,sizeof(buf2));
close(i);
read(j,buf2,sizeof(buf2));
}