NAZWA¶
shmat, shmdt - operacje na segmentach pamięci dzielonej Systemu V
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¶
shmat()¶
shmat() dołącza segment pamięci dzielonej
  Systemu V identyfikowany przez 
shmid do przestrzeni adresowej
  procesu, który ją wywołał. Adres, pod
  którym segment ma być widoczny jest przekazywany w parametrze
  
shmaddr, przy czym system może przetworzyć ten adres w
  następujący sposób:
  - *
 
  - Jeśli shmaddr jest równy NULL, to system sam wybierze
      odpowiedni (nieużywany) adres, pod którym segment
      będzie widoczny.
 
  - *
 
  - Jeśli shmaddr jest różny od 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 przypadku shmaddr musi być wyrównanym do
      granicy strony adresem, pod którym nastąpi
      dołączenie segmentu.
 
Oprócz 
SHM_RND można
  określić następujące flagi w argumencie
  maski bitowej 
shmflg:
  - SHM_EXEC (charakterystyczne dla Linuksa; od Linuksa w wersji
    2.6.9)
 
  - Pozwala na wykonanie zawartości segmentu. Wywołujący
      musi mieć prawo wykonania segmentu.
 
  - SHM_RDONLY
 
  - Dołącza segment do dostępu tylko do odczytu. Proces
      wywołujący musi mieć prawa odczytu segmentu.
      Jeśli flaga nie jest określona, w dołączanym
      segmencie możliwy jest dostęp do odczytu jak i zapisu, przy
      czym proces musi mieć prawa do odczytu i zapisu segmentu. Nie
      istnieje pojęcie segmentu pamięci dzielonej tylko do
    zapisu.
 
  - SHM_REMAP (charakterystyczne dla Linuksa)
 
  - Ten znacznik 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 się 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 być
      równy NULL.
 
Wartość 
brk(2) procesu wywołującego nie jest
  zmieniana podczas dołączania segmentu. Segment zostanie
  automatycznie odłączony, gdy proces się zakończy.
  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.
Pomyślne wywołanie 
shmdt aktualizuje pola struktury
  
shmid_ds (patrz 
shmctl(2)) opisującej segment w
  następujący sposób:
  
  - shm_atime przypisywany jest bieżący czas.
 
  
  - shm_lpid jest ustawiane na identyfikator procesu
      wywołującego.
 
  
  - shm_nattch jest zwiększane o jeden.
 
shmdt()¶
shmdt odłącza segment pamięci dzielonej 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().
Pomyślne wywołanie 
shmdt aktualizuje pola struktury
  
shmid_ds opisującej segment w następujący
  sposób:
  
  - shm_dtime przypisywany jest bieżący czas.
 
  
  - shm_lpid jest ustawiane na identyfikator procesu
      wywołującego.
 
  
  - 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.
 
WARTOŚĆ ZWRACANA¶
Jeśli się powiedzie, 
shmat() zwraca adres
  dołączonego segmentu pamięci dzielonej; w razie
  błędu zwracane jest 
(void *) -1, a zmienna
  
errno wskazuje na przyczynę błędu.
Jeśli się powiedzie, 
shmdt() zwraca 0; w razie
  błędu zwracane jest -1, a zmienna 
errno wskazuje na
  przyczynę błędu.
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 nie ma wystarczających
      uprawnień do dołączenia segmentu w
      żądany sposób oraz nie ma ustawionego atrybutu
      CAP_IPC_OWNER.
 
  - EIDRM
 
  - shmid wskazuje na usunięty identyfikator.
 
  - EINVAL
 
  - Niewłaściwa wartość parametru shmid,
      niewyrównana (do granicy strony i nie podano SHM_RND) lub
      niepoprawna wartość shmaddr albo nieudane
      dołączenie pod adresem shmaddr lub został
      podany znacznik SHM_REMAP, podczas gdy shmaddr było
      równe NULL.
 
  - ENOMEM
 
  - Brak pamięci na deskryptor lub tablice stron.
 
