Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лек_1_10_Интерфейс с файловой системой.doc
Скачиваний:
1
Добавлен:
21.09.2019
Размер:
158.72 Кб
Скачать

Файлы заголовков

Использование текстовых файлов заголовков (header-файлов), которые вставляются в текст программы на языке Си с помощью директивы #include препроцессора Си, является традиционной техникой программирования на языке Си в среде ОС UNIX, обеспечивающей синтаксическую правильность использования библиотечных функций (в том числе и системных вызовов) в прикладной программе. Ранее файлы заголовков, главным образом, содержали определения типов и символических констант (символические константы - это константы, которым сопоставлены имена посредством директивы #define препроцессора Си), используемых в интерфейсах соответствующих библиотечных функций. Корректное применение файлов заголовков позволяло программистам не заботиться о правильности типов данных, используемых при обращении к библиотечным функциям и обработке их результатов.

Позже в стандарт языка Си было введено понятие прототипа функции. Грубо говоря, прототип функции - это часть ее объявления, содержащая только интерфейс (без тела функции). Наличие прототипа любой функции допускается в любом файле компиляции, даже не обязательно содержащем вызов этой функции. Однако если вызов функции содержится в файле компиляции, то набор параметров вызова должен точно соответствовать интерфейсу вызываемой функции, определенному в ее прототипе.

Для группы родственных библиотечных функций определен общий файл заголовков, содержащий необходимые определения типов данных и символических констант, а также набор прототипов этих библиотечных функций. После включения в файл компиляции такого файла заголовков на стадии компиляции будут обнаружены все синтаксические ошибки обращения к библиотечным функциям.

В последнее время файлы заголовков содержат большое количество операторов условной компиляции, относящихся большей частью к определению символических констант. Дело в том, что в зависимости от версии операционной системы (имеется в виду версии одной линии ОС UNIX, например, UNIX System V) значения констант, используемых с одним и тем же смыслом, часто меняются. Конечно, прикладная программа не должна зависеть от таких изменений. Наличие операторов условной компиляции внутри файла заголовков разрешает эту проблему.

При программировании на языке Си с использованием библиотечных функций используйте все требуемые файлы заголовков. Это поможет быстрее найти ошибки и повысит мобильность прикладной программы.

Большинство системных файлов заголовков находится в каталогах /usr/include или /usr/include/sys. Используя малознакомую функцию, обращайтесь к справочной системе man. Помимо описания формата функции, возвращаемого значения, особых ситуаций содержится указание, какие файлы заголовков следует включить в программу.

Если в директиве #include имя файла включено в угловые скобки (<>), то поиск файла будет производиться в общепринятых каталогах хранения файлов заголовков. Если же имя файла заключено в кавычки, используется явно указанное (абсолютное либо относительное) имя файла.

В ранних версиях UNIX большинство системных вызовов использовали стандартные типы для своих параметров (int, double, char и т.п.). В современных версиях часто используются т.н. производные типы (или примитивы системных данных). Производные типы переменных имеют окончание _t, большинство их определено в файле <sys/types.h>, а их назначение заключается в улучшении переносимости программ. Например:

int creat(const char*path, int mode); #устаревший вариант

int creat(const char*path, mode_t mode); #современный вариант

Этот набор системных типов гарантированно неизменен в контексте системных вызовов (и сегодня, и 10 лет спустя, и т.д.)

Как мы уже говорили (во Введении), среда программирования UNIX определяется несколькими стандартами. Стандарты ANCI C, POSIX.1 и XPG4 определяют названия и назначения файлов заголовков (40 шт). Приведем некоторые из них (те, которые наверняка потребуются в лаб. и курс. работах):

<dirent.h>

определения структур данных каталога, прототипы функций для работы с каталогами opendir(3), readdir(3) и т.д.

<errno.h>

определения кодов ошибок

<fcntl.h>

определения констант и структур данных для работы с файлами, прототипы системных вызовов для работы с файлами

<limits.h>

определения констант, определяющие различные виды ограничений: min и max значения основных типов данных, max число файловых связей, vax длина имени файла и т.п.

<stdarg.h>

определения для поддержки списков аргументов разной длины

<stddef.h>

стандартные определения (например size_t)

<stdio.h>

определения стандартной библиотеки ввода/вывода

<stdlib.h>

определения стандартной библиотеки

<unistd.h>

определения системных символьных констант, прототипы большинства системных вызовов

<utime.h>

определения структур данных и прототип системного вызова utime(2) для работы с временными характеристиками файла (временем доступа и модификации)

<sys/stat.h>

определения структур данных и прототипы системных вызовов, необходимых для получения сведений о файле

<sys/types.h>

определения примитивов системных данных (производных типов)

Еще ряд функций файловой системы (синтаксис по-прежнему в тексте лекции не приводится)

Работа со ссылками

В метаданных каждого файла хранится число связей, определяющее количество имен, которое имеет данный файл (жестких ссылок). Каждый раз, когда одно из имен удаляется, число связей уменьшается. Когда оно достигнет нуля, операционная система (ядро) позаботится об удалении данных файла (на самом деле данные в блоках не стираются, а блоки и inode помечаются свободными).

В программах жесткая связь создается с помощью системного вызова link(2).При этом будет образована новая запись каталога, ссылающаяся на метаданные уже существующего файла.

Для удаления жесткой связи служит системный вызов ulink(2). Эту функцию, например, вызывает команда rm(1) Системный вызов, явно удаляющий файл, отсутствует. (Почему? Вопрос для отличников).

ISO C предоставляет для удаления файла функцию remove(3) (прототип в <stdio.h>)., которая пригодна для любой ОС, поддерживающей ISO c, а не только для UNIX. Для удаления файлов она использует ulink(2), а для удаления каталогов – системный вызов rmdir(2), обсуждаемый ниже. Хотя технически это не системный вызов, возвращаемое значение в том же стиле: 0 в случае успеха, -1 в случае ошибки и errno при этом содержит код ошибки.

Символическая связь позволяет косвенно адресовать другой файл файловой системы. Системный вызов symlink(2) служит для этой цели (команда ls –s его использует). Функция open(2), принимая в качестве аргумента имя символической связи, на самом деле откроет целевой файл. Такая особенность называется следованием символической связи. Некоторые системные вызовы обладают этим свойством, а некоторые – нет)

Следуют:

access(2), chdir(2),chmod(2), chown(2), creat(2), exec(2), link(2), mkdir(2), open(2), stat(2)

Не следуют:

lchown(2), mknode(2), readlink(2), rename(2), lstat(2), unlink(2)

Чтобы прочитать содержимое файла-ссылки используется системный вызов readlink(2)