oracular (2) mmap.2.gz

Provided by: manpages-de-dev_4.23.1-1_all bug

BEZEICHNUNG

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

BIBLIOTHEK

       Standard-C-Bibliothek (libc, -lc)

ÜBERSICHT

       #include <sys/mman.h>

       void *mmap(void Adr[.laenge], size_t laenge, int prot, int Schalter,
                  int dd, off_t Versatz);
       int munmap(void Adr[.laenge], 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. Die Unterstützung für MAP_ANONYMOUS  mit  MAP_SHARED  wurde  in  Linux  2.4
              hinzugefügt.

       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  Linuxversionen,  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). Vor Linux 2.6 hatte dieser Schalter  nur  für  private,
              schreibbare Mappings eine Wirkung.

       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).  Die  Unterstützung für MAP_POPULATE zusammen mit privaten Mappings
              wurde in Linux 2.6.23 hinzugefügt.

       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.

       ENOMEM Wir mögen Adr nicht, da es den virtuellen Adressraum der CPU überschreitet.

       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 proc_sys(5).

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

VERSIONEN

       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.

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

STANDARDS

       POSIX.1-2008.

GESCHICHTE

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

       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.

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.

       Vor  Linux  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. Vor Linux  2.6.12  war  mmap()  in
       diesem  Fall  allerdings  erfolgreich: es wurde kein Mapping erstellt und der Aufruf lieferte Adr zurück.
       Seit Linux 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 <fcntl.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/mman.h>
       #include <sys/stat.h>
       #include <sys/types.h>
       #include <unistd.h>

       #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

       int
       main(int argc, char *argv[])
       {
           int          fd;
           char         *addr;
           off_t        offset, pa_offset;
           size_t       length;
           ssize_t      s;
           struct stat  sb;

           if (argc < 3 || argc > 4) {
               fprintf(stderr, "%s 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.

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