Provided by: manpages-ru-dev_4.19.0-7_all bug

ИМЯ

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

LIBRARY

       Standard C library (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

       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  │
       └───────────────────────────────────────────────────────┴──────────────────────┴──────────┘

СТАНДАРТЫ

       POSIX.1-2001, POSIX.1-2008, 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.

       На некоторых архитектурах (например, 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.

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

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

       Предположим, например, что нить A просматривает /proc/<pid>/mapsв  поиске  неиспользуемого
       адресного  диапазона, который она сможет отобразить используя MAP_FIXED, но одновременно с
       этим нить B захватывает часть или весь этот же адресный диапазон. Когда после этого нить A
       запустит mmap(MAP_FIXED), это, фактически, разобьёт отображение, созданное нитью B. В этом
       сценарии нити B не нужно создавать отображение  явным  образом;  будет  достаточно  просто
       сделать  библиотечный  вызов,  например,  dlopen(3)  для  загрузки  какой-то  другой общей
       библиотеки. Вызов dlopen(3) отобразит библиотеку в адресное пространство  процесса.  Более
       того, почти каждый библиотечный вызов можно реализовать так, чтобы он добавлял отображения
       памяти в адресное пространство с помощью этого метода или просто выделяя память. Например,
       такими   вызовами   являются   brk(2),   malloc(3),  pthread_create(3)  и  библиотеки  PAM
       ⟨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 должны быть кратны размеру нижележащей огромной страницы.

   Отличия между библиотекой 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.

ДЕФЕКТЫ

       В 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 <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 файл смещение [длина]\n", argv[0]);
               exit(EXIT_FAILURE);
           }

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

           if (fstat(fd, &sb) == -1)           /* получение размера файла */
               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, "указанное смещение находится за концом файла\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 {    /* Не указана длина ==> показать всё до конца файла */
               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, "частичная запись");
               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)

       Описание   в   proc(5)   следующих   файлов:   /proc/[pid]/maps,  /proc/[pid]/map_files  и
       /proc/[pid]/smaps.

       B.O. Gallmeister, POSIX.4, O'Reilly, pp. 128–129 and 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>

       Этот  перевод  является  бесплатной  документацией;  прочитайте  Стандартную  общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если вы обнаружите ошибки в переводе  этой  страницы  руководства,  пожалуйста,  отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.