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