.\" -*- coding: UTF-8 -*- .\" Copyright (C) 1996 Andries Brouwer .\" and Copyright (C) 2006, 2007 Michael Kerrisk .\" .\" %%%LICENSE_START(VERBATIM) .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the Linux kernel and libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" %%%LICENSE_END .\" .\" Modified 1997-01-31 by Eric S. Raymond .\" Modified 2000-03-25 by Jim Van Zandt .\" Modified 2001-10-04 by John Levon .\" Modified 2003-02-02 by Andi Kleen .\" Modified 2003-05-21 by Michael Kerrisk .\" MAP_LOCKED works from 2.5.37 .\" Modified 2004-06-17 by Michael Kerrisk .\" Modified 2004-09-11 by aeb .\" Modified 2004-12-08, from Eric Estievenart .\" Modified 2004-12-08, mtk, formatting tidy-ups .\" Modified 2006-12-04, mtk, various parts rewritten .\" 2007-07-10, mtk, Added an example program. .\" 2008-11-18, mtk, document MAP_STACK .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH MMAP 2 "21 декабря 2020 г." Linux "Руководство программиста Linux" .SH ИМЯ mmap, munmap \- отображает файлы или устройства в памяти, или удаляет их отображение .SH СИНТАКСИС .nf \fB#include \fP .PP \fBvoid *mmap(void *\fP\fIaddr\fP\fB, size_t \fP\fIlength\fP\fB, int \fP\fIprot\fP\fB, int \fP\fIflags\fP\fB,\fP \fB int \fP\fIfd\fP\fB, off_t \fP\fIoffset\fP\fB);\fP \fBint munmap(void *\fP\fIaddr\fP\fB, size_t \fP\fIlength\fP\fB);\fP .fi .PP Информацию по требованиям макроса тестирования свойств смотрите в разделе ЗАМЕЧАНИЯ. .SH ОПИСАНИЕ Вызов \fBmmap\fP() создаёт новое отображение в виртуальном адресном пространстве вызывающего процесса. Адрес начала нового отображения указывается в \fIaddr\fP. В аргументе \fIlength\fP задаётся длина отображения (должна быть больше 0). .PP .\" Before Linux 2.6.24, the address was rounded up to the next page .\" boundary; since 2.6.24, it is rounded down! Если значение \fIaddr\fP равно NULL, то ядро само выбирает адрес (выровненный по странице), по которому создаётся отображение; это наиболее переносимый метод создания нового отображения. Если значение \fIaddr\fP не равно NULL, то ядро учитывает это при размещении отображения; в Linux ядро выберет ближайшую к границе страницу (но всегда выше или равною значению, заданному в \fI/proc/sys/vm/mmap_min_addr\fP) и попытается создать отображение. Если по этому адресу уже есть отображение, то ядро выберет новый адрес, который может и не зависеть от подсказки. Адрес нового отображения возвращается как результат вызова. .PP Содержимое файлового отображения (в отличие от анонимного отображения; смотрите \fBMAP_ANONYMOUS\fP далее) инициализируется данными из файла (или объекта), на который указывает файловый дескриптор \fIfd\fP, длиной \fIlength\fP байт, начиная со смещения \fIoffset\fP. Значение \fIoffset\fP должно быть кратно размеру (возвращается \fIsysconf(_SC_PAGE_SIZE)\fP) страницы. .PP После возврата из вызова \fBmmap\fP() файловый дескриптор \fIfd\fP может быть немедленно закрыт без признания отображения недействительным. .PP В аргументе \fIprot\fP указывается желаемая защита памяти отображения (не должна конфликтовать с режимом открытого файла). Значением может быть \fBPROT_NONE\fP или побитово сложенные (OR) следующие флаги: .TP 1.1i \fBPROT_EXEC\fP Страницы доступны для исполнения. .TP \fBPROT_READ\fP Страницы доступны для чтения. .TP \fBPROT_WRITE\fP Страницы доступны для записи. .TP \fBPROT_NONE\fP .\" Страницы недоступны. .SS "Аргумент флагов" В аргументе \fIflags\fP задаётся будут ли изменения отображения видимы другим процессам, отображающим ту же область, и будут ли изменения перенесены в отображённый файл. Данное поведение определяется в \fIflags\fP одним из следующих значений: .TP \fBMAP_SHARED\fP Сделать отображение общим. Изменения отображения видимы всем процессам, отображающим ту же область и (если отображение выполняется из файла) изменения заносятся в отображённый файл (для более точного контроля над изменениями файла нужно использовать \fBmsync\fP(2)). .TP \fBMAP_SHARED_VALIDATE\fP (начиная с Linux 4.15) Данный флаг представляет тоже, что и \fBMAP_SHARED\fP, отображения \fBMAP_SHARED\fP игнорируют неизвестные флаги \fIflags\fP. Если же отображение создаётся с \fBMAP_SHARED_VALIDATE\fP, ядро проверят, что ему известны все переданные флаги и завершает отображение ошибкой \fBEOPNOTSUPP\fP, если есть неизвестные флаги. Этот тип отображения также требуется для использования некоторых флагов отображения (например, \fBMAP_SYNC\fP). .TP \fBMAP_PRIVATE\fP Создать закрытое отображение с механизмом копирования при записи. Изменения отображения невидимы другим процессам, отображающим тот же файл, и сам файл не изменяется. Не определено, будут ли видимы в отображённой области изменения в файле, сделанные после вызова \fBmmap\fP(). .PP Флаги \fBMAP_SHARED\fP и \fBMAP_PRIVATE\fP описаны в POSIX.1\-2001 и POSIX.1\-2008. Флаг \fBMAP_SHARED_VALIDATE\fP является расширением Linux. .PP Кроме этого в \fIflags\fP могут быть указаны (побитовым сложением): .TP \fBMAP_32BIT\fP (начиная с Linux 2.4.20, 2.6) .\" See http://lwn.net/Articles/294642 "Tangled up in threads", 19 Aug 08 Поместить отображение в первые 2 гигабайта адресного пространства процесса. Этот флаг поддерживается только на архитектуре x86\-64 для 64\-битных программ. Он был добавлен для размещения стеков нитей в первых 2\ ГБ памяти, что даёт увеличение производительности при переключения контекста на некоторых первых 64\-битных процессорах. В современных процессорах x86\-64 такой проблемы с производительностью больше нет, поэтому на таких системах данный флаг больше не требуется. Он игнорируется, если указан флаг \fBMAP_FIXED\fP. .TP \fBMAP_ANON\fP Synonym for \fBMAP_ANONYMOUS\fP; provided for compatibility with other implementations. .TP \fBMAP_ANONYMOUS\fP .\" See the pgoff overflow check in do_mmap(). .\" See the offset check in sys_mmap in arch/x86/kernel/sys_x86_64.c. Отображение не привязанное к файлу; его содержимое инициализируется нулями. Аргумент \fIfd\fP игнорируется ; однако в некоторых реализациях при указании \fBMAP_ANONYMOUS\fP (или \fBMAP_ANON\fP) требуется указывать \fIfd\fP равное \-1, и так нужно поступать для переносимости приложений. Аргумент \fIoffset\fP должен быть ноль. Использование \fBMAP_ANONYMOUS\fP вместе с \fBMAP_SHARED\fP поддерживается в Linux только начиная с ядра версии 2.4. .TP \fBMAP_DENYWRITE\fP .\" Introduced in 1.1.36, removed in 1.3.24. Этот флаг игнорируется (раньше — Linux 2.0 и старее — он обозначал, что попытки записи в подчинённые файлы должны завершаться с кодом ошибки \fBETXTBSY\fP. Но это стало основой для атак типа отказа в обслуживании). .TP \fBMAP_EXECUTABLE\fP .\" Introduced in 1.1.38, removed in 1.3.24. Flag tested in proc_follow_link. .\" (Long ago, it signaled that the underlying file is an executable. .\" However, that information was not really used anywhere.) .\" Linus talked about DOS related to MAP_EXECUTABLE, but he was thinking of .\" MAP_DENYWRITE? Этот флаг игнорируется. .TP \fBMAP_FILE\fP .\" On some systems, this was required as the opposite of .\" MAP_ANONYMOUS -- mtk, 1 May 2007 Флаг для совместимости, игнорируется. .TP \fBMAP_FIXED\fP Не учитывать \fIaddr\fP как подсказку: помещать отображение точно по этому адресу. Значение \fIaddr\fP должно быть выровнено соответствующим образом: на большинстве архитектур оно должно быть кратно размеру страницы; однако некоторые архитектуры могут накладывать дополнительные ограничения. Если область памяти, задаваемая \fIaddr\fP и \fIlen\fP, перекрывается со страницами существующих отображений, то перекрывающаяся часть существующих отображений будет отброшена. Если заданный адрес не может быть использован, то вызов \fBmmap\fP() завершается ошибкой. .IP В переносимом ПО флаг \fBMAP_FIXED\fP нужно использовать осторожно, так как точная раскладка процесса в памяти, доступная для изменения, может значительно отличаться в разных версиях ядер, библиотеки С и выпусках операционной системы. \fIВнимательно прочитайте описание этого флага в ЗАМЕЧАНИЯХ!\fP .TP \fBMAP_FIXED_NOREPLACE\fP (начиная с Linux 4.17) .\" commit a4ff8e8620d3f4f50ac4b41e8067b7d395056843 Данный флаг действует схожим с \fBMAP_FIXED\fP образом при контроле \fIaddr\fP, но в отличие от него, флаг \fBMAP_FIXED_NOREPLACE\fP никогда не разделяет уже существующий отображённый диапазон. Если запрошенный диапазон пересекается с существующим отображением, то такой вызов завершается ошибкой \fBEEXIST\fP. Поэтому данный флаг можно использовать как атомарную (если есть другие нити) попытку отображения адресного диапазона: для одной нити она закончится успешно; все остальные получат ошибку. .IP Note that older kernels which do not recognize the \fBMAP_FIXED_NOREPLACE\fP flag will typically (upon detecting a collision with a preexisting mapping) fall back to a "non\-\fBMAP_FIXED" type of behavior:\fP 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. .TP \fBMAP_GROWSDOWN\fP Этот флаг используется для стеков. Для виртуальной системы памяти ядра он обозначает, что отображение должно расширяться вниз по памяти. Возвращаемый адрес указывает на одну страницу ниже области памяти, которая в действительности создаётся в виртуальном адресном пространстве процесса. Обращение к адресу ниже «защитной» страницы отображения приведёт к расширению отображения на страницу. Увеличение таким способом можно повторять до тех пор, пока рост отображения страницы верхним концом не достигнет следующего нижнего отображения, при таком обращении к «защитной» страницы возникнет сигнал \fBSIGSEGV\fP. .TP \fBMAP_HUGETLB\fP (начиная с Linux 2.6.32) Выделять отображение используя «огромные страницы». Дополнительную информацию смотрите в файле исходного кода ядра Linux \fIDocumentation/admin\-guide/mm/hugetlbpage.rst\fP, а также следующее дополнение. .TP \fBMAP_HUGE_2MB\fP, \fBMAP_HUGE_1GB\fP (начиная с Linux 3.8) .\" See https://lwn.net/Articles/533499/ Используется как дополнение к \fBMAP_HUGETLB\fP для выбора размера страницы hugetlb (2\ МБ и 1\ ГБ, соответственно), сработает только в системе которая поддерживает различные размеры больших страниц. .IP Вообще, желаемый размер огромной страницы можно настроить закодировав логарифм 2 от желаемого размера страницы в шести битах со смещением \fBMAP_HUGE_SHIFT\fP (значение нуля в этом битовом поле означает выбор значения огромной страницы по умолчанию; это значение можно найти в поле \fIHugepagesize\fP просмотрев файл \fI/proc/meminfo\fP). Таким образом две показанные выше константы определены как: .IP .in +4n .EX #define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) #define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) .EE .in .IP Рабочий диапазон страниц огромного размера может быть обнаружен, перечислив подкаталоги в \fI/sys/kernel/mm/hugepages\fP. .TP \fBMAP_LOCKED\fP (начиная с Linux 2.5.37) .\" If set, the mapped pages will not be swapped out. Пометить отображаемую область как заблокированную таким же образом как с помощью \fBmlock\fP(2). Данная реализация будет пытаться заполнить (предотказ) область полностью, но вызов \fBmmap\fP() не завершится ошибкой \fBENOMEM\fP, если это не удастся сделать. Поэтому действительные отказы могут произойти позднее. Такой алгоритм не совпадает с \fBmlock\fP(2). Нужно использовать \fBmmap\fP() плюс \fBmlock\fP(2), если действительные отказы недопустимы после инициализации отображения. В старых ядрах флаг \fBMAP_LOCKED\fP игнорируется. .TP \fBMAP_NONBLOCK\fP (начиная с Linux 2.5.46) .\" commit 54cb8821de07f2ffcd28c380ce9b93d5784b40d7 Данный флаг имеет смысл только вместе с \fBMAP_POPULATE\fP. Не выполнять упреждающее чтение: только создать записи в таблице страниц для страниц, которые уже есть ОЗУ. Начиная с Linux 2.6.23 этот флаг приводит к тому, что выполнение работы \fBMAP_POPULATE\fP отменяется. Когда\-нибудь комбинация \fBMAP_POPULATE\fP и \fBMAP_NONBLOCK\fP может быть реализована заново. .TP \fBMAP_NORESERVE\fP Не резервировать страницы пространства подкачки для этого отображения. Если пространство подкачки резервируется, то для отображения гарантируется возможность изменения. Если оно не резервируется, то можно получить сигнал \fBSIGSEGV\fP при записи, если физическая память будет недоступна. Смотрите также описание файла \fI/proc/sys/vm/overcommit_memory\fP в \fBproc\fP(5). В ядрах до 2.6 этот флаг действовал только для частных доступных на запись отображений. .TP \fBMAP_POPULATE\fP (начиная с Linux 2.5.46) Наполнить (до возникновения страничного прерывания, prefault) страничные таблицы отображения. Для файлового отображения это приводит к опережающему чтению из файла. В дальнейшем это помогает сократить блокировку по отказу страниц. Флаг \fBMAP_POPULATE\fP поддерживается для закрытых отображений только начиная с Linux 2.6.23. .TP \fBMAP_STACK\fP (начиная с Linux 2.6.27) Allocate the mapping at an address suitable for a process or thread stack. .IP .\" See http://lwn.net/Articles/294642 "Tangled up in threads", 19 Aug 08 .\" commit cd98a04a59e2f94fa64d5bf1e26498d27427d5e7 .\" http://thread.gmane.org/gmane.linux.kernel/720412 .\" "pthread_create() slow for many threads; also time to revisit 64b .\" context switch optimization?" 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: \fBMAP_STACK\fP exists (and has an effect) on some other systems (e.g., some of the BSDs). .TP \fBMAP_SYNC\fP (начиная с Linux 4.15) Данный флаг доступен только с типом отображения \fBMAP_SHARED_VALIDATE\fP; отображения с типом \fBMAP_SHARED\fP будут просто игнорировать этот флаг. Этот флаг поддерживается только для файлов поддерживаемых DAX (прямое отображение в постоянную память). Для остальных файлов, создание отображения с этим флагом приводит к возврату ошибки \fBEOPNOTSUPP\fP. .IP Общие файловые отображения с этим флагом представляют гарантию того, что пока есть часть памяти отображённая для записи в адресном пространстве процесса, она будет видима в том же файле по тому же смещению даже после падения или перезагрузки системы. Вместе с использованием соответствующих инструкций ЦП это позволяет пользователям таких отображений эффективней выполнять устойчивые изменения данных. .TP \fBMAP_UNINITIALIZED\fP (начиная с Linux 2.6.33) Не очищать анонимные страницы. Этот флаг предназначен для повышения производительности на встраиваемых устройствах. Он учитывается, только если ядро было собрано с поддержкой параметра \fBCONFIG_MMAP_ALLOW_UNINITIALIZED\fP. Так как этот параметр может привести к нарушению безопасности, обычно он устанавливается только на встраиваемых устройствах (то есть, устройствах, где только один человек имеет полный контроль над содержимым пользовательской памяти). .PP .\" FIXME . for later review when Issue 8 is one day released... .\" POSIX may add MAP_ANON in the future .\" http://austingroupbugs.net/tag_view_page.php?tag_id=8 .\" http://austingroupbugs.net/view.php?id=850 Из флагов, перечисленных выше, в POSIX.1\-2001 и POSIX.1\-2008 определён только \fBMAP_FIXED\fP. Однако, большинство систем также поддерживают \fBMAP_ANONYMOUS\fP (или его синоним \fBMAP_ANON\fP). .SS munmap() Системный вызов \fBmunmap\fP() удаляет отображение для указанного адресного диапазона и это приводит к тому, что дальнейшее обращение по адресам внутри диапазона приводит к генерации неправильных ссылок на память. Также для диапазона отображение автоматически удаляется при завершении работы процесса. С другой стороны, закрытие файлового дескриптора не приводит к удалению отображения диапазона. .PP Адрес \fIaddr\fP должен быть кратен размеру страницы (но значения \fIlength\fP это не касается). Все страницы, содержащие часть указанного диапазона, удаляются из отображения и последующие ссылки на эти страницы приводят к генерации сигнала \fBSIGSEGV\fP. Это не ошибка, если указанный диапазон не содержит каких\-либо отображённых страниц. .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" При успешном выполнении \fBmmap\fP() возвращается указатель на отображённую область. При ошибке возвращается значение \fBMAP_FAILED\fP (а именно, \fI(void\ *)\ \-1\fP) и \fIerrno\fP устанавливается в соответствующее значение. .PP При успешном выполнении \fBmunmap\fP() возвращает 0. При сбои возвращается \-1, и код ошибки кладётся в \fIerrno\fP (скорее всего \fBEINVAL\fP). .SH ОШИБКИ .TP \fBEACCES\fP Файловый дескриптор указывает на не обычный файл. Или было запрошено отображение файла (mapping), но \fIfd\fP не открыт на чтение. Или был указан флаг \fBMAP_SHARED\fP и установлен бит \fBPROT_WRITE\fP, но \fIfd\fP не открыт в режиме чтения/записи (\fBO_RDWR\fP). Или был указан флаг \fBPROT_WRITE\fP, но файл доступен только для дополнения. .TP \fBEAGAIN\fP Файл заблокирован, или блокируется слишком много памяти (смотрите \fBsetrlimit\fP(2)). .TP \fBEBADF\fP Значение \fIfd\fP не является правильным файловым дескриптором (и \fBMAP_ANONYMOUS\fP не установлен). .TP \fBEEXIST\fP В \fIflags\fP указан \fBMAP_FIXED_NOREPLACE\fP и диапазон, покрываемый \fIaddr\fP и \fIlength\fP, пересекается с существующим отображением. .TP \fBEINVAL\fP Неправильное значение \fIaddr\fP, \fIlength\fP или \fIoffset\fP (например, оно либо слишком велико, либо не выровнено по границе страницы). .TP \fBEINVAL\fP (начиная с Linux 2.6.12) Значение \fIlength\fP равно 0. .TP \fBEINVAL\fP В \fIflags\fP отсутствует \fBMAP_PRIVATE\fP, \fBMAP_SHARED\fP или \fBMAP_SHARED_VALIDATE\fP. .TP \fBENFILE\fP .\" This is for shared anonymous segments .\" [2.6.7] shmem_zero_setup()-->shmem_file_setup()-->get_empty_filp() .\" .TP .\" .B ENOEXEC .\" A file could not be mapped for reading. Достигнуто максимальное количество открытых файлов в системе. .TP \fBENODEV\fP Используемая файловая система для указанного файла не поддерживает отображение памяти. .TP \fBENOMEM\fP Больше нет доступной памяти. .TP \fBENOMEM\fP Процесс превысил бы ограничение на максимальное количество отображений. Эта ошибка также может возникнуть в \fBmunmap\fP() при удалении отображения области в середине существующего отображения, так как при этом выполняется удаление отображения двух отображений меньшего размера на любом конце области. .TP \fBENOMEM\fP (начиная с Linux 4.7) Было бы превышено ограничение процесса \fBRLIMIT_DATA\fP, описанное в \fBgetrlimit\fP(2). .TP \fBEOVERFLOW\fP На 32\-битной архитектуре вместе с расширением для больших файлов (т.е., используется 64\-битный \fIoff_t\fP): количество страниц, используемых для \fIlength\fP плюс количество страниц, используемых для \fIoffset\fP приводит к переполнению \fIunsigned long\fP (32 бита). .TP \fBEPERM\fP .\" (Since 2.4.25 / 2.6.0.) Аргументом \fIprot\fP запрашивается \fBPROT_EXEC\fP, но отображённая область принадлежит файлу на файловой системе, которая смонтирована с флагом no\-exec. .TP \fBEPERM\fP Выполнение операции предотвращено опечатыванием (file seal); смотрите \fBfcntl\fP(2). .TP \fBETXTBSY\fP Был задан флаг \fBMAP_DENYWRITE\fP, но объект, указываемый \fIfd\fP, открыт на запись. .PP При использовании отображаемой области памяти могут возникать следующие сигналы: .TP \fBSIGSEGV\fP Попытка записи в область, отображённую только для чтения. .TP \fBSIGBUS\fP 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. .SH АТРИБУТЫ Описание терминов данного раздела смотрите в \fBattributes\fP(7). .TS allbox; lbw18 lb lb l l l. Интерфейс Атрибут Значение T{ \fBmmap\fP(), \fBmunmap\fP() T} Безвредность в нитях MT\-Safe .TE .SH "СООТВЕТСТВИЕ СТАНДАРТАМ" .\" SVr4 documents additional error codes ENXIO and ENODEV. .\" SUSv2 documents additional error codes EMFILE and EOVERFLOW. POSIX.1\-2001, POSIX.1\-2008, SVr4, 4.4BSD. .PP .\" POSIX.1-2001: It shall be defined to -1 or 0 or 200112L. .\" -1: unavailable, 0: ask using sysconf(). .\" glibc defines it to 1. В системах POSIX, в которых есть вызовы \fBmmap\fP(), \fBmsync\fP(2) и \fBmunmap\fP(), значение \fB_POSIX_MAPPED_FILES\fP, определённое в \fI\fP, больше 0 (смотрите также \fBsysconf\fP(3)). .SH ЗАМЕЧАНИЯ Память, отображённая с помощью \fBmmap\fP(), сохраняется при \fBfork\fP(2) с теми же атрибутами. .PP 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. .PP На некоторых архитектурах (например, i386), флаг \fBPROT_WRITE\fP подразумевает флаг \fBPROT_READ\fP. Также от архитектуры зависит подразумевает ли \fBPROT_READ\fP флаг \fBPROT_EXEC\fP или нет. Переносимые программы должны всегда устанавливать \fBPROT_EXEC\fP, если они собираются выполнять код, находящийся в отображении. .PP Переносимый способ создания отображения: указать в \fIaddr\fP значение 0 (NULL) и убрать \fBMAP_FIXED\fP из \fIflags\fP. В этом случае, система сама выберет адрес для отображения; адрес, выбранный таким образом, не будет будет конфликтовать с существующими отображениями и не будет равен 0. Если указан флаг \fBMAP_FIXED\fP и значение \fIaddr\fP равно 0 (NULL), то адрес отображения будет равен 0 (NULL). .PP Некоторые константы \fIflags\fP определены только, если определён подходящий макрос тестирования свойств (возможно, по умолчанию): \fB_DEFAULT_SOURCE\fP в glibc 2.19 и новее; \fB_BSD_SOURCE\fP или \fB_SVID_SOURCE\fP в glibc 2.19 и старее (также достаточно использовать \fB_GNU_SOURCE\fP и требовать, этот макрос логично, так как данные флаги есть только в Linux). Соответственно, флаги: \fBMAP_32BIT\fP, \fBMAP_ANONYMOUS\fP (и синоним \fBMAP_ANON\fP), \fBMAP_DENYWRITE\fP, \fBMAP_EXECUTABLE\fP, \fBMAP_FILE\fP, \fBMAP_GROWSDOWN\fP, \fBMAP_HUGETLB\fP, \fBMAP_LOCKED\fP, \fBMAP_NONBLOCK\fP, \fBMAP_NORESERVE\fP, \fBMAP_POPULATE\fP и \fBMAP_STACK\fP. .PP .\" Приложение может определить какие страницы отображены в данный момент в буфере/страничном кэше с помощью \fBmincore\fP(2). .SS "Безопасное использование MAP_FIXED" Единственным вариантом безопасного использования \fBMAP_FIXED\fP является предварительное резервирование адресного пространства, указываемого в \fIaddr\fP и \fIlength\fP, другим отображением; в остальных случаях использование \fBMAP_FIXED\fP опасно, так как оно выполняет принудительное удаление существующих отображений, что позволяет легко повредить собственное адресное пространство многонитевого процесса. .PP Предположим, например, что нить A просматривает \fI/proc//maps\fPв поиске неиспользуемого адресного диапазона, который она сможет отобразить используя \fBMAP_FIXED\fP, но одновременно с этим нить B захватывает часть или весь этот же адресный диапазон. Когда после этого нить A запустит \fBmmap(MAP_FIXED)\fP, это, фактически, разобьёт отображение, созданное нитью B. В этом сценарии нити B не нужно создавать отображение явным образом; будет достаточно просто сделать библиотечный вызов, например, \fBdlopen\fP(3) для загрузки какой\-то другой общей библиотеки. Вызов \fBdlopen\fP(3) отобразит библиотеку в адресное пространство процесса. Более того, почти каждый библиотечный вызов можно реализовать так, чтобы он добавлял отображения памяти в адресное пространство с помощью этого метода или просто выделяя память. Например, такими вызовами являются \fBbrk\fP(2), \fBmalloc\fP(3), \fBpthread_create\fP(3) и библиотеки PAM .UR http://www.linux\-pam.org .UE . .PP .\" Начиная с Linux 4.17, в многонитевых программах можно использовать флаг \fBMAP_FIXED_NOREPLACE\fP и, тем самым, избежать опасности, описанной выше, когда выполняется попытка создать отображение по фиксированному адресу, который не был зарезервирован существующим отображением. .SS "Изменение временных отметок для отображённых файлов" У отображённых файлов поле \fIst_atime\fP может измениться в любой момент между вызовом \fBmmap\fP() и соответствующим удалением отображения; первое обращение к отображённой странице приведёт к обновлению поля, если это ещё не было сделано. .PP .\" Поля \fIst_ctime\fP и \fIst_mtime\fP у отображённого с помощью флагов \fBPROT_WRITE\fP и \fBMAP_SHARED\fP файла будут обновлены после записи отображённой области и перед последующим вызовом \fBmsync\fP(2) с флагом \fBMS_SYNC\fP или \fBMS_ASYNC\fP, если он будет вызван. .SS "Отображения огромных страниц (Huge TLB)" Для отображений, работающих с огромными страницами, требования к аргументам \fBmmap\fP() и \fBmunmap\fP() несколько отличаются от требований к отображениям, в которых используются страницы с системным размером. .PP Для \fBmmap\fP(), \fIoffset\fP должно быть кратно размеру нижележащей огромной страницы. Система автоматически выравнивает \fIlength\fP до кратного значения размера нижележащей огромной страницы. .PP .\" Для \fBmunmap\fP(), \fIaddr\fP и \fIlength\fP должны быть кратны размеру нижележащей огромной страницы. .SS "Отличия между библиотекой C и ядром" .\" Since around glibc 2.1/2.2, depending on the platform. В данной странице описывается интерфейс, предоставляемый обёрточной функцией glibc \fBmmap\fP(). Раньше, эта функция обращалась к системному вызову с тем же именем. Начиная с ядра 2.4, данный системный вызов был заменён на \fBmmap2\fP(2). В настоящее время обёрточная функция glibc, \fBmmap\fP(), вызывает \fBmmap2\fP(2) с подходящим подкорректированным значением \fIoffset\fP. .SH ДЕФЕКТЫ В Linux не гарантируется результат флага \fBMAP_NORESERVE\fP, описанный выше. По умолчанию, любой процесс может быть принудительно завершён в любой момент, если в системе закончилась память. .PP В ядрах до версии 2.6.7 флаг \fBMAP_POPULATE\fP учитывается только, если значение \fIprot\fP равно \fBPROT_NONE\fP. .PP В SUSv3 указано, что \fBmmap\fP() должен завершаться с ошибкой, если \fIlength\fP равно 0. Однако в ядрах до версии 2.6.12 вызов \fBmmap\fP() в этом случае выполняется успешно: отображение не создаётся и вызов возвращает \fIaddr\fP. Начиная с ядра версии 2.6.12, в этом случае вызов \fBmmap\fP() завершается с ошибкой \fBEINVAL\fP. .PP В POSIX сказано, что система всегда должна заполнять нулями любую частичную страницу у конца объекта и что система никогда не должна вносить любые изменения вне пределов объекта. В Linux, если вы пишите данные в такую частичную страницу за концом объекта, то данные остаются в страничном кэше даже после закрытия и выключения отображения файла и хотя данные никогда не пишутся в сам файл, последующие отображения могут увидеть изменённое содержимое. В некоторых случаях это можно исправить вызвав \fBmsync\fP(2) перед выключением отображения; однако это не работает на \fBtmpfs\fP(5) (например, когда используется интерфейс общей памяти POSIX, описанный в \fBshm_overview\fP(7)). .SH ПРИМЕРЫ .\" FIXME . Add an example here that uses an anonymous shared region for .\" IPC between parent and child. Следующая программа выводит часть файла, указанного в первом аргументе командной строки, в стандартный вывод. Диапазон выдаваемых байт задаётся смещением и длиной во втором и третьем аргументах командной строки. Программа создаёт отображение требуемых страниц файла и затем использует \fBwrite\fP(2) для вывода запрошенных байт. .SS "Исходный код программы" .EX #include #include #include #include #include #include #define handle_error(msg) \e do { perror(msg); exit(EXIT_FAILURE); } while (0) int main(int argc, char *argv[]) { char *addr; int fd; struct stat sb; off_t offset, pa_offset; size_t length; ssize_t s; if (argc < 3 || argc > 4) { fprintf(stderr, "%s файл смещение [длина]\en", 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 & \(ti(sysconf(_SC_PAGE_SIZE) \- 1); /* для mmap() нужно выронить смещение */ if (offset >= sb.st_size) { fprintf(stderr, "указанное смещение находится за концом файла\en"); exit(EXIT_FAILURE); } if (argc == 4) { length = atoi(argv[3]); if (offset + length > sb.st_size) length = sb.st_size \- offset; /* Нельзя показать байты за концом файла */ } 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); } .EE .SH "СМ. ТАКЖЕ" \fBftruncate\fP(2), \fBgetpagesize\fP(2), \fBmemfd_create\fP(2), \fBmincore\fP(2), \fBmlock\fP(2), \fBmmap2\fP(2), \fBmprotect\fP(2), \fBmremap\fP(2), \fBmsync\fP(2), \fBremap_file_pages\fP(2), \fBsetrlimit\fP(2), \fBshmat\fP(2), \fBuserfaultfd\fP(2), \fBshm_open\fP(3), \fBshm_overview\fP(7) .PP Описание в \fBproc\fP(5) следующих файлов: \fI/proc/[pid]/maps\fP, \fI/proc/[pid]/map_files\fP и \fI/proc/[pid]/smaps\fP. .PP .\" .\" Repeat after me: private read-only mappings are 100% equivalent to .\" shared read-only mappings. No ifs, buts, or maybes. -- Linus B.O. Gallmeister, POSIX.4, O'Reilly, страницы 128\(en129 и 389\(en391. .SH ЗАМЕЧАНИЯ Эта страница является частью проекта Linux \fIman\-pages\fP версии 5.10. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу \%https://www.kernel.org/doc/man\-pages/. .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства был сделан aereiae , Alexey , Azamat Hackimov , Dmitriy S. Seregin , Dmitry Bolkhovskikh , ITriskTI , Max Is , Yuri Kozlov , Иван Павлов и Малянов Евгений Викторович . .PP Этот перевод является бесплатной документацией; прочитайте .UR https://www.gnu.org/licenses/gpl-3.0.html Стандартную общественную лицензию GNU версии 3 .UE или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. .PP Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на .MT man-pages-ru-talks@lists.sourceforge.net .ME .