Gdy 
shmdt() zakończy się niepomyślnie, zmiennej
  
errno przypisywana jest jedna z następujących
  wartości:
  - EINVAL
 
  - Żaden segment pamięci dzielonej nie jest
      podłączony pod adresem shmaddr lub shmaddr nie
      jest wyrównany do granicy strony.
 
ZGODNE Z¶
SVr4, POSIX.1-2001.
W SVID 3 (lub być może wcześniejszym) typ parametru
  
shmaddr został zmieniony z 
char * na 
const
  void *, a typ wyniku zwracanego przez 
shmat() z
  
char * na 
void *.
UWAGI¶
W wyniku wywołania 
fork(2) proces potomny dziedziczy
  dołączone segmenty pamięci dzielonej.
Po wykonaniu 
exec(2) wszystkie dołączone segmenty
  pamięci dzielonej są odłączane od procesu.
Po wykonaniu 
_exit(2) wszystkie dołączone segmenty
  pamięci dzielonej są odłączane od procesu.
Używanie 
shmat() z 
shmaddr równym NULL jest
  zalecaną i przenośną metodą
  dołączania segmentu pamięci dzielonej. Trzeba jednak
  być świadomym, że ta metoda dołączania
  segmentu pamięci dzielonej 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 dzielonej muszą
  być względne (zazwyczaj względem adresu
  początkowego segmentu), nie zaś bezwzględne.
Linux pozwala na dołączenie segmentu pamięci dzielonej,
  nawet jeśli już został zaznaczony do usunięcia.
  Jednakże POSIX.1-2001 nie określa takiego zachowania i wiele
  innych implementacji go nie obsługuje.
Na wywołanie 
shmat() wpływa następujący
  parametr systemowy:
  - SHMLBA
 
  - Wielokrotność dolnej granicy adresu segmentu. Podczas
      bezpośredniego wskazania dołączonego adresu w
      wywołaniu do shmat(), wywołujący powinien
      się upewnić, że adres jest
      wielokrotnością tej wartości. Jest to konieczne w
      przypadku niektórych architektur, aby zapewnić dobrą
      wydajność pamięci podręcznej procesora lub aby
      zapewnić, że różne dołączenia
      tego samego segmentu mają spójne widoki w pamięci
      podręcznej procesora. SHMLBA jest zwykle jakąś
      wielokrotnością systemowego rozmiaru strony (w wielu
      architekturach linuksowym jest to wprost systemowy rozmiar strony).
 
Aktualna implementacja nie ma wewnętrznego ograniczenia na liczbę
  segmentów pamięci dzielonej dołączanych do jednego
  procesu ( 
SHMSEG).
ZOBACZ TAKŻE¶
brk(2), 
mmap(2), 
shmctl(2), 
shmget(2),
  
capabilities(7), 
shm_overview(7), 
svipc(7)
O STRONIE¶
Angielska wersja tej strony pochodzi z wydania 3.71 projektu Linux
  
man-pages. Opis projektu, informacje dotyczące zgłaszania
  błędów, oraz najnowszą wersję
  oryginału można znaleźć pod adresem
  
http://www.kernel.org/doc/man-pages/.
TŁUMACZENIE¶
Autorami polskiego tłumaczenia niniejszej strony podręcznika man
  są: Rafał Lewczuk (PTM) <R.Lewczuk@elka.pw.edu.p>, Andrzej
  Krzysztofowicz (PTM) <ankry@mif.pg.gda.pl>, Robert Luberda
  <robert@debian.org> i Michał Kułach
  <michal.kulach@gmail.com>.
Polskie tłumaczenie jest częścią projektu
  manpages-pl; uwagi, pomoc, zgłaszanie błędów na
  stronie 
http://sourceforge.net/projects/manpages-pl/. Jest zgodne z
  wersją 
 3.71 oryginału.