Provided by: manpages-de-dev_4.15.0-9_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  laenge  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. Der  Aufruf  mmap()  schlägt  nicht  fehl,
              falls   das   Mapping   nicht  belegt  werden  kann  (beispielsweise  aufgrund  von
              Beschränkungen der Anzahl der  gemappten  großen  Seiten  bei  der  Verwendung  von
              MAP_HUGETLB).  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 gesetzt, um den Fehler anzuzeigen.

       Bei  Erfolg liefert munmap() 0 zurück. Im Fehlerfall liefert es -1 und errno wird gesetzt,
       um den Fehler (wahrscheinlich EINVAL) anzuzeigen.

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).

       EPERM  Der   Schalter   MAP_HUGETLB   wurde  angegeben,  aber  der  Aufrufende  war  nicht
              privilegiert (verfügte  nicht  über  die  Capability  CAP_IPC_LOCK)  und  ist  kein
              Mitglied   der   Gruppe   sysctl_hugetlb_shm_group;   siehe  die  Beschreibung  von
              /proc/sys/vm/sysctl_hugetlb_shm_group in

       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.13  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⟩.