Provided by: manpages-ru-dev_4.27.0-1_all bug

НАИМЕНОВАНИЕ

       mmap, munmap - отображает файлы или устройства в памяти, или удаляет их отображение

БИБЛИОТЕКА

       Стандартная библиотека языка C (libc, -lc)

ОБЗОР

       #include <sys/mman.h>

       void *mmap(void addr[.length], size_t length, int prot, int flags,
                  int fd, off_t offset);
       int munmap(void addr[.length], size_t length);

       Информацию по требованиям макроса тестирования свойств смотрите в разделе ЗАМЕЧАНИЯ.

ОПИСАНИЕ

       Вызов  mmap()  создаёт  новое отображение в виртуальном адресном пространстве вызывающего процесса. Адрес
       начала нового отображения указывается в addr. В аргументе length задаётся длина отображения (должна  быть
       больше 0).

       Если  значение  addr  равно  NULL,  то  ядро  само  выбирает адрес (выровненный по странице), по которому
       создаётся отображение; это наиболее переносимый метод создания нового отображения. Если значение addr  не
       равно  NULL,  то  ядро учитывает это при размещении отображения; в Linux ядро выберет ближайшую к границе
       страницу (но всегда выше или  равною  значению,  заданному  в  /proc/sys/vm/mmap_min_addr)  и  попытается
       создать  отображение.  Если  по  этому  адресу уже есть отображение, то ядро выберет новый адрес, который
       может и не зависеть от подсказки. Адрес нового отображения возвращается как результат вызова.

       Содержимое файлового отображения (в отличие от  анонимного  отображения;  смотрите  MAP_ANONYMOUS  далее)
       инициализируется  данными  из  файла  (или  объекта), на который указывает файловый дескриптор fd, длиной
       length байт, начиная со смещения  offset.  Значение  offset  должно  быть  кратно  размеру  (возвращается
       sysconf(_SC_PAGE_SIZE)) страницы.

       После  возврата  из  вызова  mmap()  файловый  дескриптор  fd  может быть немедленно закрыт без признания
       отображения недействительным.

       В аргументе prot указывается желаемая защита  памяти  отображения  (не  должна  конфликтовать  с  режимом
       открытого файла). Значением может быть PROT_NONE или побитово сложенные (OR) следующие флаги:

       PROT_EXEC  Страницы доступны для исполнения.

       PROT_READ  Страницы доступны для чтения.

       PROT_WRITE Страницы доступны для записи.

       PROT_NONE  Страницы недоступны.

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

       MAP_SHARED
              Сделать отображение общим. Изменения отображения видимы всем процессам, отображающим ту же область
              и (если отображение выполняется из файла) изменения  заносятся  в  отображённый  файл  (для  более
              точного контроля над изменениями файла нужно использовать msync(2)).

       MAP_SHARED_VALIDATE (начиная с Linux 4.15)
              Данный  флаг  представляет  тоже,  что и MAP_SHARED, отображения MAP_SHARED игнорируют неизвестные
              флаги flags. Если же отображение создаётся с MAP_SHARED_VALIDATE, ядро проверят, что ему  известны
              все переданные флаги и завершает отображение ошибкой EOPNOTSUPP, если есть неизвестные флаги. Этот
              тип  отображения  также  требуется  для  использования  некоторых  флагов  отображения  (например,
              MAP_SYNC).

       MAP_PRIVATE
              Создать закрытое отображение с механизмом копирования при записи. Изменения  отображения  невидимы
              другим  процессам,  отображающим  тот  же  файл, и сам файл не изменяется. Не определено, будут ли
              видимы в отображённой области изменения в файле, сделанные после вызова mmap().

       Флаги MAP_SHARED и MAP_PRIVATE описаны в POSIX.1-2001 и POSIX.1-2008. Флаг  MAP_SHARED_VALIDATE  является
       расширением Linux.

       Кроме этого в flags могут быть указаны (побитовым сложением):

       MAP_32BIT (начиная с Linux 2.4.20, 2.6)
              Поместить   отображение   в   первые  2  гигабайта  адресного  пространства  процесса.  Этот  флаг
              поддерживается только на архитектуре x86-64 для 64-битных программ. Он был добавлен для размещения
              стеков нитей в первых  2 ГБ  памяти,  что  даёт  увеличение  производительности  при  переключения
              контекста  на  некоторых  первых  64-битных  процессорах.  В  современных процессорах x86-64 такой
              проблемы с производительностью больше нет,  поэтому  на  таких  системах  данный  флаг  больше  не
              требуется. Он игнорируется, если указан флаг MAP_FIXED.

       MAP_ANON
              Synonym for MAP_ANONYMOUS; provided for compatibility with other implementations.

       MAP_ANONYMOUS
              The  mapping  is not backed by any file; its contents are initialized to zero.  The fd argument is
              ignored; however, some implementations require fd to be -1  if  MAP_ANONYMOUS  (or  MAP_ANON)   is
              specified,  and  portable  applications  should  ensure this.  The offset argument should be zero.
              Support for MAP_ANONYMOUS in conjunction with MAP_SHARED was added in Linux 2.4.

       MAP_DENYWRITE
              This flag is ignored.  (Long ago—Linux 2.0 and earlier—it signaled that attempts to write  to  the
              underlying file should fail with ETXTBSY.  But this was a source of denial-of-service attacks.)

       MAP_EXECUTABLE
              Этот флаг игнорируется.

       MAP_FILE
              Флаг для совместимости, игнорируется.

       MAP_FIXED
              Не  учитывать addr как подсказку: помещать отображение точно по этому адресу. Значение addr должно
              быть выровнено соответствующим образом: на большинстве архитектур оно должно быть  кратно  размеру
              страницы;  однако некоторые архитектуры могут накладывать дополнительные ограничения. Если область
              памяти, задаваемая addr  и  length,  перекрывается  со  страницами  существующих  отображений,  то
              перекрывающаяся  часть существующих отображений будет отброшена. Если заданный адрес не может быть
              использован, то вызов mmap() завершается ошибкой.

              Software that aspires to be portable should use the MAP_FIXED flag with care, keeping in mind that
              the exact layout of a process's memory mappings is allowed to change significantly  between  Linux
              versions,  C  library  versions,  and operating system releases.  Carefully read the discussion of
              this flag in NOTES!

       MAP_FIXED_NOREPLACE (начиная с Linux 4.17)
              Данный флаг действует схожим с MAP_FIXED образом при контроле addr, но в  отличие  от  него,  флаг
              MAP_FIXED_NOREPLACE  никогда не разделяет уже существующий отображённый диапазон. Если запрошенный
              диапазон пересекается с существующим отображением, то  такой  вызов  завершается  ошибкой  EEXIST.
              Поэтому  данный  флаг можно использовать как атомарную (если есть другие нити) попытку отображения
              адресного диапазона: для одной нити она закончится успешно; все остальные получат ошибку.

              Note that older kernels which do not recognize the MAP_FIXED_NOREPLACE flag will  typically  (upon
              detecting a collision with a preexisting mapping) fall back to a “non-MAP_FIXED” type of behavior:
              they   will  return  an  address  that  is  different  from  the  requested  address.   Therefore,
              backward-compatible software should check the returned address against the requested address.

       MAP_GROWSDOWN
              Этот флаг используется для  стеков.  Для  виртуальной  системы  памяти  ядра  он  обозначает,  что
              отображение  должно расширяться вниз по памяти. Возвращаемый адрес указывает на одну страницу ниже
              области памяти, которая в действительности создаётся в виртуальном адресном пространстве процесса.
              Обращение к адресу ниже «защитной» страницы  отображения  приведёт  к  расширению  отображения  на
              страницу.  Увеличение  таким  способом  можно повторять до тех пор, пока рост отображения страницы
              верхним концом не достигнет следующего нижнего  отображения,  при  таком  обращении  к  «защитной»
              страницы возникнет сигнал SIGSEGV.

       MAP_HUGETLB (начиная с Linux 2.6.32)
              Выделять  отображение  используя  «огромные  страницы». Дополнительную информацию смотрите в файле
              исходного  кода  ядра  Linux  Documentation/admin-guide/mm/hugetlbpage.rst,  а   также   следующее
              дополнение.

       MAP_HUGE_2MB
       MAP_HUGE_1GB (начиная с Linux 3.8)
              Используется  как  дополнение  к  MAP_HUGETLB  для  выбора  размера страницы hugetlb (2 МБ и 1 ГБ,
              соответственно), сработает  только  в  системе  которая  поддерживает  различные  размеры  больших
              страниц.

              Вообще,  желаемый  размер  огромной  страницы  можно настроить закодировав логарифм 2 от желаемого
              размера страницы в шести битах со смещением MAP_HUGE_SHIFT (значение  нуля  в  этом  битовом  поле
              означает  выбор  значения  огромной  страницы  по  умолчанию;  это  значение  можно  найти  в поле
              Hugepagesize  просмотрев  файл  /proc/meminfo).  Таким  образом  две  показанные  выше   константы
              определены как:

                  #define MAP_HUGE_2MB    (21 << MAP_HUGE_SHIFT)
                  #define MAP_HUGE_1GB    (30 << MAP_HUGE_SHIFT)

              Рабочий  диапазон  страниц  огромного  размера  может  быть  обнаружен,  перечислив  подкаталоги в
              /sys/kernel/mm/hugepages.

       MAP_LOCKED (начиная с Linux 2.5.37)
              Пометить отображаемую область как заблокированную таким же образом как с помощью mlock(2).  Данная
              реализация  будет  пытаться заполнить (предотказ) область полностью, но вызов mmap() не завершится
              ошибкой ENOMEM, если это  не  удастся  сделать.  Поэтому  действительные  отказы  могут  произойти
              позднее.  Такой  алгоритм  не  совпадает с mlock(2). Нужно использовать mmap() плюс mlock(2), если
              действительные отказы недопустимы после инициализации отображения. В старых ядрах флаг  MAP_LOCKED
              игнорируется.

       MAP_NONBLOCK (начиная с Linux 2.5.46)
              Данный  флаг  имеет  смысл  только  вместе с MAP_POPULATE. Не выполнять упреждающее чтение: только
              создать записи в таблице страниц для страниц, которые уже есть ОЗУ. Начиная с  Linux  2.6.23  этот
              флаг  приводит  к  тому,  что  выполнение  работы MAP_POPULATE отменяется. Когда-нибудь комбинация
              MAP_POPULATE и MAP_NONBLOCK может быть реализована заново.

       MAP_NORESERVE
              Do not reserve swap space for this mapping.  When swap space is reserved, one  has  the  guarantee
              that  it is possible to modify the mapping.  When swap space is not reserved one might get SIGSEGV
              upon a write  if  no  physical  memory  is  available.   See  also  the  discussion  of  the  file
              /proc/sys/vm/overcommit_memory  in  proc(5).   Before  Linux  2.6,  this  flag had effect only for
              private writable mappings.

       MAP_POPULATE (начиная с Linux 2.5.46)
              Populate (prefault) page tables for a mapping.  For a file mapping, this causes read-ahead on  the
              file.   This  will help to reduce blocking on page faults later.  The mmap()  call doesn't fail if
              the mapping cannot be populated (for example, due to limitations on  the  number  of  mapped  huge
              pages  when using MAP_HUGETLB).  Support for MAP_POPULATE in conjunction with private mappings was
              added in Linux 2.6.23.

       MAP_STACK (начиная с Linux 2.6.27)
              Allocate the mapping at an address suitable for a process or thread stack.

              This flag is currently a no-op on Linux.  However, by employing this flag, applications can ensure
              that they transparently obtain support if the flag is implemented in the future.  Thus, it is used
              in the glibc threading implementation to allow for the fact that some  architectures  may  (later)
              require  special  treatment  for  stack  allocations.   A  further  reason  to employ this flag is
              portability: MAP_STACK exists (and has an effect) on some other systems (e.g., some of the BSDs).

       MAP_SYNC (начиная с Linux 4.15)
              Данный  флаг  доступен  только  с  типом  отображения  MAP_SHARED_VALIDATE;  отображения  с  типом
              MAP_SHARED  будут  просто  игнорировать  этот  флаг.  Этот  флаг  поддерживается только для файлов
              поддерживаемых DAX (прямое отображение  в  постоянную  память).  Для  остальных  файлов,  создание
              отображения с этим флагом приводит к возврату ошибки EOPNOTSUPP.

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

       MAP_UNINITIALIZED (начиная с Linux 2.6.33)
              Не  очищать  анонимные  страницы.  Этот  флаг  предназначен  для  повышения  производительности на
              встраиваемых устройствах. Он учитывается, только если ядро было  собрано  с  поддержкой  параметра
              CONFIG_MMAP_ALLOW_UNINITIALIZED.  Так  как  этот параметр может привести к нарушению безопасности,
              обычно он устанавливается только на встраиваемых устройствах (то  есть,  устройствах,  где  только
              один человек имеет полный контроль над содержимым пользовательской памяти).

       Из  флагов,  перечисленных  выше,  в  POSIX.1-2001  и  POSIX.1-2008  определён  только MAP_FIXED. Однако,
       большинство систем также поддерживают MAP_ANONYMOUS (или его синоним  MAP_ANON).

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

       Адрес addr должен быть кратен размеру страницы (но  значения  length  это  не  касается).  Все  страницы,
       содержащие  часть  указанного  диапазона,  удаляются  из отображения и последующие ссылки на эти страницы
       приводят к генерации сигнала SIGSEGV. Это не ошибка,  если  указанный  диапазон  не  содержит  каких-либо
       отображённых страниц.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       On  success,  mmap()   returns  a  pointer  to the mapped area.  On error, the value MAP_FAILED (that is,
       (void *) -1)  is returned, and errno is set to indicate the error.

       On success, munmap()  returns 0.  On failure, it returns -1, and errno  is  set  to  indicate  the  error
       (probably to EINVAL).

