Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

mmap, mmap64 - Speicherseiten abbilden

&pagelevel(4)&pagelevel

Definition

#include <sys/mman.h>

void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
void *mmap64(void *addr, size_t len, int prot, int flags, int fildes, off64_t off);

Beschreibung

mmap() stellt eine Abbildung zwischen dem Adressbereich eines Prozesses ( [pa, pa + len)) und einem Dateiabschnitt her ([off, off + len)).

Der Aufruf hat folgendes Format:

pa = mmap(addr, len, prot, flags, fildes, off);

Zwischen dem Adressraum des Prozesses an der Adresse pa für len Bytes einerseits und der durch den Dateideskriptor fildes beschriebenen Datei mit dem Offset off für len-Bytes andererseits wird eine Abbildung hergestellt. Der Wert von pa ist eine implementierungsabhängige Funktion von addr und dem Wert flags. Ein erfolgreicher Aufruf von mmap() liefert pa als Ergebnis zurück. Die Adressbereiche, die durch [pa, pa + len) und [off, off + len) definiert werden, müssen für den möglichen (nicht notwendigerweise den aktuellen) Adressbereich des Prozesses bzw. der Datei zulässig sein. mmap() kann eine Datei nicht vergrößern.

Die Abbildung, die durch mmap() mit MAP_FIXED hergestellt wird, ersetzt alle vorhergehenden Abbildungen für die Seiten des Prozesses im Bereich [pa, pa + len).

Wenn die Größe der abgebildeten Datei nach dem Aufruf von mmap() verändert wird, ist nicht festgelegt, welchen Effekt Referenzen auf Abbildungsteile haben, die zu einem neu hinzugekommenen oder gelöschten Teil der Datei korrespondieren.

mmap() wird nur für normale Dateien unterstützt.

Der Parameter prot bestimmt, ob gelesen, geschrieben, ausgeführt oder Kombinationen dieser Zugriffe auf die abgebildeten Seiten erlaubt werden sollen. Die Zugriffsrechte werden in sys/mman.h wie folgt definiert:

PROT_READ

Seite kann gelesen werden.

PROT_WRITE

Seite kann geschrieben werden..

PROT_EXEC

Seite kann ausgeführt werden.

PROT_NONE

auf Seite kann nicht zugegriffen werden.

PROT_WRITE ist als PROT_WRITE|PROT_EXEC implementiert und PROT_EXEC als PRO-T_READ|PROT_EXEC.

Drei Zustände sind möglich:

  • Seite ist nicht zugreifbar

  • auf die Seite kann nur lesend zugegriffen werden

  • auf die Seite kann lesend und schreibend zugegriffen werden

Das Verhalten von PROT_WRITE kann durch die Option MAP_PRIVATE in dem Parameter flags beeinflusst werden, wie weiter unten noch näher beschrieben wird.

Der Parameter flags enthält weitere Informationen über die Behandlung der abgebildeten Seiten. Die Optionen werden in sys/mman.h wie folgt definiert:

MAP_SHARED

Änderungen sind gemeinsam benutzbar

MAP_PRIVATE

Änderungen sind privat

MAP_FIXED

addr ist exakt zu interpretieren

MAP_SHARED und MAP_PRIVATE kontrollieren die Sichtbarkeit von Schreibzugriffen auf die Speicherseiten. Es muss entweder MAP_SHARED oder MAP_PRIVATE angegeben werden.Der Abbildungstyp wird nach einem fork() beibehalten.

Wenn MAP_SHARED angegeben wird, ändern Schreibzugriffe auf die Speicherseiten die Datei, und die Änderungen sind in allen mit MAP_SHARED hergestellten Abbildungen des entsprechenden Dateiabschnittes sichtbar.

Wenn MAP_PRIVATE angegeben wird, ändern Schreibzugriffe auf die Speicherseiten nicht die Datei, und die Änderungen sind für keinen anderen Prozess sichtbar, der den entsprechenden Dateiabschnitt abbildet. Der erste Schreibzugriff erzeugt eine privat gehaltene Kopie der Speicherseiten und leitet die Abbildung auf die Kopie um. Beachten Sie, dass die privat gehaltene Kopie erst beim ersten Schreibzugriff erzeugt wird; bis dahin können andere Benutzer, die den Dateiabschnitt mit MAP_SHARED abgebildet haben, den Dateiabschnitt ändern.

MAP_FIXED legt fest, dass der Wert von pa genau addr entsprechen muss. Die Benutzung von MAP_FIXED wird nicht empfohlen, da dieser Parameter eine effektive Nutzung der Systemressourcen verhindern kann.

Wenn MAP_FIXED nicht gesetzt ist, wird implementierungsabhängig eine Adresse pa zurückgegeben, indem ein Bereich aus dem Adressraum des Prozesses ausgewählt wird, den das System zur Abbildung von len-Bytes für passend hält. Ein addr-Wert von null bedeutet, dass pa unter Einhaltung der unten beschriebenen Bedingungen frei gewählt werden kann. Enthält addr einen Wert ungleich null, so wird dies als Vorschlag gewertet, die Abbildung nahe an dieser Adresse zu wählen. In keinem Fall wird für pa der Wert 0 ausgewählt, eine bestehende Abbildung überschrieben oder in dynamisch zugewiesene Speicherbereiche abgebildet.

