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