ОШИБКИ

       EACCES Файловый  дескриптор указывает на не обычный файл. Или было запрошено отображение файла (mapping),
              но fd не открыт на чтение. Или был указан флаг MAP_SHARED и установлен бит PROT_WRITE,  но  fd  не
              открыт  в  режиме  чтения/записи (O_RDWR). Или был указан флаг PROT_WRITE, но файл доступен только
              для дополнения.

       EAGAIN Файл заблокирован, или блокируется слишком много памяти (смотрите setrlimit(2)).

       EBADF  Значение fd не является правильным файловым дескриптором (и MAP_ANONYMOUS не установлен).

       EEXIST В flags  указан  MAP_FIXED_NOREPLACE  и  диапазон,  покрываемый  addr  и  length,  пересекается  с
              существующим отображением.

       EINVAL Неправильное  значение  addr,  length  или  offset  (например,  оно  либо  слишком велико, либо не
              выровнено по границе страницы).

       EINVAL (начиная с Linux 2.6.12) Значение length равно 0.

       EINVAL В flags отсутствует MAP_PRIVATE, MAP_SHARED или MAP_SHARED_VALIDATE.

       ENFILE Достигнуто максимальное количество открытых файлов в системе.

       ENODEV Используемая файловая система для указанного файла не поддерживает отображение памяти.

       ENOMEM Больше нет доступной памяти.

       ENOMEM Процесс превысил бы ограничение на максимальное количество отображений.  Эта  ошибка  также  может
              возникнуть  в  munmap() при удалении отображения области в середине существующего отображения, так
              как при этом выполняется удаление отображения двух отображений меньшего  размера  на  любом  конце
              области.

       ENOMEM (начиная   с   Linux  4.7)  Было  бы  превышено  ограничение  процесса  RLIMIT_DATA,  описанное  в
              getrlimit(2).

       ENOMEM We don't like addr, because it exceeds the virtual address space of the CPU.

       EOVERFLOW
              На 32-битной архитектуре вместе с расширением для больших  файлов  (т.е.,  используется  64-битный
              off_t):  количество  страниц,  используемых  для  length плюс количество страниц, используемых для
              offset приводит к переполнению unsigned long (32 бита).

       EPERM  Аргументом prot запрашивается PROT_EXEC, но отображённая область  принадлежит  файлу  на  файловой
              системе, которая смонтирована с флагом no-exec.

       EPERM  Выполнение операции предотвращено опечатыванием (file seal); смотрите fcntl(2).

       EPERM  The  MAP_HUGETLB  flag  was  specified,  but  the  caller  was  not  privileged  (did not have the
              CAP_IPC_LOCK capability)  and is not a member  of  the  sysctl_hugetlb_shm_group  group;  see  the
              description of /proc/sys/vm/sysctl_hugetlb_shm_group in proc_sys(5).

       ETXTBSY
              Был задан флаг MAP_DENYWRITE, но объект, указываемый fd, открыт на запись.

       При использовании отображаемой области памяти могут возникать следующие сигналы:

       SIGSEGV
              Попытка записи в область, отображённую только для чтения.

       SIGBUS Attempted  access  to  a  page  of the buffer that lies beyond the end of the mapped file.  For an
              explanation of the treatment of the bytes in the page that corresponds to the end of a mapped file
              that is not a multiple of the page size, see NOTES.

