mmap(2) mmap(2)
NAME
mmap, mmap64 - Speicherseiten abbilden
SYNTAX
#include <sys/mman.h>
void *mmap(void *addr, sizet len, int prot, int flags,
int fildes, offt off);
void *mmap64(void *addr, sizet len, int prot, int flags,
int fd, off64t offset);
BESCHREIBUNG
mmap() stellt eine Abbildung zwischen dem Adreßbereich eines Prozesses
und einer Datei her. Der Aufruf hat folgendes Format:
pa=mmap(addr, len, prot, flags, fildes, off);
mmap() stellt eine Abbildung zwischen dem Adreßbereich eines Prozesses
an der Adresse pa für len Bytes und der Datei, die durch den Dateide-
skriptor fildes angegeben wird, am Offset off für len Bytes her. Der
Wert von pa ist eine nicht definierte Funktion mit dem Argument addr
und Werten für flags. Ein erfolgreicher Aufruf von mmap() liefert pa
als Ergebnis zurück. Die Adreßbereiche, die durch [pa, pa + len) und
[off, off + len) abgedeckt werden, müssen für den möglichen (nicht
notwendigerweise den aktuellen) Adreßbereich eines Prozesses und die
in Frage kommende Datei zulässig sein.
Wenn sich die Größe der abgebildeten Datei nach dem Aufruf von mmap()
aufgrund anderer an der abgebildeten Datei vorgenommenen Operationen
ändert, ist das Verhalten bei Verweisen auf Abschnitte des abgebilde-
ten Bereichs, die hinzugefügten oder gelöschten Abschnitten in der
Datei entsprechen, unbestimmt.
Die Funktion mmap() wird für reguläre Dateien unterstützt. Bei Verwen-
dung auf andere Dateitypen ist das Verhalten unbestimmt.
Das Argument prot bestimmt, ob Lese-, Schreib- oder Ausführungszugriff
oder eine Kombination aus diesen Zugriffsberechtigungen für die abge-
bildeten Seiten erteilt werden soll. Die Zugriffsberechtigungsoptionen
sind in <sys/mman.h> wie folgt definiert:
PROTREAD Seite kann gelesen werden.
PROTWRITE Seite kann geschrieben werden.
PROTEXEC Seite kann ausgeführt werden.
PROTNONE Kein Zugriff auf die Seite.
Seite 1 Reliant UNIX 5.44 Gedruckt 11/98
mmap(2) mmap(2)
Die Implementierungen müssen nicht unbedingt alle Kombinationen der
Zugriffsberechtigungen unterstützen. Allerdings sollten Schreibopera-
tionen nur erlaubt sein, wenn PROTWRITE gesetzt wurde.
Das Argument flags bietet andere Informationen über die Behandlung von
abgebildeten Seiten. Die Optionen werden in <sys/mman.h> wie folgt
definiert:
MAPSHARED Änderungen gemeinsam benutzen.
MAPPRIVATE Änderungen sind privat.
MAPFIXED Adresse exakt interpretieren.
Die Flags MAPPRIVATE und MAPSHARED steuern die Anzeige von Schreib-
zugriffen auf die Speicherregion. Einer der Flags muß angegeben wer-
den, es dürfen jedoch nicht beide Flags zusammen angegeben werden. Der
Abbildungstyp wird nach einem fork() beibehalten und an den Sohnprozeß
vererbt.
Wenn MAPSHARED in flags angegeben ist, können durch den aufrufenden
Prozeß erfolgte Schreibzugriffe auf die Speicherregion die Datei
ändern und werden für jeden Prozeß in allen Abbildungen vom Typ
MAPSHARED desselben Abschnitts der Datei angezeigt.
Wenn MAPPRIVATE in flags angegeben ist, ändern durch den aufrufenden
Prozeß erfolgte Schreibzugriffe auf die Speicherregion die Datei nicht
und werden für keinen Prozeß in anderen Abbildungen desselben
Abschnitts der Datei angezeigt.
Es ist nicht definiert, ob Schreibzugriffe durch Prozesse, die die
Speicherregion mit MAPSHARED abgebildet haben, auch für Prozesse
angezeigt werden, die denselben Bereich der Datei mit MAPPRIVATE
abgebildet haben.
Ferner ist nicht definiert, ob Schreibzugriffe auf eine mit MAPSHARED
abgebildete Speicherregion für Prozesse angezeigt werden, die die
Datei nur lesen, und ob Schreiboperationen auf eine Datei für Prozesse
angezeigt werden, die den geänderten Abschnitt dieser Datei abgebildet
haben (ausgenommen der Auswirkungen von msync()).
Wenn MAPFIXED im Argument flags angegeben ist, wird die Implementie-
rung darüber informiert, daß der Wert von pa genau addr entsprechen
muß. Wenn MAPFIXED gesetzt ist, gibt mmap() möglicherweise (void *)-1
zurück und setzt errno auf EINVAL. Bei einer erfolgreichen MAPFIXED-
Anforderung, ersetzt die durch mmap() hergestellte Abbildung alle frü-
heren Abbildungen für die Seiten des Prozesses im Bereich [pa, pa +
len).
Seite 2 Reliant UNIX 5.44 Gedruckt 11/98
mmap(2) mmap(2)
Wenn MAPFIXED nicht angegeben ist, verwendet die Implementierung addr
in einer nicht angegebenen Weise, um pa zu erhalten. Die so gewählte
Adresse pa ist ein Bereich aus dem Adreßbereich, den die Implementie-
rung für die Abbildung von len Bytes auf die Datei für angemessen
hält. Alle Implementierungen interpretieren einen addr-Wert von Null
dahingehend, daß pa (unter Berücksichtigung der unten genannten Ein-
schränkungen) frei gewählt werden kann. Enthält addr einen Wert
ungleich Null, so wird dies als Vorschlag für eine Prozessoradresse
gewertet, in deren Nähe die Abbildung erfolgen soll. Wenn die Imple-
mentierung einen Wert für pa auswählt, so wird dies niemals die
Adresse 0 sein, noch werden Abbildungen ersetzt oder in Bereichen zur
dynamischen Speicherzuordnung plaziert.
Ausrichtung und Größe des Arguments off sind durch den Rückgabewert
von sysconf eingeschränkt, wenn SCPAGESIZE oder SCPAGESIZE über-
geben wird. Wenn MAPFIXED angegeben wird, muß das Argument addr eben-
falls diesen Einschränkungen entsprechen. Die Implementierung führt
Abbildungsoperationen über ganze Seiten aus. Da das Argument len nicht
an bestimmte Größen oder Ausrichtungen gebunden ist, bezieht die
Implementierung jede Restseite, die bei der Abbildungsoperation des
Bereiches [pa, pa + len) anfällt, mit in die Operation ein.
Die Implementierung füllt Teilseiten am Ende der Datei immer mit Nul-
len auf. Außerdem gibt die Implementierung niemals geänderte
Abschnitte der letzten Seite einer Datei aus, die über das Dateiende
hinausgehen. Erstreckt sich die von mmap() hergestellte Abbildung auf
Seiten, die über die Seite mit dem letzten Byte der Datei hinausgehen,
wird bei einem Anwendungsverweis auf eine dieser Abbildungsseiten, die
über die letzte Seite hinausgehen, ein SIGBUS- oder SIGSEGV-Signal
ausgegeben.
Die Funktion mmap() fügt einen zusätzlichen Verweis auf die durch den
Dateideskriptor fildes angegebene Datei hinzu; dieser Verweis wird bei
einem nachfolgenden close()-Aufruf für den Dateideskriptor nicht ent-
fernt. Der Verweis wird erst entfernt, wenn keine Abbildungen auf die
Datei mehr vorliegen.
Das Feld statime der abgebildeten Datei kann jederzeit zwischen dem
mmap()-Aufruf und dem zugehörigen munmap()-Aufruf zur Aktualisierung
gekennzeichnet werden. Der ursprüngliche Verweis für einen Lese- oder
Schreibzugriff auf einen abgebildeten Bereich führt dazu, daß das Feld
statime der Datei zur Aktualisierung gekennzeichnet wird, wenn dies
nicht bereits geschehen ist.
Die Felder stctime und stmtime einer mit MAPSHARED und PROTWRITE
abgebildeten Datei werden in der Zeit zwischen einem Schreibzugriff
auf den abgebildeten Bereich und dem nächsten, durch einen beliebigen
Prozeß ausgeführten Aufruf von msync() mit MSASYNC oder MSSYNC für
diesen Abschnitt der Datei, zur Aktualisierung gekennzeichnet. Wenn
kein entsprechender Aufruf erfolgt, können diese Felder jederzeit nach
einem Schreibzugriff zur Aktualisierung gekennzeichnet werden, wenn
die zugrundeliegende Datei aufgrund dieses Zugriffs geändert wird.
Seite 3 Reliant UNIX 5.44 Gedruckt 11/98
mmap(2) mmap(2)
In bezug auf die Anzahl der Speicherregionen, die (pro Prozeß oder pro
System) abgebildet werden können, kann es implementierungsspezifische
Grenzwerte geben. Liegt ein solcher Grenzwert vor, ist es von der
jeweiligen Implementierung abhängig, ob die Anzahl der Speicherregio-
nen, die von einem Prozeß abgebildet werden können, durch Verwendung
von shmat() herabgesetzt wird.
Es besteht kein funktionaler Unterschied zwischen mmap() und mmap64(),
außer bei der Interpretation von off64t [siehe lfs(5)].
RÜCKGABEWERT
Bei erfolgreicher Ausführung gibt mmap() die Adresse (pa) zurück, an
der die Abbildung abgelegt wurde. Andernfalls wird -1 zurückgegeben
und errno zur Anzeige des Fehlers gesetzt.
FEHLER
Die folgenden Beschreibungen der Fehlercodes sind funktionsspezifisch.
Eine allgemeingültige Beschreibung finden Sie in introprm2(2) bzw. in
errno(5).
Die Funktion mmap() schlägt bei folgenden Bedingungen fehl:
EBADF Das Argument fildes ist kein gültiger offener Dateide-
skriptor.
EACCES Das Argument fildes ist nicht zum Lesen geöffnet, unabhän-
gig von dem angegebenen Zugriffsschutzmechanismus, oder
fildes ist nicht zum Schreiben geöffnet und PROTWRITE
wurde für eine Abbildung vom Typ MAPSHARED angefordert.
ENXIO Adressen im Bereich [off, off + len) sind für fildes
ungültig.
EINVAL Das Argument addr (wenn MAPFIXED angegeben wurde) oder
off ist kein Vielfaches der Seitengröße, wie von sysconf()
zurückgeliefert, oder wird von der Implementierung als
ungültig angesehen.
EINVAL Der Wert von flags ist ungültig (weder MAPPRIVATE noch
MAPSHARED ist angegeben).
EINVAL Das ausgeführte Programm ist ein speziell vorabgeladenes
Programm. Das Argument addr liegt illegal zwischen den
Text- und Daten-Bereichen.
EMFILE Die Anzahl abgebildeter Bereiche würde eine implementie-
rungsabhängige Grenze überschreiten (pro Prozeß oder pro
System).
ENODEV Das Argument fildes verweist auf eine Datei, dessen Typ
von mmap() nicht unterstützt wird.
Seite 4 Reliant UNIX 5.44 Gedruckt 11/98
mmap(2) mmap(2)
ENOMEM MAPFIXED wurde angegeben, und der Bereich [addr, addr +
len) überschreitet den erlaubten Adreßbereich eines Pro-
zesses, oder MAPFIXED wurde nicht angegeben, und es gibt
nicht genügend Speicherplatz im Adreßbereich, um die
Abbildung wirksam werden zu lassen.
EOVERFLOW Die Datei ist eine reguläre Datei, und der Wert von off
plus len überschreitet das Offset-Maximum, das in der
fildes zugeordneten internen Beschreibung der offenen
Datei festgelegt ist.
HINWEISE
Durch die Verwendung von mmap() steht anderen Speicherzuordnungsfunk-
tionen möglicherweise weniger Speicher zur Verfügung.
Die Verwendung von MAPFIXED kann zu undefiniertem Verhalten in der
weiteren Verwendung von brk(), sbrk(), malloc() und shmat() führen.
Die Verwendung von MAPFIXED wird nicht empfohlen, da sie eine Imple-
mentierung davon abhalten kann, die Systemressourcen effektiv zu nut-
zen.
Die Anwendung muß für eine korrekte Synchronisierung sorgen, wenn
mmap() zusammen mit anderen Dateizugriffsmethoden, wie beispielsweise
read() und write(), Standard-Ein-/Ausgabe sowie shmat() verwendet wird.
mmap() erlaubt Zugriff auf Ressourcen über Adreßbereichsmanipulationen
anstelle der read/write-Schnittstelle. Wurde eine Datei abgebildet,
muß ein Prozeß lediglich auf die Daten an der Adresse zugreifen, an
der die Datei abgebildet wurde. Der folgende Pseudo-Code zeigt, wie
ein vorhandenes Programm für die Verwendung von mmap() geändert werden
kann. Der Code
fildes = open(...)
lseek(fildes, someoffset)
read(fildes, buf, len)
/* Daten im Puffer verwenden */
wird zu:
fildes = open(...)
address = mmap(0, len, PROTREAD, MAPPRIVATE, fildes, someoffset)
/* Daten an Adresse verwenden */
Damit die Konsistenz mit read() und write() gewahrt bleibt, schlägt
die Funktion mmap() fehl, wenn die Anforderung über das Offset-Maximum
hinausgeht.
SIEHE AUCH
exec(2), fcntl(2), fork(2), mprotect(2), munmap(2), plock(2),
shmat(2), lockf(3C), mlockall(3C), sysconf(3C), lfs(5), mman(5),
preload(8).
Seite 5 Reliant UNIX 5.44 Gedruckt 11/98