NAZWA¶
mmap, munmap - mapowanie lub usunięcie mapowania plików lub
urządzeń w pamięci
SKŁADNIA¶
#include <sys/mman.h>
#ifdef _POSIX_MAPPED_FILES
void * mmap(void *start, size_t length, int
prot , int flags, int fd, off_t
offset);
int munmap(void *start, size_t length);
#endif
OPIS¶
Uwaga! To tłumaczenie może być nieaktualne!
Funkcja
mmap zleca zamapowanie do pamięci, najchętniej pod
adres
start,
length bajtów pliku (lub innego obiektu)
zadanego przez deskryptor
fd, przesuniętych względem
początku o
offset. Adres
start jest jednak tylko
propozycją i zazwyczaj jest przekazywany jako 0. Rzeczywiste miejsce
zamapowania obiektu jest zwracane przez
mmap i nigdy nie jest zerem.
Argument
prot opisuje oczekiwany sposów ochrony pamięci (i
nie może być sprzeczny z trybem otwarcia pliku). Może on
być równy
PROT_NONE lub może być logicznym
OR jednego lub więcej spośród innych znaczników
PROT_*.
- PROT_EXEC
- Strony mogą być wykonywane.
- PROT_READ
- Strony mogą być odczytywane.
- PROT_WRITE
- Strony mogą być zapisywane.
- PROT_NONE
- Strony nie mogą być dostępne.
Patametr
flags określa rodzaj mapowanego obiektu, opcje mapowania
i czy modyfikacje na zmapowanej kopii strony są prywatne dla procesu,
czy też powinny być współdzielone z innymi
odniesieniami. Ma on bity
- MAP_FIXED
- Polecenie nie wybierania innego adresu niż podany. Jeśli
podanego adresu nie można użyć, mmap
zawiedzie. Jeśli podano MAP_FIXED, start musi być
wielokrotnością rozmiaru strony. Używanie tej opcji
nie jest zalecane.
- MAP_SHARED
- Polecenie współdzielenia mapowania ze wszystkimi innymi
procesami, które mapują ten obiekt. Zapisywanie danych w
danym obszarze będzie równoważne z zapisywaniem do
pliku. Plik może w rzeczywistości nie zostać
zaktualizowany aż do wywołania msync(2) lub
munmap(2).
- MAP_PRIVATE
- Polecenie utworzenia prywatnego mapowania, typu "kopiowanie podczas
zapisu". Zapisywanie danych w danym obszarze nie będzie
wpływać na zawartość oryginalnego pliku. Nie
jest określone, czy zmiany zawartości pliku wykonane po
wywołaniu mmap będą uwidocznione w mapowanym
obszarze.
Trzeba podać dokładnie jedno spomiędzy MAP_SHARED i
MAP_PRIVATE.
Powyższe trzy znaczniki są opisane w POSIX.1b (poprzednio POSIX.4)
oraz SUSv2. Linux obsługje dodatkowo następujące
znaczniki niestandardowe:
- MAP_DENYWRITE
- Ten znacznik jest ignorowany. (Dawno temu sygnalizował on,
że próba zapisu to mapowanego pliku powinna
zawieść z ETXTBUSY. Ale było to
źródłem ataków blokujących
usługę (DoS).)
- MAP_EXECUTABLE
- Ten znacznik jest ignorowany.
- MAP_NORESERVE
- (Używany łącznie z MAP_PRIVATE.) Poleca nie
rezerwować stron przestrzeni wymiany dla tego mapowania. Gdy
przestrzeń wymiany jest zarezerwowana, ma się
gwarancję, że istnieje możliwość
modyfikacji tego prywatnego "kopiowanego podczas zapisu"
obszaru. Gdy nie jest ona zarezerwowana, można otrzymać
SIGSEGV podczas zapisu, jeżeli braknie pamięci.
- MAP_LOCKED
- Ten znacznik jest ignorowany.
- MAP_GROWSDOWN
- Używany do stosów. Sygnalizuje systemowi zarządzania
pamięcią wirtualną w jądrze, że to
mapowanie powinno być rozszerzane w pamięci w
dół.
- MAP_ANONYMOUS
- Mapowanie nie jest oparte na żadnym pliku; argumenty fd i
offset zostaną zignorowane. Ten znacznik w
połączeniu z MAP_SHARED jest zaimplementowany w Linuksie
począwszy od 2.4.
- MAP_ANON
- Alias dla MAP_ANONYMOUS. Porzucony.
- MAP_FILE
- Znacznik służący zgodności. Ignorowany.
- MAP_32BIT
- Umieszczenie mapowania w pierwszych 2GB przestrzeni adresowej procesu.
Ignorowany gdy ustawiony jest MAP_FIXED. Znacznik ten jest obecnie
wspierany jedynie przez 64-bitowe programy na architekturze x86-64.
Niektóre systemy dokumentują dodatkowe znaczniki MAP_AUTOGROW,
MAP_AUTORESRV, MAP_COPY i MAP_LOCAL.
fd powinno być prawidłowowym deskryptorem pliku;
jeżeli ustawiono MAP_ANONYMOUS, to argument ten jest ignorowany.
offset powinno być wielokrotnością rozmiaru strony
zwracanego przez
getpagesize(2).
Pamięć zamapowana za pomocą
mmap jest zachowywana
poprzez
fork(2) z tymi samymi atrybutami.
Plik jest mapowany w wielokrotnościaćh rozmiaru strony. Dla
plików, które nie są wielokrotnościami rozmiaru
strony, pozostała pamięć jest zerowana podczas mapowania,
a zapisy do tego obszaru nie są zapisywane w pliku. Efektem zmiany
rozmiaru zamapowanego pliku na zamapowane strony, które
odpowiadają dodanym lub usuniętym obszarom pliku, jest
nieokreślony.
Funkcja systemowa
munmap usuwa mapowanie z podanego zakresu
adresów i powoduje, że dalsze odwołania do adresów
z tego zakresu będą generować nieprawidłowe
odwołania do pamięci. Mapowanie obszaru jest
również automatycznie usuwane, gdy proces się
zakończy. Z drugiej strony, zamknięcie deskryptora pliku nie
usuwa mapowania obszaru.
Adres
start musi być wielokrotnością rozmiaru
strony. Usuwane jest mapowanie wszystkich stron zawierających fragmenty
ze wskazanego zakresu, wszystkie późniejsze odwołania do
tych stron wygenerują SIGSEGV. Nie jest błędem, gdy brak
w podanym zakresie zamapowanych stron.
Dla mapowań opartych na plikach pole
st_atime zamapowanego pliku
może zostać zaktualizowane w dowolnym momencie pomiędzy
mmap() i usunięciem odpowiedniego mapowania; pierwsze
odwołanie do zamapowanej strony spowoduje zaktualizowanie tego pola,
jeśli nie stało się to wcześniej.
Pola
st_ctime i
st_mtime pliku zamapowanego z PROT_WRITE i
MAP_SHARED zostanie zaktualizowane po zapisie do mapowanego obszaru, a przed
późniejszym wywołaniem
msync() ze znacznikiem
MS_SYNC lub MS_ASYNC, jeśli taki wywołanie wystąpi.
WARTOŚĆ ZWRACANA¶
Po pomyślnym zakończeniu B mmap zwraca wskaźnik do
mapowanego obszaru. Po błędzie zwracane jest MAP_FAILED (-1) i
odpowiednio ustawiane jest
errno. Po pomyślnym
zakończeniu
munmap zwraca 0, a po błędzie -1 i
ustawia
errno (prawdopodobnie na EINVAL).
UWAGI¶
To, czy
PROT_READ zawiera
PROT_EXEC, czy nie, zależy od
architektury. W przenośnych programach należy zawsze
ustawiać
PROT_EXEC, gdy planowane jest uruchamianie przez nie
kodu w nowym mapowaniu.
BŁĘDY¶
- EBADF
- fd nie jest prawidłowym deskryptorem pliku (a nie ustawiono
MAP_ANONYMOUS).
- EACCES
- Deskryptor pliku nie odnosi się do zwykłego pliku. Lub
zgłoszono MAP_PRIVATE, lecz fd nie jest otwarty dla odczytu.
Lub zgłoszono MAP_SHARED i ustawiono PROT_WRITE, a fd nie
jest otwarte w trybie odczytu i zapisu (O_RDWR). Lub zgłoszono
PROT_WRITE, lecz plik jest otwarty tylko do dopisywania.
- EINVAL
- Niewłaściwe start, length lub offset.
(Np., mogą być zbyt duże lub niewyrównane do
granicy strony (PAGESIZE).)
- ETXTBUSY
- Ustawiono MAP_DENYWRITE, lecz obiekt wskazywany przez fd jest
otwarty do zapisu.
- EAGAIN
- Plik został zablokowany lub zablokowano zbyt wiele
pamięci.
- ENOMEM
- Brak dostępnej pamięci lub zostałaby przekroczona
maksymalna liczba mapowań dla procesu. ENODEV System
plików, na którym znajduje sie podany plik nie wspiera
mapowania w pamięci.
Użycie zamapowanego obszaru może spowodować
wystąpienie następujących sygnałów:
- SIGSEGV
- Próba zapisu do obszaru podanego dla mmap jako tylko do
odczytu.
- SIGBUS
- Próba dostępu do fragmentu bufora, który nie
odpowiada plikowi (na przykład, za końcem pliku,
włączając w to przypadek obcięcia pliku przez
inny process).
ZGODNE Z¶
SVr4, POSIX.1b (poprzednio POSIX.4), 4.4BSD, SUSv2. SVr4 dokumentuje dodatkowe
błędy ENXIO i ENODEV. SUSv2 dokumentuje dodatkowe
błędy EMFILE i EOVERFLOW.
MAP_32BIT jest rozszerzeniem linuksowym.
ZOBACZ TAKŻE¶
getpagesize(2),
mmap2(2),
mremap(2),
msync(2),
shm_open(2), B.O. Gallmeister, POSIX.4, O'Reilly, str. 128-129 i
389-391.
Powyższe tłumaczenie pochodzi z nieistniejącego już
Projektu Tłumaczenia Manuali i
może nie być
aktualne. W razie zauważenia różnic między
powyższym opisem a rzeczywistym zachowaniem opisywanego programu lub
funkcji, prosimy o zapoznanie się z oryginalną
(angielską) wersją strony podręcznika za pomocą
polecenia:
- man --locale=C 2 mmap
Prosimy o pomoc w aktualizacji stron man - więcej informacji można
znaleźć pod adresem
http://sourceforge.net/projects/manpages-pl/.