АТРИБУТЫ

       Описание терминов данного раздела смотрите в attributes(7).
       ┌─────────────────────────────────────────────────────────────────────┬──────────────────────┬──────────┐
       │ ИнтерфейсАтрибутЗначение │
       ├─────────────────────────────────────────────────────────────────────┼──────────────────────┼──────────┤
       │ mmap(), munmap()                                                    │ Безвредность в нитях │ MT-Safe  │
       └─────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────┘

ВЕРСИИ

       На некоторых архитектурах (например, i386),  флаг  PROT_WRITE  подразумевает  флаг  PROT_READ.  Также  от
       архитектуры  зависит  подразумевает  ли  PROT_READ  флаг  PROT_EXEC или нет. Переносимые программы должны
       всегда устанавливать PROT_EXEC, если они собираются выполнять код, находящийся в отображении.

       Переносимый способ создания отображения: указать в addr значение 0 (NULL) и убрать MAP_FIXED из flags.  В
       этом  случае,  система сама выберет адрес для отображения; адрес, выбранный таким образом, не будет будет
       конфликтовать с существующими отображениями и не будет равен 0. Если указан  флаг  MAP_FIXED  и  значение
       addr равно 0 (NULL), то адрес отображения будет равен 0 (NULL).

       Некоторые  константы  flags  определены  только,  если  определён  подходящий макрос тестирования свойств
       (возможно, по умолчанию): _DEFAULT_SOURCE в glibc 2.19 и новее; _BSD_SOURCE или _SVID_SOURCE в glibc 2.19
       и старее (также достаточно использовать _GNU_SOURCE и требовать, этот  макрос  логично,  так  как  данные
       флаги  есть  только  в  Linux).  Соответственно,  флаги:  MAP_32BIT,  MAP_ANONYMOUS (и синоним MAP_ANON),
       MAP_DENYWRITE,  MAP_EXECUTABLE,   MAP_FILE,   MAP_GROWSDOWN,   MAP_HUGETLB,   MAP_LOCKED,   MAP_NONBLOCK,
       MAP_NORESERVE, MAP_POPULATE и MAP_STACK.

   Отличия между библиотекой C и ядром
       This  page  describes  the  interface  provided  by the glibc mmap()  wrapper function.  Originally, this
       function invoked a system call of the same name.  Since Linux 2.4, that system call has  been  superseded
       by  mmap2(2),  and nowadays the glibc mmap()  wrapper function invokes mmap2(2)  with a suitably adjusted
       value for offset.