Der Parameter off unterliegt bezüglich Größe und Ausrichtung Beschränkungen, die sich nach dem Rückgabewert von sysconf() bezüglich der Parameter _SC_PAGESIZE und _SC_PAGE_SIZE richten. Wenn MAP_FIXED angegeben wird, muss der Parameter addr ebenfalls diese Beschränkungen einhalten.

Das System führt Abbildungsoperationen über ganze Seiten aus. Da der Parameter len nicht an bestimmte Größen oder Ausrichtungen gebunden ist, bezieht das System jede Restseite, die bei der Abbildung des Bereiches [pa, pa + len) anfällt, mit in die Abbildungsoperation ein. Das System füllt solche Teilseiten am Ende eines Speicherbereiches [pa, pa + len) mit Nullen. Veränderungen dieses Bereichs werden nicht zurückgeschrieben. Falls sich die Abbildung auf ganze Seiten erstreckt, die hinter dem letzten Byte der Datei liegen, erzeugen Referenzen auf diese Seiten ein SIGSEGV-Signal. SIGSEGV-Signale können außerdem bei verschiedenen Fehlerbedingungen des Dateisystems gesendet werden, einschließlich der Überschreitung des Quotas.

mmap() erzeugt eine zusätzliche Referenz auf die Datei, die durch fildes beschrieben wird. Diese Referenz wird bei einem close() auf fildes nicht gelöscht, sondern erst, wenn keine Abbildung mehr auf die Datei existiert.

Es besteht kein funktioneller Unterschied zwischen mmap() und mmap64(), außer dass mmap64() einen off64_t Typ verwendet.


Returnwert

 pa

Adresse, an der die Abbildung platziert wurde.

 

-1

bei Fehler. errno wird gesetzt, um den Fehler anzuzeigen.

Fehler

mmap() und mmap64() schlagen fehl, wenn gilt:

 

EACCES

fildes ist nicht zum Lesen geöffnet, unabhängig von dem angegebenen prot-Argument, oder fildes ist nicht zum Schreiben geöffnet und bei einer Abbildung vom Typ MAP_SHARED wurde PROT_WRITE angefordert.

 

EAGAIN

Die Abbildung kann im Speicher nicht gesperrt werden.

 

EBADF

fildes ist kein gültiger offener Dateideskriptor.

 

ENXIO

Adressen im Bereich [off, off + len) sind für fildes ungültig.

 

EINVAL

Das Argument off (oder addr, wenn MAP_FIXED angegeben wurde) enthält kein Vielfaches der von sysconf() zurückgelieferten Seitenlänge, oder off bzw. addr hat einen ungültigen Wert.

Der Wert in flags ist ungültig (weder MAP_PRIVATE noch MAP_SHARED ist gesetzt).

Das Argument len hat einen Wert kleiner oder gleich 0.

 

EMFILE

Die Anzahl der Abbildungen überschreitet den maximal zulässigen Wert.

 

ENOMEM

MAP_FIXED wurde angegeben, und der Bereich [addr, addr + len) überschreitet den für einen Prozess erlaubten Adressbereich, oder
MAP_FIXED wurde nicht angegeben, aber es steht nicht genügend Speicherplatz im Adressbereich für die Abbildung zur Verfügung.


ENODEV

fildes bezieht sich auf eine Datei, deren Typ von mmap() nicht unterstützt wird, wie zum Beispiel eine Gerätedatei.


EOVERFLOW

Der Wert von off plus len überschreitet das Offset-Maximum, das in der fildes  zugeordneten internen Beschreibung der offenen Datei festgelegt ist.

Hinweise

Die Verwendung von mmap() verringert den Speicherplatz, der für andere Funktionen zur Verfügung steht, die ebenfalls Speicherplatz belegen.

Die Angabe MAP_FIXED wird nicht empfohlen, da dieser Parameter eine effektive Nutzung der Systemressourcen verhindern kann.

Die Anwendung muss auf eine Synchronisation der Dateizugriffe achten, wenn mmap() zusammen mit anderen Dateizugriffsmethoden wie read(), write(), Standardein/-ausgabe und shmat() verwendet wird.

mmap() erlaubt Zugriff auf Ressourcen über Adressbereichsmanipulationen an Stelle der read/write-Schnittstelle. Wird eine Datei abgebildet, muss ein Prozess lediglich auf die Adresse zugreifen, an die das Dateiobjekt abgebildet wird. Man betrachte den folgenden (unvollständigen) Code:

fildes = open(...)
lseek(fildes, some_offset)
read(fildes, buf, len)
   /* Daten in buf verwenden */

Unter Verwendung von mmap() kann der Code folgendermaßen umgeschrieben werden:

fildes = open(...)
address =mmap(0, len, PROT_READ, MAP_PRIVATE, fildes, some_offset)
   /* Daten über address verwenden */

Siehe auch

exec(), fcntl(), fork(), lockf(), munmap(), msync(), mprotect(), shmat(), sysconf(), sys/mman.h.