Provided by:
manpages-pl-dev_20060617-1_all 
NAZWA
shmop - operacje na segmentach pamięci wspólnej
SKŁADNIA
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
OPIS
Funkcja shmat dołącza segment pamięci wspólnej o deskryptorze shmid do
przestrzeni adresowej procesu, który ją wywołał. Adres, pod którym
segment ma być widoczny jest przekazywany parametrem shmaddr, przy czym
system może przetworzyć ten adres w następujący sposób:
Jeśli shmaddr jest równy NULL, wówczas system sam wybierze odpowiedni
(nieużywany) adres, pod którym segment będzie widoczny.
Jeśli shmaddr nie jest równy NULL i w shmflg przekazany został znacznik
SHM_RND, wówczas segment zostanie dołączony pod adresem shmaddr
zaokrąglonym w dół do wielokrotności SHMLBA. W innym razie shmaddr
musi być wyrównanym do granicy strony adresem, pod którym nastąpi
dołączenie segmentu.
Jeśli w shmflg przekazany zostanie znacznik SHM_RDONLY, wówczas segment
zostanie odwzorowany z zabezpieczeniem przed zapisem. Proces wywołujący
shmat musi mieć prawa odczytu segmentu. W przeciwnym razie w
dołączanym segmencie możliwe są zarówno odczyt, jak i zapis, przy czym
proces musi mieć prawa do odczytu i zapisu segmentu. Nie istnieje
pojęcie segmentu pamięci wspólnej tylko do zapisu.
Znacznik (specyficzny dla Linuksa) SHM_REMAP, który może zostać
przekazany w shmflg oznacza, że odwzorowanie tego segmentu powinno
zastąpić jakiekolwiek istniejące wcześniej odwzorowanie w zakresie
rozpoczynającym się od shmaddr i rozciągającym na rozmiar segmentu.
(Normalnie, gdy odwzorowanie w tym zakresie adresów już istnieje,
powinien wystąpić błąd EINVAL.) W tym przypadku shmaddr nie może byc
równe NULL.
Wartość brk procesu wywołującego funkcję nie jest zmieniana podczas
dołączania segmentu. Segment zostanie automatycznie odłączony, gdy
proces zakończy się. Ten sam segment może być dołączony do przestrzeni
adresowej procesu jako "tylko do odczytu" lub "do odczytu i zapisu"
więcej niż raz.
W wyniku pomyślnego wywołania shmat system operacyjny aktualizuje pola
struktury shmid_ds opisującej segment w następujący sposób:
shm_atime zostaje przypisany aktualny czas.
shm_lpid zostanie przypisany identyfikator procesu wywołującego
shmat.
shm_nattch zostanie zwiększone o jeden.
Należy zwrócić uwagę, że operacja powiedzie się nawet jeśli dołączany
segment pamięci wspólnej jest zaznaczony do usunięcia.
Funkcja shmdt wyłącza segment pamięci wspólnej odwzorowany pod adresem
podanym w shmaddr z przestrzeni adresowej procesu wywołującego tę
funkcję. Przekazany funkcji w parametrze shmaddr adres musi być równy
adresowi zwróconemu wcześniej przez wywołanie shmat .
W wyniku pomyślnego wywołania shmdt pola struktury shmid_ds opisującej
segment aktualizowane są w następujący sposób:
shm_dtime przypisywany jest aktualny czas.
shm_lpid przypisywany jest identyfikator procesu wywołującego
shmdt.
shm_nattch jest zmniejszane o jeden. Jeśli pole to osiągnie 0 i
segment jest zaznaczony do usunięcia, wówczas zostanie on
usunięty.
Obszar w przestrzeni adresowej procesu wywołującego funkcję jest
zwalniany.
WYWOŁANIA SYSTEMOWE
fork() W wyniku wywołania fork() proces potomny dziedziczy dołączone
segmenty pamięci wspólnej.
exec() Po wykonaniu exec() wszystkie odwzorowane segmenty są odłączane
(nie są usuwane).
exit() Po wykonaniu exit() wszystkie dołączone segmenty pamięci
wspólnej są odłączane (nie są usuwane).
WARTOŚĆ ZWRACANA
W przypadku wystąpienia błędu opydwie funkcje zwracają -1 przypisując
zmiennej errno kod błędu. W wyniku poprawnego wykonania funkcja shmat
zwraca adres początku obszaru odwzorowania segmentu, natomiast funkcja
shmdt zwraca wartość 0.
BŁĘDY
Gdy shmat zakończy się niepomyślnie, zmiennej errno przypisywana jest
jedna z następujących wartości:
EACCES Proces wywołujący funkcję nie ma uprawnień do dołączenia
segmentu w zadany sposób (do odczytu lub odczytu / zapisu).
EINVAL Niewłaściwa wartość parametru shmid, niewyrównana do granicy
strony (i nie podano SHM_RND), niepoprawna wartość shmaddr,
nieudane dołączenie pod adresem brk lub został podany
znacznik SHM_REMAP, podczas gdy shmaddr jest równe NULL.
ENOMEM Brak pamięci na deskryptor lub tablice stron.
Funkcja shmdt może zakończyć się niepomyślnie tylko w sytuacji, gdy pod
adresem shmaddr nie istnieje segment pamięci wspólnej. Wowczas zmienna
errno przyjmie wartość EINVAL.
UWAGI
Używanie shmat z shmaddr równym NULL jest zalecaną, przenośną motodą
dołączania segmentu pamięci wspólnej. Trzeba jednak być świadomym, że
ta metoda dołączania segmentu pamięci wspólnej może spowodować jego
dołączenie pod różnymi adresami w różnych procesach. W związku z tym
wszystkie wskaźniki obsługiwane w pamięci wspólnej muszą być względne
(zazwyczaj względem adresu początkowego segmentu), nie zaś bezwzględne.
Dla wywołania shmat obowiązuje następujące ograniczenie systemowe:
SHMLBA Wartość, której wielokrotnością musi być adres dolnej
granicy segmentu. Musi być wyrównana do granicy strony. W
aktualnej implementacji SHMLBA jest równe PAGE_SIZE.
Aktualna implementacja nie ma wewnętrznego ograniczenia na ilość
segmentów pamięci wspólnej dołączanych do jednego procesu (SHMSEG).
ZGODNE Z
SVr4, SVID. SVr4 dokumentuje dodatkowy kod błędu EMFILE. W SVID-v4 typ
parametru shmaddr został zmieniony z char * na const void *, a typ
wyniku zwracanego przez shmat() z char * na void *. (Linuksowe libc4 i
libc5 zawierają prototypy char *; glibc2 zawiera void *.)
ZOBACZ TAKŻE
brk(2), ipc(5), mmap(2), shmctl(2), shmget(2).