Скачиваний:
56
Добавлен:
08.01.2014
Размер:
2.6 Mб
Скачать

1.1.2. Владелец файла и права доступа

Файл характеризуется не только содержащимися в нем данными: существует еще ряд других простых атрибутов, связанных с каждым файлом UNIX. Например, для каждого файла задан определенный пользователь – владелец файла (file owner). Владелец файла обладает определенными правами, в том числе возможностью изменять права доступа (permissions) к файлу. Как показано в главе 3, права доступа определяют, кто из пользователей может читать или записывать информацию в файл либо запускать его на выполнение, если файл является программой.

1.1.3. Обобщение концепции файла

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

$ cat file > /dev/rmt0

представляет грубый способ записи файла на магнитную ленту (путь /dev/rmt0 обычно обозначает стример).

1.2. Процесс

В терминологии UNIX термин процесс (process) обычно обозначает экземпляр выполняющейся программы. Простейший способ создания процесса - передать команду для исполнения оболочке (shell), которая также называется командным интерпретатором (command processor). Например, если пользователь напечатает:

$ ls

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

1.2.1. Межпроцессное взаимодействие

Система UNIX позволяет процессам, выполняемым одновременно, взаимодействовать друг с другом, используя ряд методов межпроцессного взаимодействия.

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

$ ls | wc -l

организует конвейер из двух процессов, в одном из которых будет выполняться программа ls, а в другом – одновременно программа подсчета числа слов wc. При этом выход ls будет связан с входом wc. В результате будет выведено число файлов в текущем каталоге.

Другими средствами межпроцессного взаимодействия UNIX являются сигналы (signals), которые обеспечивают модель взаимодействия по принципу программных прерываний. Дополнительные средства предоставляют семафоры (semaphores) и разделяемая память (shared memory). Для обмена между процессами одной системы могут также использоваться сокеты (sockets), используемые обычно для взаимодействия между процессами в сети.

1.3. Системные вызовы и библиотечные подпрограммы

В предисловии уже упомянули, что книга сконцентрирована на интерфейсе системных вызовов (system call interface). Тем не менее понятие системного вызова требует дополнительного определения.

Системные вызовы фактически дают разработчику программного обеспечения доступ к ядру (kernel). Ядро, с которым познакомились в предисловии, – это блок кода, который постоянно находится в памяти и занимается планированием системных процессов UNIX и управлением вводом/выводом. По существу ядро является частью UNIX, которое и делает ее операционной системой. Все управление, выделение ресурсов и контроль над пользовательскими процессами, а также весь доступ к файловой системе осуществляется через ядро.

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

read(fileptr, inputbuf);

или при помощи низкоуровневого системного вызова fdread:

nread := fdread(filedes, inputbuf, BUFSIZE);

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

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

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

Код программы

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

Библиотечная процедура read

Пользовательский код для fdread

Адресное пространство ядра (системные ресурсы)

Код ядра для вызова fdread

Рис. 1.2. Связь между кодом программы, библиотечной подпрограммой и системным вызовом

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

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

Кроме интерфейса системных вызовов, системы UNIX также предоставляют обширную библиотеку стандартных процедур, одним из важных примеров которых является Стандартная библиотека ввода/вывода (Standard I/O Library). Подпрограммы этой библиотеки обеспечивают средства преобразования форматов данных и автоматическую буферизацию, которые отсутствуют в системных вызовах доступа к файлам. Хотя процедуры стандартной библиотеки ввода/вывода гарантируют эффективность, они сами, в конечном счете, используют интерфейс системных вызовов. Их можно представить, как дополнительный уровень средств доступа к файлам, основанный на системных примитивах доступа к файлам, а не отдельную подсистему. Таким образом, любой процесс, взаимодействующий со своим окружением, каким бы незначительным не было это взаимодействие, должен использовать системные вызовы.

На рис. 1.2 показана связь между кодом программы и библиотечной процедурой, а также связь между библиотечной процедурой и системным вызовом. Из рисунка видно, что библиотечная процедура read в конечном итоге является интерфейсом к лежащему в его основе системному вызову fdread.

Упражнение 1.1. Объясните значение следующих терминов: ядро, системный вызов, подпрограмма Pascal, процесс, каталог, путь.

Соседние файлы в папке Полищук, Семериков. Системное программирование в UNIX средствами Free Pascal