void * mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *start, size_t length);
#endif
ОПИСАНИЕ
Функция
mmap
отражает
length
байтов, начиная со смещения
offset
файла (или другого объекта), определенного файловым описателем
fd,
в память, начиная с адреса
start.
Последний параметр (адрес) необязателен, и обычно бывает равен 0.
Настоящее местоположение отраженных данных возвращается самой
функцией
mmap,
и никогда не бывает равным 0.
Аргумент
prot
описывает желаемый режим защиты памяти (он не должен конфликтовать
с режимом открытия файла).
Оно является либо
PROT_NONE
либо побитовым ИЛИ одного или нескольких флагов PROT_*.
PROT_EXEC
(данные в страницах могут исполняться);
PROT_READ
(данные можно читать);
PROT_WRITE
(в эту область можно записывать информацию);
PROT_NONE
(доступ к этой области памяти запрещен).
Параметр
flags
задает тип отражаемого объекта, опции отражения и указывает, принадлежат ли
отраженные данные только этому процессу или их могут читать другие. Он состоит
из комбинации следующих битов:
MAP_FIXED
Не использовать другой адрес, если адрес задан в параметрах функции.
Если заданный адрес не может быть использован, то функция
mmap
вернет сообщение об ошибке. Если используется MAP_FIXED, то
start
должен быть пропорционален размеру страницы. Использование этой опции
не рекомендуется.
MAP_SHARED
Разделить использование этого отражения с другими процессами,
отражающими тот же объект. Запись информации в эту область памяти будет
эквивалентна записи в файл. Файл может не обновляться до вызова
функций
msync(2)
или
munmap(2).
MAP_PRIVATE
Создать неразделяемое отражение с механизмом copy-on-write.
Запись в эту область памяти не влияет на файл.
Не определено, являются или нет изменения в файле после вызова
mmap
видимыми в отраженном диапазоне.
Вы должны задать либо MAP_SHARED, либо MAP_PRIVATE.
Эти три флага описаны в POSIX.1b (бывшем POSIX.4) and SUSv2.
В Linux также анализируются следующие нестандартные флаги:
MAP_DENYWRITE
Этот флаг игнорируется.
(Раньше он обозначал, что попытки записи в подчиненные файлы должны
завершаться с кодом ошибки ETXTBUSY. Но это стало основой для
атак типа 'отказ-в-доступе' - 'denial-of-service'.)
MAP_EXECUTABLE
Этот флаг игнорируется.
MAP_NORESERVE
(Используется вместе с MAP_PRIVATE.) Не выделяет страницы
пространства подкачки для этого отображения.
Если пространство подкачки выделяется, то это частное пространство
копирования-при-записи может быть изменено.
Если оно не выделено, то можно получить SIGSEGV при записи
и отсутствии доступной памяти.
MAP_LOCKED
(Linux 2.5.37 и выше) Блокировать страницу или размеченную область
в памяти так, как это делает
mlock().
Этот флаг игнорируется в старых ядрах.
MAP_GROWSDOWN
Используется для стеков. Для VM системы ядра обозначает, что отображение
должно распространяться вниз по памяти.
MAP_ANONYMOUS
Отображение не резервируется ни в каком файле; аргументы
fd
и
offset
игнорируются. Этот флаг вместе с MAP_SHARED реализован с Linux 2.4.
MAP_ANON
Псевдоним для MAP_ANONYMOUS. Не используется.
MAP_FILE
Флаг совместимости. Игнорируется.
MAP_32BIT
Поместить размещение в первые 2Гб адресного рпостранства процесса.
Игнорируется, если указано
MAP_FIXED.
Этот флаг сейчас поддерживается только на x86-64 для 64-битных программ.
Некоторые системы документируют дополнительные флаги
MAP_AUTOGROW, MAP_AUTORESRV, MAP_COPY и MAP_LOCAL.
fd
должно быть корректным описателем файла, если только не установлено
MAP_ANONYMOUS, так как в этом случае аргумент игнорируется.
offset
должен быть пропорционален размеру страницы, получаемому
при помощи функции
getpagesize(2).
Memory mapped by
mmap
is preserved across
fork(2),
with the same attributes.
A file is mapped in multiples of the page size. For a file that is not
a multiple of the page size, the remaining memory is zeroed when mapped,
and writes to that region are not written out to the file. The effect of
changing the size of the underlying file of a mapping on the pages that
correspond to added or removed regions of the file is unspecified.
Системный вызов
munmap
удаляет все отражения из заданной области памяти, после чего все
ссылки на данную область будут вызывать ошибку "неправильное обращение
к памяти" (invalid memory reference). Отражение удаляется автоматически
при завершении процесса. С другой стороны, закрытие файла не приведет
к снятию отражения.
Адрес
start
должно быть кратен размеру страницы. Все страницы, содержащие часть
указанного диапазона, не отображены, и последующие ссылки на эти
страницы будут генерировать SIGSEGV. Это не будет являться ошибкой,
если указанный диапазон не содержит отображенных страниц.
Для отображений 'файл-бэкэнд' поле
st_atime
отображаемого файла может быть обновлено в любой момент между
mmap()
и соответствующим снятием отображения; первое обращение к отображенной
странице обновит поле, если оно до этого уже не было обновлено.
Поля
st_ctime
и
st_mtime
файла, отображенного по PROT_WRITE и MAP_SHARED, будут обновлены
после записи в отображенний диапазон, и до вызова последующего
msync()
с флагом MS_SYNC или MS_ASYNC, если такой случится.
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
При удачном выполнении
mmap
возвращает указатель на область с отраженными данными.
При ошибке возвращается значение MAP_FAILED (-1), а переменная
errno
приобретает соответствующее значение.
При удачном выполнении
munmap
возвращаемое значение равно нулю. При ошибке возвращается
-1, а переменная
errno
приобретает соответствующее значение. (Вероятнее всего,
это будет EINVAL).
ЗАМЕЧАНИЯ
Будет содержаться
PROT_EXEC
в
PROT_READ
или нет - зависит от архитектуры.
Портируемые прогарммы должны всегда устанавливать
PROT_EXEC
если они намерены исполлнить код в новом распределении.
НАЙДЕННЫЕ ОШИБКИ
EBADF
fd
не является правильным файловым описателем (и не задано MAP_ANONYMOUS).
EACCES
Описатель файла ссылается на не обычный файл.
Или была запрошена опция MAP_PRIVATE, но
fd
не открыт для чтения. Или была запрошена опция MAP_SHARED с
установленным битом PROT_WRITE, а
fd
не открыт в режиме чтения/записи (O_RDWR).
Или установлен PROT_WRITE, но файл доступен только-для-дополнения.
EINVAL
Неправильные значения
start, length
или
offset.
(Т.е., они либо слишком велики, либо не выровнены по границе страницы.)
ETXTBSY
Была задана опция MAP_DENYWRITE, но заданный объект
fd
открыт для записи.
EAGAIN
Файл заблокирован, или блокируется слишком много памяти.
ENOMEM
Недостаточно памяти в системе, или было превышено максимальное число
отображения процесса.
ENODEV
Связанная файловая система для указанного файла не поддерживает
отображение памяти.
Использование отражаемой области памяти может привести к следующим сигналам:
SIGSEGV
(попытка записи в область памяти, заданную mmap как область для чтения);
SIGBUS
(попытка доступа к части буфера, которая не является файлом; например, она
может находиться за пределами файла. Подобной является ситуация,
когда другой процесс уменьшает длину файла).
СООТВЕТСТВИЕ СТАНДАРТАМ
SVr4, POSIX.1b (бывший POSIX.4), 4.4BSD, SUSv2.
SVr4 описывает дополнительные коды ошибок ENXIO и ENODEV.
SUSv2 описывает дополнительные коды ошибок EMFILE и EOVERFLOW.