СТАНДАРТЫ

       POSIX.1-2008.

ИСТОРИЯ

       POSIX.1-2001, SVr4, 4.4BSD.

       В системах POSIX, в которых есть  вызовы  mmap(),  msync(2)  и  munmap(),  значение  _POSIX_MAPPED_FILES,
       определённое в <unistd.h>, больше 0 (смотрите также sysconf(3)).

ПРИМЕЧАНИЯ

       Память, отображённая с помощью mmap(), сохраняется при fork(2) с теми же атрибутами.

       A  file is mapped in multiples of the page size.  For a file that is not a multiple of the page size, the
       remaining bytes in the partial page at the end of the mapping are zeroed when mapped,  and  modifications
       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.

       Приложение может определить какие страницы отображены в данный момент в буфере/страничном кэше с  помощью
       mincore(2).

   Безопасное использование MAP_FIXED
       Единственным  вариантом  безопасного  использования  MAP_FIXED  является  предварительное  резервирование
       адресного  пространства,  указываемого  в  addr  и  length,  другим  отображением;  в  остальных  случаях
       использование  MAP_FIXED  опасно, так как оно выполняет принудительное удаление существующих отображений,
       что позволяет легко повредить собственное адресное пространство многонитевого процесса.

       For example, suppose that thread A looks through /proc/pid/maps in order  to  locate  an  unused  address
       range  that  it  can map using MAP_FIXED, while thread B simultaneously acquires part or all of that same
       address range.  When thread A subsequently employs  mmap(MAP_FIXED),  it  will  effectively  clobber  the
       mapping  that  thread  B  created.  In this scenario, thread B need not create a mapping directly; simply
       making a library call that, internally, uses dlopen(3)  to load some other shared library, will  suffice.
       The  dlopen(3)   call  will  map  the  library into the process's address space.  Furthermore, almost any
       library call may be implemented in a way that adds memory mappings to the address space, either with this
       technique, or by simply allocating memory.  Examples include brk(2),  malloc(3),  pthread_create(3),  and
       the PAM libraries http://www.linux-pam.org.

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

   Изменение временных отметок для отображённых файлов
       У  отображённых  файлов  поле  st_atime  может  измениться  в  любой  момент  между  вызовом   mmap()   и
       соответствующим  удалением  отображения;  первое  обращение к отображённой странице приведёт к обновлению
       поля, если это ещё не было сделано.

       Поля st_ctime и st_mtime у отображённого с помощью флагов PROT_WRITE и MAP_SHARED файла  будут  обновлены
       после  записи  отображённой  области  и перед последующим вызовом msync(2) с флагом MS_SYNC или MS_ASYNC,
       если он будет вызван.

   Отображения огромных страниц (Huge TLB)
       Для отображений, работающих с огромными страницами, требования к аргументам mmap() и  munmap()  несколько
       отличаются от требований к отображениям, в которых используются страницы с системным размером.

       Для  mmap(),  offset  должно  быть  кратно  размеру  нижележащей огромной страницы. Система автоматически
       выравнивает length до кратного значения размера нижележащей огромной страницы.

       Для munmap(), addr и length должны быть кратны размеру нижележащей огромной страницы.

