Системное программирование в UNIX средствами Free Pascal

       

Реализация каталогов


На самом деле каталоги UNIX – не более чем файлы. Во многих аспектах система обращается с ними точно так же, как и с обычными файлами. Они имеют владельца, группу, размер и связанные с ними права доступа. Многие из системных вызовов для работы с файлами, которые были рассмотрены в предыдущих главах, могут использоваться и для работы с каталогами, хотя так делать и не рекомендуется. Например, каталоги можно открывать на чтение при помощи системного вызова open, и возвращенный этим вызовом дескриптор файла может использоваться для последующих вызовов fdread, fdseek, fstat и fdclose.

Тем не менее между каталогами и обычными файлами существуют некоторые важные различия, налагаемые системой. Каталоги не могут быть созданы при помощи системных вызовов fdcreat или fdopen. Системный вызов fdopen также не будет работать с каталогом, если установлен любой из флагов Open_WRONLY или Open_RDWR (только для записи или чтение/запись). При этом вызов вернет ошибку и запишет в переменную linuxerror код ошибки Sys_EISDIR. Эти ограничения делают невозможным изменение каталога при помощи системного вызова fdwrite. Фактически из-за особой природы каталогов для работы с ними гораздо лучше использован выделенное семейство системных вызовов, которое будет далее изучено.

Структура каталогов состоит из набора элементов каталогов, по одному элементу для каждого содержащегося в них файла или подкаталога. Каждый элемент каталога состоит, по крайней мере, из одного положительного числа, номера индексного дескриптора (inode number), и символьного поля, содержащего имя файла. Когда имена файлов были длиной не более 14 символов, элементы каталога имели фиксированную длину и большинство систем UNIX использовали один и тот же метод их реализации (исключение составлял Berkeley UNIX). Тем не менее после введения длинных имен файлов элементы каталога стали иметь различную длину, и реализация каталогов стала зависеть от файловой системы. Поэтому при разработке программ не следует полагаться на формат каталога, и для того, чтобы сделать их действительно переносимыми, необходимо использовать для работы с каталогами системные вызовы из спецификации XSI.




Часть каталога, содержащая три файла, может выглядеть примерно так, как показано на рис. 4.2. (Информация, необходимая для управления свободным пространством в файле каталога, исключена.) Этот каталог содержит имена трех файлов fred, bookmark и abc, которые могут быть и подкаталогами. Номера индексных дескрипторов для этих файлов равны соответственно 120, 207 и 235. На рис. 4.2 представлена логическая структура каталога; в действительности же каталог представляет собой непрерывный поток байтов.


120


f




r


e


d


\0






207


b


o


o


k


m


a


r


k


\0


235


a


b


c


\0






Рис. 4.2. Часть каталога

Номер индексного дескриптора однозначно идентифицирует файл (на самом деле номера индексных дескрипторов уникальны только в пределах одной файловой системы, но подробнее об этом будет рассказано ниже). Номер индексного дескриптора используется операционной системой для поиска в дисковой структуре данных структуры индексного дескриптора (inode structure), содержащей всю информацию, необходимую для обращения файлом: его размер, идентификатор владельца и группы, права доступа, время последнего доступа, последнего изменения и адреса блоков на диске, в которых хранятся данные файла. Большая часть информации, получаемой системным вызовом fstat, описанными в предыдущей главе, фактически получается напрямую из структуры индексного дескриптора. Более подробно структура индексного дескриптора будет рассмотрена в разделе 4.5.

Важно понимать, что представление каталога является только логической картиной. Просмотр содержимого каталога при помощи команды cat может завершиться выводом «мусора» на экран терминала. Более удобно исследовать каталог при помощи команды восьмеричного вывода od

с параметром -с. Например, для вывода содержимого текущей директории следует набрать в командной строке:

$ od -с .

Символ «точка» (.) в этой команде является стандартным способом задания текущего рабочего каталога.


Содержание раздела