Операционная система UNIX
if (nread < 0) {perror("readlink");exit(1);}/* readlink не завершает строку '\0' */printf("Символическая связь:\n %s\n", buf);/* Теперь прочитаем содержимое целевого файла */printf("Читаем целевой файл\n");fd = open(argv[1], O_RDONLY);if (fd < 0) {perror("open");exit(2);}nread = read(fd, buf, BUFSIZ);if (nread < 0) {perror("read");exit(3);}buf[nread] = '\0';printf("Целевой файл:\n %s\n", buf);close(fd);exit(0);}Перед тем как запустить программу, создадим символическую связь с файлом unix0.txt:
$ <b>ln -s unix0.txt symlink.txt</b>$ <b>ls -l</b>lrwxrwxrwx 1 andy user 10 Jan 6 09:54 symlink.txt -> unix0.txt-rw-r--r-- 1 andy user 498 Jan 6 09:53 unix0.txt$ <b>a.out symlink.txt</b>Читаем символическую связьСимволическая связь:unix0.txtЧитаем целевой файлЦелевой файл:Начиная с 1975 года фирма AT&T начала предоставлять лицензии наиспользование операционной системы как научно-образовательнымучреждениям, так и коммерческим организациям. Поскольку основнаячасть системы поставлялась в исходных текстах, написанных наязыке С, опытным программистам не требовалось детальнойдокументации, чтобы разобраться в архитектуре UNIX. С ростомпопулярности микропроцессоров...Файлы, отображаемые в памяти
Системный вызов mmap(2) предоставляет механизм доступа к файлам, альтернативный вызовам read(2) и write(2). С помощью этого вызова процесс имеет возможность отобразить участки файла в собственное адресное пространство. После этого данные файла могут быть получены или записаны путем чтения или записи в память. Функция mmap(2) определяется следующим образом:
#include <sys/types.h>#include <sys/mman.h>caddr_t mmap(caddr_t addr, size_t len, int prot,int flags, int fildes, off_t off);Этот вызов задает отображение
байтов файла с дескрипторомlen, начиная со смещенияfildes, в область памяти со стартовым адресомoff. Разумеется, перед вызовом mmap(2) файл должен быть открыт с помощью функции open(2). Аргументaddrопределяет права доступа к области памяти, которые должны соответствовать правам доступа к файлу, указанным в системном вызове open(2). В табл. 2.12 приведены возможные значения аргумента prot и соответствующие им права доступа к файлу. Возможно логическое объединение отдельных значенийprot. Так значениеprotсоответствует доступуPROT_READ | PROT_WRITEк файлу.O_RDWRТаблица 2.12. Права доступа к области памяти
Значение аргумента prot Описание Права доступа к файлу PROT_READОбласть доступна для чтения r PROT_WRITEОбласть доступна для записи w PROT_EXECОбласть доступна для исполнения x PROT_NONEОбласть недоступна - Обычно значение
задается равным 0, что позволяет операционной системе самостоятельно выбрать виртуальный адрес начала области отображения. В любом случае, при успешном завершении возвращаемое системным вызовом значение определяет действительное расположение области памяти.addrОперационная система округляет значение len до следующей страницы виртуальной памяти. [19] Например, если размер файла 96 байтов, а размер страницы 4 Кбайт, то система все равно выделит область памяти размером 4096 байтов. При этом 96 байтов займут собственно данные файла, а остальные 4000 байтов будут заполнены нулями. Процесс может модифицировать и оставшиеся 4000 байтов, но эти изменения не отразятся на содержимом файла. При обращении к участку памяти, лежащему за пределами файла, ядро отправит процессу сигнал
[20]. Несмотря на то что область памяти может превышать фактический размер файла, процесс не имеет возможности изменить его размер.SIGBUSИспользование права на исполнение (
) позволяет процессу определить собственный механизм загрузки кода. В частности, такой подход используется редактором динамических связей при загрузке динамических библиотек, когда библиотека отображается в адресное пространство процесса. Значениеprot = PROT_EXECпозволяет приложению определить собственные механизмы контроля доступа к разделяемым объектам (например, к разделяемой памяти), разрешая или запрещая доступ к области памяти.PROT_NONEАргумент
определяет дополнительные особенности управления областью памяти. В табл. 2.13 приведены возможные типы отображения, определяемые аргументомflags.flags