ОШИБКИ

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

       Before Linux 2.6.7, the MAP_POPULATE flag has effect only if prot is specified as PROT_NONE.

       SUSv3 specifies that mmap()  should fail if length is 0.  However, before Linux 2.6.12, mmap()  succeeded
       in this case: no mapping was created and the call returned addr.  Since Linux 2.6.12, mmap()  fails  with
       the error EINVAL for this case.

       В  POSIX  сказано,  что система всегда должна заполнять нулями любую частичную страницу у конца объекта и
       что система никогда не должна вносить любые изменения вне пределов  объекта.  В  Linux,  если  вы  пишите
       данные  в  такую  частичную  страницу  за концом объекта, то данные остаются в страничном кэше даже после
       закрытия и выключения отображения файла и  хотя  данные  никогда  не  пишутся  в  сам  файл,  последующие
       отображения  могут увидеть изменённое содержимое. В некоторых случаях это можно исправить вызвав msync(2)
       перед выключением отображения; однако это не работает на tmpfs(5) (например, когда используется интерфейс
       общей памяти POSIX, описанный в shm_overview(7)).

ПРИМЕРЫ

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

   Исходный код программы
       #include <fcntl.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/mman.h>
       #include <sys/stat.h>
       #include <sys/types.h>
       #include <unistd.h>

       #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

       int
       main(int argc, char *argv[])
       {
           int          fd;
           char         *addr;
           off_t        offset, pa_offset;
           size_t       length;
           ssize_t      s;
           struct stat  sb;

           if (argc < 3 || argc > 4) {
               fprintf(stderr, "%s file offset [length]\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           fd = open(argv[1], O_RDONLY);
           if (fd == -1)
               handle_error("open");

           if (fstat(fd, &sb) == -1)           /* To obtain file size */
               handle_error("fstat");

           offset = atoi(argv[2]);
           pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
               /* offset for mmap() must be page aligned */

           if (offset >= sb.st_size) {
               fprintf(stderr, "offset is past end of file\n");
               exit(EXIT_FAILURE);
           }

           if (argc == 4) {
               length = atoi(argv[3]);
               if (offset + length > sb.st_size)
                   length = sb.st_size - offset;
                       /* Can't display bytes past end of file */

           } else {    /* No length arg ==> display to end of file */
               length = sb.st_size - offset;
           }

           addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
                       MAP_PRIVATE, fd, pa_offset);
           if (addr == MAP_FAILED)
               handle_error("mmap");

           s = write(STDOUT_FILENO, addr + offset - pa_offset, length);
           if (s != length) {
               if (s == -1)
                   handle_error("write");

               fprintf(stderr, "partial write");
               exit(EXIT_FAILURE);
           }

           munmap(addr, length + offset - pa_offset);
           close(fd);

           exit(EXIT_SUCCESS);
       }

СМОТРИТЕ ТАКЖЕ

       ftruncate(2),  getpagesize(2),  memfd_create(2),  mincore(2), mlock(2), mmap2(2), mprotect(2), mremap(2),
       msync(2), remap_file_pages(2), setrlimit(2), shmat(2), userfaultfd(2), shm_open(3), shm_overview(7)

       The  descriptions  of  the  following  files  in  proc(5):   /proc/pid/maps,   /proc/pid/map_files,   and
       /proc/pid/smaps.

       B.O. Gallmeister, POSIX.4, O'Reilly, стр. 128–129 и 389–391.

ПЕРЕВОД

       Русский   перевод   этой   страницы   руководства   разработал(и)   aereiae  <aereiae@gmail.com>,  Alexey
       <a.chepugov@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>,
       Dmitry Bolkhovskikh <d20052005@yandex.ru>, ITriskTI <ITriskTI@gmail.com>,  Max  Is  <ismax799@gmail.com>,
       Yuri   Kozlov   <yuray@komyakino.ru>,   Иван   Павлов  <pavia00@gmail.com>,  Малянов  Евгений  Викторович
       <maljanow@outlook.com> и Kirill Rekhov <krekhov.dev@gmail.com>

       Этот перевод является свободной программной документацией; он распространяется на условиях  общедоступной
       лицензии  GNU  (GNU  General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или
       более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

       Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите  об  этом
       разработчику(ам)   по   его(их)  адресу(ам)  электронной  почты  или  по  адресу  списка рассылки русских
       переводчиков.

Справочные страницы Linux 6.9.1                  15 июня 2024 г.                                         mmap(2)