Андрей Робачевский - Операционная система UNIX
- Название:Операционная система UNIX
- Автор:
- Жанр:
- Издательство:BHV - Санкт-Петербург
- Год:1997
- Город:Санкт-Петербург
- ISBN:5-7791-0057-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Андрей Робачевский - Операционная система UNIX краткое содержание
Книга посвящена семейству операционных систем UNIX и содержит информацию о принципах организации, идеологии и архитектуре, объединяющих различные версии этой операционной системы.
В книге рассматриваются: архитектура ядра UNIX (подсистемы ввода/вывода, управления памятью и процессами, а также файловая подсистема), программный интерфейс UNIX (системные вызовы и основные библиотечные функции), пользовательская среда (командный интерпретатор shell, основные команды и утилиты) и сетевая поддержка в UNIX (протоколов семейства TCP/IP, архитектура сетевой подсистемы, программные интерфейсы сокетов и TLI).
Для широкого круга пользователей
Операционная система UNIX - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Таблица 2.12. Права доступа к области памяти
Значение аргумента prot | Описание | Права доступа к файлу |
---|---|---|
PROT_READ |
Область доступна для чтения | r |
PROT_WRITE |
Область доступна для записи | w |
PROT_EXEC |
Область доступна для исполнения | x |
PROT_NONE |
Область недоступна | - |
Обычно значение addr
задается равным 0, что позволяет операционной системе самостоятельно выбрать виртуальный адрес начала области отображения. В любом случае, при успешном завершении возвращаемое системным вызовом значение определяет действительное расположение области памяти.
Операционная система округляет значение len до следующей страницы виртуальной памяти. [19] Организация виртуальной памяти подробно рассматривается в главе 3.
Например, если размер файла 96 байтов, а размер страницы 4 Кбайт, то система все равно выделит область памяти размером 4096 байтов. При этом 96 байтов займут собственно данные файла, а остальные 4000 байтов будут заполнены нулями. Процесс может модифицировать и оставшиеся 4000 байтов, но эти изменения не отразятся на содержимом файла. При обращении к участку памяти, лежащему за пределами файла, ядро отправит процессу сигнал SIGBUS
[20] Если быть более точным, сигнал посылается процессу, когда происходит обращение к странице памяти, на которую не отображается ни один из участков файла. Таким образом, в приведенном примере сигнал процессу не будет отправлен.
. Несмотря на то что область памяти может превышать фактический размер файла, процесс не имеет возможности изменить его размер.
Использование права на исполнение ( prot = PROT_EXEC
) позволяет процессу определить собственный механизм загрузки кода. В частности, такой подход используется редактором динамических связей при загрузке динамических библиотек, когда библиотека отображается в адресное пространство процесса. Значение PROT_NONE
позволяет приложению определить собственные механизмы контроля доступа к разделяемым объектам (например, к разделяемой памяти), разрешая или запрещая доступ к области памяти.
Аргумент flags
определяет дополнительные особенности управления областью памяти. В табл. 2.13 приведены возможные типы отображения, определяемые аргументом flags
.
Таблица 2.13. Типы отображения
Значение аргумента flags | Описание |
---|---|
MAP SHARED |
Область памяти может совместно использоваться несколькими процессами |
MAP PRIVATE |
Область памяти используется только вызывающим процессом |
MAP_FIXED |
Требует выделения памяти, начиная точно с адреса addr |
MAP_NORESERVE |
He требует резервирования области свопинга |
В случае указания MAP_PRIVATE
, для процесса, определившего этот тип отображения, будет создана собственная копия страницы памяти, которую он пытается модифицировать. Заметим, что копия будет создана только при вызове операции записи, до этого остальные процессы, определившие тип отображения как MAP_SHARED
могут совместно использовать одну и ту же область памяти.
Не рекомендуется использовать флаг MAP_FIXED
, т.к. это не позволяет системе максимально эффективно распределить память. В случае отсутствия этого флага, ядро пытается выделить область памяти, начиная с адреса наиболее близкого к значению addr
. Если же значение addr
установлено равным 0, операционная система получает полную свободу в размещении области отображения.
Отображение автоматически снимается при завершении процесса. Процесс также может явно снять отображение с помощью вызова munmap(2) . Закрытие файла не приводит к снятию отображения. Следует отметить, что снятие отображения непосредственно не влияет на отображаемый файл, т. е. содержимое страниц области отображения не будет немедленно записано на диск. Обновление файла производится ядром согласно алгоритмам управления виртуальной памятью. В то же время в ряде систем существует функция msync(3C) , которая позволяет синхронизировать обновление памяти с обновлением файла на диске. [21] На самом деле msync(3C) синхронизирует обновление страниц памяти с вторичной памятью. Для областей типа MAP_SHARED вторичной памятью является сам файл на диске. Для областей типа MAP_PRIVATE вторичной памятью является область свопинга. Функция msync(3C) также позволяет принудительно обновить страницы, так что при следующем обращении к какой-либо из них ее содержимое будет загружено из вторичной памяти.
В качестве примера приведем упрощенную версию утилиты cp(1) , копирующую один файл в другой с использованием отображения файла в память.
#include
#include
#include
#include
#include
main(int argc, char *argv[]) {
int fd_src, fd_dst;
caddr_t addr_src, addr_dst;
struct stat filestat;
/* Первый аргумент - исходный файл, второй - целевой */
fd_dst=open(argv[2], O_RDWR | O_CREAT);
/* Определим размер исходного файла */
fstat(fd_src, &filestat);
/* Сделаем размер целевого файла равным исходному */
lseek(fd_dst, filestat.st_size - 1, SEEK_SET);
/* Зададим отображение */
addr_src=mmap((caddr_t)0, filestat.st_size,
PROT_READ, MAP_SHARED, fd_src, 0);
addr_dst=mmap((caddr_t)0, filestat.st_size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd_dst, 0);
/* Копируем области памяти */
memcpy(addr_dst, addr_src, filestat.st_size);
exit(0);
}
Поскольку, как обсуждалось выше, с помощью вызова mmap(2 ) нельзя изменить размер файла, это было сделано с помощью вызова lseek(2) с последующей записью одного байта так, что размер целевого файла стал равным размеру исходного. При этом в целевом файле образуется "дыра", которая, к счастью, сразу же заполняется содержимым копируемого файла.
Владение файлами
Владелец-пользователь и владелец-группа файла могут быть изменены с помощью системных вызовов chown(2) , fchown(2) и lchown(2) :
#include
#include
int chown(const char *path, uid_t owner, gid_t group);
int fchown(int fildes, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, gid_t group);
Все три вызова работают одинаково за исключением ситуации, когда адресуемый файл является символической связью. В последнем случае вызов lchown(2) действует на сам файл — символическую связь, а не на целевой файл (т.е. не следует символической связи). В функциях chown(2) и lchown(2) файл адресуется по имени, а в fchown(2) — по файловому дескриптору. Если значение owner
или group
установлено равным -1, соответствующий владелец файла не изменяется.
В версиях BSD UNIX только суперпользователь может изменить владение файлом. Это ограничение призвано, в первую очередь, не допустить "скрытие" файлов под именем другого пользователя, например, при установке квотирования ресурсов файловой системы. Владельца-группу можно изменить только для файлов, которыми вы владеете, причем им может стать одна из групп, членом которой вы являетесь. Эти же ограничения определены и стандартом POSIX.1.
Читать дальшеИнтервал:
Закладка: