jammy (2) munmap.2.gz

Provided by: manpages-de-dev_4.13-4_all bug

BEZEICHNUNG

       mmap, munmap - (un)mapt Dateien oder Geräte im Speicher

ÜBERSICHT

       #include <sys/mman.h>

       void *mmap(void *Adr, size_t laenge, int prot, int Schalter,
                  int dd, off_t Versatz);
       int munmap(void *Adr, size_t laenge);

       Siehe ANMERKUNGEN für Informationen über Feature-Test-Makros-Anforderungen.

BESCHREIBUNG

       mmap()  erstellt  ein  neues  Mapping  in  den  virtuellen  Adressraum  des  aufrufenden  Prozesses.  Die
       Anfangsadresse für dieses neue Mapping wird in Adr angegeben. Das Argument laenge gibt an,  welche  Größe
       das Mapping haben soll (dies muss größer als 0 sein).

       Falls  Adr NULL ist, wählt der Kernel die (Seiten-ausgerichtete) Adresse aus, an der das Mapping erstellt
       wird. Dies ist die portabelste Methode, ein neues Mapping zu erstellen. Falls Adr nicht NULL ist,  wertet
       der  Kernel  die  Adresse  als Hinweis, wo das Mapping erstellt werden soll. Unter Linux wird das Mapping
       dann eine Speicherseitengrenze in der Nähe auswählen (allerdings immer identisch zu oder oberhalb von dem
       durch  /proc/sys/vm/mmap_min_addr  festgelegten Wert) und versuchen, dort ein Mapping zu erstellen. Falls
       dort bereits ein anderes Mapping existiert, dann wählt der Kernel eine  neue  Adresse,  die  den  Hinweis
       berücksichtigen  kann,  aber  nicht  muss.  Die  Adresse des neuen Mappings wird als Ergebnis des Aufrufs
       zurückgegeben.

       Die Inhalte eines Datei-Mappings werden initialisiert, indem  laenge  Byte  aus  der  Datei  (oder  einem
       anderen  Objekt),  die  durch  den  Dateideskriptor dd beschrieben wird, ab dem Versatz Versatz verwendet
       werden. Dies ist anders als beim anonymen Mapping, siehe MAP_ANONYMOUS unten. Versatz muss ein Vielfaches
       der Seitengröße sein, die von sysconf(_SC_PAGE_SIZE) zurückgegeben wird.

       Nachdem  der mmap()-Aufruf zurückgekehrt ist, kann der Dateideskriptor dd sofort geschlossen werden, ohne
       dass das Mapping ungültig wird.

       Das Argument prot beschreibt den gewünschten Speicherschutz des Mappings (und darf nicht  im  Widerspruch
       zum  Öffnungsmodus  der  Datei  stehen).  Es ist entweder PROT_NONE oder das bitweise ODER von einem oder
       mehreren der folgenden Schalter:

       PROT_EXEC  Seiten können ausgeführt werden.

       PROT_READ  Seiten dürfen gelesen werden.

       PROT_WRITE Seiten dürfen beschrieben werden.

       PROT_NONE  Auf die Seiten darf nicht zugegriffen werden.

   Das Argument »Schalter«
       Das Argument Schalter bestimmt, ob Aktualisierungen des Mappings für andere Prozesse sichtbar  sind,  die
       denselben  Bereich  mappen  und  ob  Aktualisierungen  auch  in die zugrundeliegende Datei weitergereicht
       werden. Dieses Verhalten wird durch genau einen der folgenden Werte in Schalter festgelegt:

       MAP_SHARED
              Das Mapping gemeinsam benutzen. Aktualisierungen dieses Mappings sind für andere Prozesse  in  dem
              gleichen  Bereich  sichtbar und (falls es sich um Datei-basierende Mappings handelt) werden zu der
              zugrundeliegenden Datei weitergereicht.  (Um  genau  zu  steuern,  wann  Aktualisierungen  zu  der
              zugrundeliegenden Datei weitergereicht werden, muss msync(2) eingesetzt werden.)

       MAP_SHARED_VALIDATE (seit Linux 4.15)
              Dieser Schalter stellt das gleiche Verhalten wie MAP_SHARED bereit, außer dass MAP_SHARED-Mappings
              unbekannte Schalter in Schalter ignorieren. Im Gegensatz überprüft der Kernel,  wenn  er  Mappings
              mittels  MAP_SHARED_VALIDATE erstellt, dass alle übergebenen Schalter bekannt sind und schlägt mit
              dem Fehler EOPNOTSUPP bei unbekannten Schaltern fehl. Dieser Mapping-Typ wird  auch  benötigt,  um
              bestimmte Mapping-Schalter (z.B. MAP_SYNC) verwenden zu können.

       MAP_PRIVATE
              Erstellt ein privates, beim Kopieren zu schreibendes Mapping. Aktualisierungen an dem Mapping sind
              für andere Prozesse, die die gleiche Datei  mappen,  nicht  sichtbar,  und  werden  nicht  an  die
              zugrundeliegende  Datei weitergeleitet. Es ist nicht spezifiziert, ob Änderungen an der Datei, die
              nach dem Aufruf von mmap() erfolgen, in der gemappten Region sichtbar sind.

       Sowohl  MAP_SHARED  als  auch  MAP_PRIVATE  werden  in   POSIX.1-2001   und   POSIX.1-2008   beschrieben.
       MAP_SHARED_VALIDATE ist eine Linux-Erweiterung.

       Zusätzlich können null oder mehrere der folgenden Werte mit OR in Schalter hinzugefügt werden:

       MAP_32BIT (seit Linux 2.4.20, 2.6)
              Legt  das Mapping in die ersten zwei Gigabyte des Prozessadressraums. Dieser Schalter wird nur auf
              X86-64 für 64-Bit-Programme  unterstützt.  Er  wurde  hinzugefügt,  damit  Thread-Stacks  irgendwo
              innerhalb   der   ersten   2 GB   Speicher  zugewiesen  werden  können,  damit  die  Leistung  des
              Kontext-Umschaltens   auf   einigen   der   ersten   64-Bit-Prozessoren   erhöht   wird.   Moderne
              X86-64-Prozessoren  haben dieses Leistungsproblem nicht mehr, wodurch der Einsatz dieses Schalters
              auf diesen Systemen nicht  mehr  benötigt  wird.  Der  Schalter  MAP_32BIT  wird  ignoriert,  wenn
              MAP_FIXED gesetzt ist.

       MAP_ANON
              Synonym für MAP_ANONYMOUS; zur Kompatibilität mit anderen Implementierungen bereitgestellt.

       MAP_ANONYMOUS
              Diesem  Mapping liegt keine Datei zugrunde; ihr Inhalt wird mit Nullen initialisiert. Das Argument
              dd wird ignoriert, einige Implementierungen verlangen aber, dass dd -1  ist,  falls  MAP_ANONYMOUS
              (oder  MAP_ANON) festgelegt ist, und portable Anwendungen sollten dies sicherstellen. Das Argument
              Versatz sollte 0 sein. Unter Linux wird die Kombination von MAP_ANONYMOUS mit MAP_SHARED  erst  ab
              Kernelversion 2.4 unterstützt.

       MAP_DENYWRITE
              Dieser  Schalter  wird  ignoriert. (Vor langer Zeit — Linux 2.0 und älter — signalisierte er, dass
              Schreibversuche auf die zugrundeliegende Datei mit ETXTBSY fehlschlagen  sollten.  Dies  war  aber
              eine Quelle von Diensteverweigerungsangriffen.

       MAP_EXECUTABLE
              Dieser Schalter wird ignoriert.

       MAP_FILE
              Kompatibilitätsschalter. Ignoriert.

       MAP_FIXED
              Adr  wird  nicht  als Hinweis interpretiert; legt das Mapping genau an dieser Adresse an. Adr muss
              geeignet ausgerichtet sein: bei den meisten Architekturen reicht ein  Vielfaches  der  Seitengröße
              aus,  allerdings könnten einige Architekturen zusätzliche Anforderungen stellen. Falls der mit Adr
              und len festgelegte Speicherbereich bestehende Mappings  überlappt,  dann  wird  der  überlappende
              Anteil  des  bestehenden  Mappings  verworfen.  Falls die angegebene Adresse nicht verwandt werden
              kann, wird mmap() fehlschlagen.

              Software, die Portierbarkeit anstrebt, sollte den Schalter MAP_FIXED mit  Vorsicht  verwenden  und
              dabei  berücksichtigen,  dass  sich  die  genaue  Anordnung der Mappings des Prozesses im Speicher
              deutlich zwischen  Kernelversionen,  C-Bibliotheksversionen  und  Betriebssystemveröffentlichungen
              unterscheiden kann. Lesen Sie die Erörterung dieses Schalters im Abschnitt ANMERKUNGEN sorgfältig!

       MAP_FIXED_NOREPLACE (seit Linux 4.17)
              Dieser  Schalter stellt ein Verhalten bereit, das MAP_FIXED im Hinblick auf die Erzwingung von Adr
              ähnelt, sich aber dadurch  unterscheidet,  dass  MAP_FIXED_NOREPLACE  einen  bereits  bestehenden,
              gemappten  Bereich  durcheinanderbringt.  Falls  der  angeforderte  Bereich  mit einem bestehenden
              Mapping kollidieren würde, dann schlägt dieser Aufruf mit EEXIST fehl. Dieser Schalter kann  daher
              für  atomare  (im  Hinblick  auf andere Threads) Versuche, einen Adressbereich zu mappen, verwandt
              werden: ein Thread hat Erfolg, alle anderen berichten einen Fehlschlag.

              Beachten  Sie,  dass  ältere  Kernel,  die  den  Schalter  MAP_FIXED_NOREPLACE   nicht   erkennen,
              typischerweise  (bei  der Erkennung einer Kollision mit einem bereits bestehenden Mapping) auf den
              Verhaltenstyp von nicht-MAP_FIXED zurückfallen: sie liefern eine Adresse zurück, die sich von  der
              angeforderten    Adresse    unterscheidet.   Daher   sollte   rückwärtskompatible   Software   die
              zurückgelieferte Adresse mit der angeforderten Adresse vergleichen.

       MAP_GROWSDOWN
              Dieser Schalter wird für Stacks verwandt. Er zeigt dem Kernelsystem für  virtuellen  Speicher  an,
              dass sich das Mapping nach unten im Speicher ausdehnen soll. Die zurückgelieferte Adresse ist eine
              Seite tiefer als der Speicherbereich, der  tatsächlich  im  virtuellen  Adressraum  des  Prozesses
              erstellt  wird.  Wird  eine  Adresse  in  der »Wächter«-Seite unterhalb des Mappings berührt, dann
              wächst das Mapping um eine Seite. Dieses Wachstum kann wiederholt werden, bis das Mapping bis  auf
              eine  Seite  innerhalb  des  hohen  Endes  des  nächst-niedrigeren  Mappings  anwächst - zu diesem
              Zeitpunkt führt das Berühren der »Wächter«-Seite zu einem SIGSEGV-Signal.

       MAP_HUGETLB (seit Linux 2.6.32)
              Reserviert  das  Mapping  mittels  »großer  Speicherseiten«.  Siehe   die   Linux-Kernelquelldatei
              Documentation/admin-guide/mm/hugetlbpage.rst  sowie  die  nachfolgenden  ANMERKUNGEN  für  weitere
              Details.

       MAP_HUGE_2MB, MAP_HUGE_1GB (seit Linux 3.8)
              Wird in Zusammenhang mit MAP_HUGETLB verwandt,  um  alternative  hugetlb-Seitengrößen  (respektive
              2 MB und 1 GB) auf Systemen auszuwählen, die mehrere hugetlb-Seitengrößen unterstützen.

              Allgemeiner  kann  die  gewünschte Größe der großen Speicherseiten durch Kodierung des Logarithmus
              zur Basis 2 der gewünschten Seitengröße in den sechs Bits am Versatz  MAP_HUGE_SHIFT  konfiguriert
              werden.  (Ein Wert 0 in diesem Bitfeld stellt die standardmäßige große Speicherseitengröße bereit;
              die Vorgabegröße großer Speicherseiten kann mittels des durch /proc/meminfo  offengelegten  Feldes
              Hugepagesize ermittelt werden.) Daher sind die obigen zwei Konstanten wie folgt definiert:

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

              Der  von  dem System unterstützte Bereich der Größe der großen Speicherseiten kann durch Auflisten
              der Unterverzeichnisse in /sys/kernel/mm/hugepages ermittelt werden.

       MAP_LOCKED (seit Linux 2.5.37)
              Markiert den gemappten Bereich auf die  gleiche  Art  wie  mlock(2).  Diese  Implementierung  wird
              versuchen,  den  gesamten  Bereich vorzubelegen (»prefault«) aber der Aufruf von mmap() wird nicht
              mit ENOMEM fehlschlagen, falls dies nicht gelingt. Daher können später große  Ausnahmebehandlungen
              passieren.  Daher  ist  die  Semantik nicht so stark wie mlock(2). Sie sollten mmap() mit mlock(2)
              verwenden,  wenn  große  Ausnahmebehandlungen  nach  der  Initialisierung   des   Mappings   nicht
              akzeptierbar sind. Der Schalter MAP_LOCKED wird unter älteren Kerneln ignoriert.

       MAP_NONBLOCK (seit Linux 2.5.46)
              Dieser  Schalter  ergibt  nur  im  Zusammenhang  mit  MAP_POPULATE  Sinn. Es wird kein Vorauslesen
              durchgeführt, es werden Seitentabelleneinträge  nur  für  Seiten  erstellt,  die  bereits  im  RAM
              vorhanden  sind.  Seit  Linux  2.6.23  führt dieser Schalter dazu, dass MAP_POPULATE nichts macht.
              Irgendwann könnte die Kombination von MAP_POPULATE und MAP_NONBLOCK wieder implementiert werden.

       MAP_NORESERVE
              Reserviert für dieses Mapping keinen Auslagerungsspeicher.  Wenn  Auslagerungsspeicher  reserviert
              wird,   muss   garantiert  werden,  dass  Änderungen  an  dem  Mapping  möglich  sind.  Wird  kein
              Auslagerungsspeicher reserviert, könnte beim Schreiben ein SIGSEGV empfangen  werden,  falls  kein
              physischer     Speicher    verfügbar    ist.    Siehe    auch    die    Diskussion    der    Datei
              /proc/sys/vm/overcommit_memory in proc(5). In Kerneln vor  2.6  hatte  dieser  Schalter  nur  eine
              Wirkung für private, schreibbare Mappings.

       MAP_POPULATE (seit Linux 2.5.46)
              Belegt  (»prefault«)  Seitentabellen  für  ein  Mapping. Für ein Datei-Mapping führt dies zu einem
              Vorablesen der Datei. Dies hilft dabei, später  Blockierungen  bei  Seitenausnahmebehandlungen  zu
              vermeiden. MAP_POPULATE wird für private Mappings erst seit Linux 2.6.23 unterstützt.

       MAP_STACK (seit Linux 2.6.27)
              Reserverviert  ein  Mapping  an  einer  Adresse,  die für einen Stack eines Prozesses oder Threads
              geeignet ist.

              Dieser Schalter löst derzeit nichts aus. Durch Einsatz dieses Schalters  können  Anwendungen  aber
              transparent  sicherstellen,  dass  sie  die  Unterstützung  erlangen,  wenn dieser Schalter in der
              Zukunft implementiert wird. Daher wird er in der Glibc-Threading-Implementierung verwandt, um  der
              Tatsache Rechnung zu tragen, dass auf einigen Architekturen (später) eine besondere Behandlung von
              Stack-Zuweisungen nötig sein könnte. Ein weiterer Grund,  diesen  Schalter  einzusetzen,  ist  die
              Portabilität:  MAP_STACK  existiert  (und  hat eine Auswirkung) auf einigen anderen Systemen (z.B.
              einigen BSDs).

       MAP_SYNC (seit Linux 4.15)
              Dieser Schalter ist nur mit  dem  Mapping-Typ  MAP_SHARED_VALIDATE  verfügbar.  Mappings  vom  Typ
              MAP_SHARED  ignorieren diesen Schalter ohne Rückmeldung. Dieser Schalter wird nur für Dateien, die
              DAX (direktes Mapping von dauerhaftem Speicher) unterstützen, unterstützt. Für andere Dateien wird
              das Erstellen eines Mappings mit diesem Schalter zu einem EOPNOTSUPP-Fehler führen.

              Gemeinsame  Datei-Mappings  mit  diesem  Schalter  garantieren,  dass  der schreibbare eingemappte
              Speicheranteil im Adressraum des Prozesses auch in der gleichen  Datei  an  dem  gleichen  Versatz
              selbst  nach  einem  Systemabsturz  oder  -neustart  sichtbar ist. Im Zusammenhang mit dem Einsatz
              geeigneter CPU-Anweisungen stellt dieses Benutzern solcher Mappings eine effizientere Art  bereit,
              solche Datenveränderungen dauerhaft zu machen.

       MAP_UNINITIALIZED (seit Linux 2.6.33)
              Die  anonymen  Seiten  nicht bereinigen. Dieser Schalter ist für die Verbesserung der Leistung auf
              eingebetteten Systemen gedacht. Dieser Schalter wird nur berücksichtigt, falls der Kernel mit  der
              Option     CONFIG_MMAP_ALLOW_UNINITIALIZED     konfiguriert     worden     war.    Aufgrund    der
              Sicherheitsauswirkungen wird diese  Option  normalerweise  nur  auf  eingebetteten  Geräten  (d.h.
              Geräten, bei denen komplette Kontrolle über die Speicherinhalte besteht) aktiviert.

       Von  den  obigen  Schaltern  ist  nur MAP_FIXED in POSIX.1-2001 und POSIX.1-2008 spezifiziert. Allerdings
       unterstützen die meisten Systeme MAP_ANONYMOUS (oder sein Synonym MAP_ANON).

   munmap()
       Der munmap-Systemaufruf hebt die Mappings im angegebenen Speicherbereich  auf.  Zukünftige  Zugriffe  auf
       diesen   Adressraum  erzeugen  dann  einen  Fehler  vom  Typ  »invalid  memory  reference«  -  Ungültiger
       Speicherzugriff. Der Adressraum wird außerdem automatisch ausgemappt, wenn der Prozess beendet wird.  Das
       Schließen des Dateideskriptors hingegen führt nicht dazu, dass der Adress-Mapping aufgehoben wird.

       Die  Adresse  Adr  muss  ein  Vielfaches  der  Seitengröße sein (für laenge ist das nicht der Fall). Alle
       Seiten, die einen Teil des angezeigten Bereichs enthalten, werden ausgemappt, und nachfolgende Referenzen
       auf  diese  Seiten  führen  zu  SIGSEGV. Es ist kein Fehler, falls der angezeigte Bereich keine gemappten
       Seiten enthält.

RÜCKGABEWERT

       Bei Erfolg gibt mmap einen Zeiger auf den gemappten Speicherbereich zurück. Bei Fehlern  wird  MAP_FAILED
       ((void *) -1) zurückgegeben und errno entsprechend gesetzt, um die Fehlerursache anzuzeigen.

       Bei  Erfolg  liefert  munmap()  0  zurück.  Im  Fehlerfall liefert es -1 und errno wird auf den Grund des
       Fehlers gesetzt (wahrscheinlich EINVAL).

FEHLER

       EACCES Ein Dateideskriptor bezieht sich auf eine  nicht  normale  Datei.  Oder  ein  Datei-Mapping  wurde
              angefordert,  aber  dd  ist nicht zum Lesen geöffnet. Oder MAP_SHARED wurde erbeten und PROT_WRITE
              ist gesetzt, aber dd  ist  nicht  zum  Lesen/Schreiben  geöffnet  (O_RDWR).  Oder  PROT_WRITE  ist
              angegeben, aber die Datei darf nur am Ende weiter beschrieben werden (»append-only«).

       EAGAIN Die Datei wurde gesperrt oder zuviel Speicher wurde gesperrt (siehe setrlimit(2)).

       EBADF  dd ist kein gültiger Dateideskriptor (und MAP_ANONYMOUS wurde nicht gesetzt).

       EEXIST MAP_FIXED_NOREPLACE  wurde  in  Schalter angegeben und der durch Adr und laenge abgedeckte Bereich
              überschneidet sich mit einem bestehenden Mapping.

       EINVAL Die Adressen, die durch Adr, laenge oder Versatz angegeben wurden, sind ungültig. (Z.B.  sind  sie
              zu groß oder nicht an einer Speicherseitengröße ausgerichtet.)

       EINVAL (seit Linux 2.6.12)  laenge war 0.

       EINVAL Schalter enthielt weder MAP_PRIVATE, MAP_SHARED noch MAP_SHARED_VALIDATE.

       ENFILE Die systemweite Beschränkung für die Gesamtzahl offener Dateien wurde erreicht.

       ENODEV Das zugrundeliegende Dateisystem der angegebenen Datei unterstützt das Speicher-Mapping nicht.

       ENOMEM Es ist kein Speicher verfügbar.

       ENOMEM Die  maximale  Anzahl  von Mappings des Prozesses würde überschritten. Dieser Fehler kann auch für
              munmap() beim Aufheben  von  Mappings  einer  Region  in  der  Mitte  eines  bestehenden  Mappings
              auftreten, da dies zu zwei kleineren Mappings auf jeder Seite des entmappten Bereichs führt.

       ENOMEM (seit  Linux  4.7).  Die  Prozessbeschränkung  RLIMIT_DATA,  beschrieben  in  getrlimit(2),  würde
              überschritten.

       EOVERFLOW
              Auf 32-Bit-Architekturen zusammen mit den Erweiterungen für große Dateien (d.h. der Verwendung von
              64-Bit  off_t): die Anzahl der für laenge sowie die Anzahl der für Versatz verwandten Seiten würde
              einen Überlauf von unsigned long (32-Bit) hervorrufen.

       EPERM  Das Argument prot verlangt PROT_EXEC, aber der gemappte Bereich gehört zu einer  Datei  auf  einem
              Dateisystem, das ohne Ausführrechte eingehängt wurde (»no-exec«).

       EPERM  Die Aktion wurde durch eine Dateiversiegelung verhindert; siehe fcntl(2).

       ETXTBSY
              MAP_DENYWRITE wurde angegeben, aber das durch dd bezeichnete Objekt ist zum Schreiben geöffnet.

       Die Verwendung eines gemappten Bereichs kann diese Signale verursachen:

       SIGSEGV
              Es wurde versucht, in einen Bereich zu schreiben, der nur lesbar gemappt wurde.

       SIGBUS Es wurde versucht, auf eine Seite des Puffers zuzugreifen, die hinter dem Ende der gemappten Datei
              liegt. Für eine Erläuterung der Behandlung von Bytes in der Seite,  die  dem  Ende  der  gemappten
              Datei entspricht, die kein Vielfaches der Seitengröße ist, siehe ANMERKUNGEN.

ATTRIBUTE

       Siehe attributes(7) für eine Erläuterung der in diesem Abschnitt verwandten Ausdrücke.

       ┌───────────────────┬───────────────────────┬─────────┐
       │SchnittstelleAttributWert    │
       ├───────────────────┼───────────────────────┼─────────┤
       │mmap(), munmap()   │ Multithread-Fähigkeit │ MT-Safe │
       └───────────────────┴───────────────────────┴─────────┘

KONFORM ZU

       POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD.

       Auf  POSIX-Systemen,  auf  denen mmap(), msync(2) und munmap() verfügbar sind, ist _POSIX_MAPPED_FILES in
       <unistd.h> auf einen Wert größer 0 definiert. (Siehe auch sysconf(3).)

ANMERKUNGEN

       Speicher, der mit mmap() gemappt wurde, wird über fork(2) hinweg mit den gleichen Attributen erhalten.

       Eine Datei wird in Vielfachen der Seitengröße gemappt. Für eine  Datei,  die  nicht  ein  Vielfaches  der
       Seitengröße  ist,  werden  die  verbliebenen Bytes in der unvollständigen Seite am Ende des Mappings beim
       Mappen mit Nullen überschrieben und Änderungen an diesem Bereich werden nicht in die  Datei  geschrieben.
       Es  ist  nicht  spezifiziert, wie sich die Größenänderung der zugrundeliegenden Datei auf das Mapping der
       Seiten, die hinzugefügten oder entfernten Regionen der Datei entsprechen, auswirkt.

       Auf   einigen   Hardware-Architekturen   (z.B.   i386)   impliziert   PROT_WRITE   PROT_READ.   Es    ist
       architekturabhängig,  ob  PROT_READ  PROT_EXEC  impliziert (oder nicht). Portable Programme sollten immer
       PROT_EXEC setzen, falls sie vorhaben, Code in dem neuen Mapping auszuführen.

       Die portierbare Art, ein Mapping zu erstellen, ist die Angabe von Adr als 0 (NULL) und das Auslassen  von
       MAP_FIXED  aus Schalter. In diesem Fall wählt das System die Adresse für das Mapping; die Adresse wird so
       gewählt, dass sie mit keinem bestehenden Mapping in Konflikt steht und  nicht  0  sein  wird.  Falls  der
       Schalter MAP_FIXED angegeben und Adr 0 (NULL) ist, dann wird die gemappte Adresse 0 (NULL) sein.

       Bestimmte Schalter-Konstanten sind nur definiert, falls die geeigneten Feature-Test-Makros definiert sind
       (möglicherweise standardmäßig):  _DEFAULT_SOURCE  mit  Glibc  2.19  oder  neuer;  oder  _BSD_SOURCE  oder
       _SVID_SOURCE  in  Glibc 2.19 und älter. (Es reicht auch aus, _GNU_SOURCE einzusetzen, und dieses Makro zu
       verlangen, wäre logischer gewesen, da alle diese Schalter Linux-spezifisch sind). Die relevanten Schalter
       sind:  MAP_32BIT,  MAP_ANONYMOUS  (und  das  Synonym  MAP_ANON), MAP_DENYWRITE, MAP_EXECUTABLE, MAP_FILE,
       MAP_GROWSDOWN, MAP_HUGETLB, MAP_LOCKED, MAP_NONBLOCK, MAP_NORESERVE, MAP_POPULATE und MAP_STACK.

       Durch Verwendung von mincore(2) kann eine Anwendung ermitteln, welche Seiten eines Mappings sich  derzeit
       im Puffer/Seitenzwischenspeicher befinden.

   MAP_FIXED sicher benutzen
       Der  einzige  sichere  Anwendungsfall  für  MAP_FIXED  ist,  falls  der  durch Adr und laenge festgelegte
       Adressbereich vorher durch ein anderes Mapping reserviert  wurde;  andernfalls  ist  die  Verwendung  von
       MAP_FIXED  gefährlich,  da  sie  bereits  bestehende  Mappings zwangsweise entfernt, wodurch es für einen
       Prozess mit mehreren Threads leicht wird, seinen eigenen Adressraum zu beschädigen.

       Nehmen wir beispielsweise an, dass  Thread  A  /proc/<PID>/maps  durchsucht,  um  einen  nicht  benutzten
       Adressbereich  zu  finden,  den er mittels MAP_FIXED mappen kann, während Thread B gleichzeitig Teile des
       gleichen  Adressbereichs  (oder  den  gesamten  Adressbereich)  erlangt.  Wenn  Thread   A   anschließend
       mmap(MAP_FIXED)  einsetzt,  wird  es das Mapping, das Thread B erstellte, durcheinanderbringen. In diesem
       Szenario muss Thread B nicht das Mapping direkt erstellen: einfach ein Aufruf einer  Bibliotheksfunktion,
       die  intern dlopen(3) zum Laden einer anderen dynamische Bibliothek verwendet, reicht aus. Der Aufruf von
       dlopen(3) wird die Bibliothek in den Adressraum des Prozesses  einmappen.  Desweiteren  kann  fast  jeder
       Bibliotheksaufruf  auf  eine  Art  implementiert sein, die Speicher-Mappings zu dem Adressraum hinzufügt,
       entweder mit dieser Technik  oder  einfach  durch  Reservierung  von  Speicher.  Beispiele  sind  brk(2),
       malloc(3), pthread_create(3) und die PAM-Bibliotheken ⟨http://www.linux-pam.org⟩.

       Seit  Linux  4.17  kann  ein Multithread-Programm den Schalter MAP_FIXED_NOREPLACE verwenden, um die oben
       beschriebene Gefahr zu vermeiden, dass ein Mapping an einer festen Adresse versucht wird, die nicht durch
       ein bereits existierendes Mapping reserviert wurde.

   Zeitstempeländerungen für Datei-basierte Mappings
       Für  Datei-basierte  Mappings  wird  das Feld st_atime für die gemappte Datei zu jedem Zeitpunkt zwischen
       mmap() und dem entsprechenden Entmappen aufgerufen werden; die erste Referenz auf die gemappte Seite wird
       das Feld aktualisieren, falls es nicht bereits erfolgt ist.

       Das  Feld  st_ctime  und  st_mtime  für eine mit PROT_WRITE und MAP_SHARED gemappte Datei wird nach einem
       Schreibzugriff auf den gemappten Bereich und vor dem nachfolgenden msync(2) mit den Schalter MS_SYNC oder
       MS_ASYNC, falls dieser erfolgt, aktualisiert.

   Mappings großer Speicherseiten (Huge TLB)
       Für  Mappings, die große Speicherseiten einsetzen, unterscheiden sich die Anforderungen für die Argumente
       von mmap() und munmap() etwas von den  Anforderungen  für  Mappings,  die  die  native  Systemseitengröße
       verwenden.

       Für  mmap()  muss  Versatz  ein  Vielfaches  der unterliegenden Größe der großen Speicherseiten sein. Das
       System richtet laenge automatisch aus, dass  es  ein  Vielfaches  der  unterliegenden  Größe  der  großen
       Speicherseiten ist.

       Für  munmap()  müssen  sowohl  Adr  als  auch  laenge  ein Vielfaches der unterliegenden Größe der großen
       Speicherseiten sein.

   Unterschiede C-Bibliothek/Kernel
       Diese Seite beschreibt die durch den mmap()-Wrapper der Glibc bereitgestellte Funktion. Ursprünglich rief
       diese  Funktion  einen Systemaufruf mit dem gleichen Namen auf. Seit Kernel 2.4 wurde dieser Systemaufruf
       durch mmap2(2) ersetzt und heutzutage ruft die  Wrapperfunktion  mmap()  der  Glibc  mmap2(2)  mit  einem
       geeignet angepassten Wert für Versatz auf.

FEHLER

       Unter Linux gibt es keine Garantien, wie die, die unter MAP_NORESERVE vorgeschlagen werden. Standardmäßig
       kann jeder Prozess jederzeit getötet werden, wenn dem System der Speicher ausgeht.

       In Kerneln vor 2.6.7 hatte  der  Schalter  MAP_POPULATE  nur  einen  Effekt,  falls  prot  als  PROT_NONE
       festgelegt ist.

       SUSv3  spezifiziert,  dass mmap() fehlschlagen soll, falls laenge 0 ist. In Kerneln vor 2.6.12 war mmap()
       in diesem Fall allerdings erfolgreich: es wurde kein Mapping erstellt und der Aufruf lieferte Adr zurück.
       Seit Kernel 2.6.12 schlägt es in diesem Fall mit dem Fehler EINVAL fehl.

       POSIX  spezifiziert,  dass das System immer jede teilweise gefüllte Seite am Ende des Objektes mit Nullen
       auffüllen muss und dass das System niemals Änderungen an dem Objekt hinter seinem  Ende  schreibt.  Unter
       Linux  verbleiben  sämtliche  geschriebenen  Daten  in  solchen  Teilseiten nach dem Ende des Objektes im
       Seitenzwischenspeicher, selbst nachdem die Datei geschlossen und entmappt wurde  und  selbst  obwohl  die
       Daten  niemals  zu  der  Datei  selbst  geschrieben wurden, könnten nachfolgende Mappings die veränderten
       Inhalte sehen. In einigen Fällen könnte dies durch einen Aufruf von  msync(2),  bevor  das  Aufheben  des
       Mappings  stattfindet,  behoben  werden,  allerdings funktioniert dies nicht auf tmpfs(5) (beispielsweise
       beim Einsatz der POSIX-Schnittstelle für gemeinsamen Speicher, wie in shm_overview(7) dokumentiert).

BEISPIELE

       Das nachfolgende Programm gibt Teile der als sein erstes Befehlszeilenargument übergebenen Datei auf  die
       Standardausgabe  aus.  Der  ausgegebene  Byte-Bereich  wird mittels des Versatzes und des Längenwertes im
       zweiten und dritten Befehlszeilenargument angegeben.  Das  Programm  erstellt  ein  Speicher-Mapping  der
       benötigten Seiten der Datei und verwendet write(2), um die gewünschten Bytes auszugeben.

   Programmquelltext
       #include <sys/mman.h>
       #include <sys/stat.h>
       #include <fcntl.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>

       #define handle_error(msg) \
           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 Dateiversatz [Länge]\n", argv[0]);
               exit(EXIT_FAILURE);
           }

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

           if (fstat(fd, &sb) == -1)           /* Um die Dateigröße zu erhalten */
               handle_error("fstat");

           offset = atoi(argv[2]);
           pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
               /* Versatz für mmap() muss an der Seite ausgerichtet sein */

           if (offset >= sb.st_size) {
               fprintf(stderr, "Versatz ist hinter dem Dateiende\n");
               exit(EXIT_FAILURE);
           }

           if (argc == 4) {
               length = atoi(argv[3]);
               if (offset + length > sb.st_size)
                   length = sb.st_size - offset;
                       /* Bytes hinter dem Dateiende können nicht angezeigt werden */

           } else {    /* Kein Längen-Argument ==> Anzeige bis zum Dateiende */
               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, "Schreiben unvollständig");
               exit(EXIT_FAILURE);
           }

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

           exit(EXIT_SUCCESS);
       }

