Материал: 6262

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

16

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

Стандартизованы средства порождения и завершения процессов, смены их программ, опроса и/или изменения разнообразных характеристик. Процессы можно приостанавливать и активизировать в заданное время.

Необходимая степень детерминизма выполнения приложений достигается благодаря средствам поддержки реального времени, к которым относятся управление дисциплиной выделения процессоров, сигналы реального времени, удержание страниц в оперативной памяти, таймеры высокого разрешения и другие.

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

Механизм блокировки фрагментов файлов позволяет обеспечить атомарность транзакций.

Асинхронный ввод/вывод дает возможность совмещать операции обмена, оптимизируя тем самым приложения.

С помощью множества служебных программ можно относительно легко организовать сложную обработку данных.

Тщательно проработаны вопросы доступа к внешним устройствам, которые подсоедины по последовательным линиям, особенно к терминалам.

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

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

Служебные программы образуют развитую среду выполнения для shell-процедур. Фоновый режим выполнения программ позволяет организовать одновременное выполнение нескольких программ и взаимодействие с ними.

Стандарт POSIX стандартизует интерфейс командной строки. Вероятно, в будущих версиях стандарта будет регламентирован графический интерфейс.

Для многопользовательских систем, POSIX регламентирует различные средства

непосредственного и почтового обмена информацией.

Стандарт POSIX - обязательный элемент современной дисциплины разработки прикладных систем.

17

1.2 Системные операции для работы с файловой системой

Рассмотрев основные понятия и требования стандарта POSIX, можно перейти к непосредственному обсуждению системных вызовов ОС, по управлению файлами и файловыми системами.

Замечание

Изучение данного вопроса предполагает, что студент усвоил и повторил учебный материал темы 4 «Управление файловыми системами ОС» [4].

Теперь перейдем к изучению основных системных вызовов, разделенных на две группы, список которых приведен на рисунке 1.5:

управление файлами;

управление каталогами и файловыми системами.

Изучение назначения и возможностей этих функций является предметом изучения данной темы.

Рисунок 1.5 — Системные функции подсистемы ввода-вывода

Замечание

Отметим, что наряду с низкоуровневыми системными вызовами, приведенными на рисунке 1.5, для работы с файлами и файловыми системами используются более высокоуровневые функции, которые обеспечивают буферизованный ввод-вывод и подробно изложены в любом учебнике по языку С. Считается, что студент студент уже имеет опыт работы с ними и, при необходимости, использует учебник [5] как справочное пособие.

18

В данном подразделе будут изучены только первые шесть функций, которые касаются непосредственно управления файлами.

Замечание

При изучении системных функций следует помнить, что все приводимые примеры и ограничения привязаны к архитектуре ОС УПК АСУ.

Все системные функции ввода-вывода используют целочисленное значение дескриптора файла. Это значение формируется в ядре ОС и индивидуально привязывается к конкретному процессу.

Нумерация значений дескрипторов для каждого процесса начинается с нуля и определяется в момент открытия файлов, из условия минимального значения доступного (незанятого) дескриптора.

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

Все остальные системные функции, кроме функции stat(...), используют уже открытый дескриптор файла.

Замечание

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

1.2.1 Системные вызовы open() и close()

Системный вызов open(...) открывает некоторый файл и, в случае успешного завершения, возвращает целочисленный номер дескриптора.

Общий формат вызова имеет вид:

#include <sys/types.h>

#include <sys/stat.h> #include <fcntl.h>

int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

Допускается использование следующих аргументов:

pathname — строковый указатель на имя файла, заданного в соответсвии с требованиями конкретной ОС;

flags — целочисленное значение, определяющее режимы открытия файла, которые обычно задаются конкатенацией битовых масок:

O_APPEND — добавление информации в конец файла;

O_CREAT — создание файла, если он отсутсвует;

O_RDONLY — только для чтения из файла;

O_WRONLY — только для записи в файл;

19

O_RDWR — для чтения и записи в файл;

O_TMPFILE — после закрытия файл будет удален, а также многие другие.

mode — целочисленное значение, определяющее режимы доступа к файлу, как это было описано в теме 4, например, восьмеричное значение 0666 разрешает доступ на чтение и запись всем пользователям.

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

Замечание

Функция open(...) содержит множество режимов открытия файлов, которые могут быть несовместимы друг с другом, а также множество вариантов сообщений об ошибках, поэтому для полного ее изучения следует пользоваться действующим руководством ОС, например, используя команду: man 2 open

Системный вызов close(...) закрывает открытый файл и освобождает номер дескриптора для последующего использования. Формат этого системного вызова имеет вид:

#include <unistd.h> int close(int fd);

Вслучае успешного завершения вызова, возвращается целочисленное значение 0.

Вслучае ошибки — целочисленное значение -1, а переменная errno содержит код ошибки:

EBADF — аргумент функции не является правильным дескриптором файла;

EINTR — закрытие файла было прервано сигналом;

EIO — общая ошибка ввода-вывода.

Замечание

Несмотря на кажущуюся простоту, системный вызов close(...) выполняет очень важ-ные функции:

он универсален, поскольку применим ко всем видам файлов;

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

неявно вызывается ядром ОС, когда процесс завершает свою работу.

20

1.2.2 Системные вызовы read() и write()

Системный вызов read(...) читает заданное число байт из файла, определенного его дескриптором.

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

Общий формат вызова имеет вид:

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

Для вызова этой функции используется три аргумента:

fd — целочисленный номер дескриптора открытого файла;

buf — указатель на внешний буфер, в который записываюся читаемые байты;

count — количество байт запрашиваемых для чтения из файла.

Функция read(...) читает байты с текущей позиции файла:

если смещение текущей позиции равно или больше размера файла, то возвращается значение 0;

если данные недоступны, но конец файла не достигнут, то ожидается поступление данных, что в общем случае определяется режимом открытия файла;

в случае ошибки чтения, возвращается значение -1 и необходимо анализировать переменную errno;

если размер параметра count превышает значение константы SSIZE_MAX, то результат выполнения операции не специфицирован.

Замечание

При использовании функции read(...) необходимо анализировать системные ограничения конкретной ОС: максимальный размер выделяемого буфера для записи читаемых данных и максимальное число читаемых данных за одну операци. Например, для ОС УПК АСУ:

тип ssize_t определяет целое число размерности 8 байт;

BUFSIZ — размер выделяемого по умолчанию буфера равен 4096 байт;

SSIZE_MAX — соответствует максимальному значению 64-битного целого.

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

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

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

Источник: https://studfile.net/preview/16438530/