алгоритм open входная информация: имя файла режим открытия права доступа (при создании файла) выходная информация: дескриптор файла { превратить имя файла в идентификатор индекса (алгоритм namei); если (файл не существует или к нему не разрешен доступ) возвратить (код ошибки); выделить для индекса запись в таблице файлов, инициали- зировать счетчик, смещение; выделить запись в таблице пользовательских дескрипторов файла, установить указатель на запись в таблице файлов; если (режим открытия подразумевает усечение файла) освободить все блоки файла (алгоритм free); снять блокировку (с индекса); /* индекс заблокирован выше, в алгоритме namei */ возвратить (пользовательский дескриптор файла); } |
Предположим, что процесс, открывая файл "/etc/passwd" дважды, один раз только для чтения и один раз только для записи, и однажды файл "local" для чтения и для записи (**), выполняет следующий набор операторов:
fd1 = open("/etc/passwd",O_RDONLY); fd2 = open("local",O_RDWR); fd3 = open("/etc/passwd",O_WRONLY);На Рисунке 5.3 показана взаимосвязь между таблицей индексов, таблицей файлов и таблицей пользовательских дескрипторов файла. Каждый вызов функции open возвращает процессу дескриптор файла, а соответствующая запись в таблице пользовательских дескрипторов файла указывает на уникальную запись в таблице файлов ядра, пусть даже один и тот же файл ("/etc/passwd") открывается дважды. Записи в таблице файлов для всех экземпляров одного и того же открытого файла указывают на одну запись в таблице индексов, хранящихся в памяти. Процесс может обращаться к файлу "/etc/passwd" с чтением или записью, но только через дескрипторы файла, имеющие значения 3 и 5 (см. Рисунок).Ядро запоминает разрешение на чтение или запись в файл в строке таблицы файлов, выделенной во время выполнения функции open. Предположим, что второй процесс выполняет следующий набор операторов:
(**) В описании вызова системной функции open содержатся три параметра (третий используется при открытии в режиме создания), но программисты обычно используют только первые два из них. Компилятор с языка Си не проверяет правильность количества параметров. В системе первые два параметра и третий (с любым "мусором", что бы ни произошло в стеке) передаются обычно ядру. Ядро не проверяет наличие третьего параметра, если только необходимость в нем не вытекает из значения второго параметра, что позволяет программистам указать только два параметра.