SIEHE AUCH

       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)

       Die  Beschreibung  der  folgenden  Dateien  in  proc(5):  /proc/[PID]/maps,   /proc/[PID]/map_files   und
       /proc/[pid]/smaps.

       B.O. Gallmeister, POSIX.4, O'Reilly, Seiten 128–129 und 389–391.

KOLOPHON

       Diese  Seite  ist  Teil  der  Veröffentlichung  5.10  des Projekts Linux-man-pages. Eine Beschreibung des
       Projekts, Informationen, wie Fehler gemeldet werden können sowie die aktuelle Version dieser Seite finden
       sich unter https://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG

       Die  deutsche  Übersetzung  dieser  Handbuchseite  wurde  von  Johnny Teveßen <j.tevessen@gmx.de>, Martin
       Schulze   <joey@infodrom.org>,   Dr.   Tobias   Quathamer   <toddy@debian.org>   und   Helge   Kreutzmann
       <debian@helgefjell.de> erstellt.

       Diese  Übersetzung  ist  Freie  Dokumentation;  lesen  Sie  die  GNU  General  Public  License  Version 3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE
       HAFTUNG übernommen.

       Wenn  Sie  Fehler  in  der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die
       Mailingliste der Übersetzer ⟨debian-l10n-german@lists.debian.org⟩.