BEZEICHNUNG¶
shmat, shmdt - Operationen mit gemeinsam benutztem Speicher
ÜBERSICHT¶
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
BESCHREIBUNG¶
shmat() blendet das durch 
shmid bezeichnete gemeinsame
  Speichersegment in den Adressraum des aufrufenden Prozesses ein. Die Adresse
  der Enblendung wird durch 
shmaddr nach einem der folgenden Kriterien
  bestimmt:
Falls 
shmaddr NULL ist, wählt das System eine geeignete (freie)
  Adresse, an der das Segment eingeblendet wird.
Wenn 
shmaddr nicht NULL ist und 
SHM_RND in 
shmflg angegeben
  ist, wird die Adresse durch Abrundung von 
shmaddr als Vielfaches von
  
SHMLBA bestimmt. Andernfalls muss 
shmaddr eine an einer
  Speicherseite ausgerichtete Adresse sein, an welcher das Einblenden beginnt.
Ist 
SHM_RDONLY in 
shmflg gesetzt, wird das Segment zum Lesen
  eingeblendet und der Prozess muss die Berechtigung für Lesezugriffe auf
  das Segment besitzen. Andernfalls wird das Segment zum Lesen und Schreiben
  eingeblendet und der Prozess muss die Berechtigung für Lese- und
  Schreibzugriffe auf das Segment besitzen. Ein gemeinsames Speichersegment mit
  reinem Schreibzugriff ist nicht vorgesehen.
Mit dem (Linux-spezifischen) Schalter 
SHM_REMAP in 
shmflag
  können Sie bestimmen, dass das Abbilden des Segments jede vorhandene
  Abbildung im Bereich von 
shmaddr bis zum Ende des Segments ersetzt.
  (Falls bereits eine Abbildung in diesem Adressbereich existiert, würde
  dies normalerweise zu dem Fehler 
EINVAL führen.) In diesem Fall
  darf 
shmaddr nicht NULL sein.
Der 
brk(2)-Wert des aufrufenden Prozesses wird durch das Einblenden nicht
  verändert. Das Segment wird bei Beenden des Prozesses automatisch
  abgetrennt. Das gleiche Segment kann mit Lese- sowie mit Lese- und
  Schreibzugriff einmal oder mehrfach an den Adressraum des Prozesses
  eingeblendet werden.
Nach einem erfolgreichen 
shmat()-Aufruf aktualisiert das System die
  Bestandteile der dem Speichersegment zugeordneten 
shmid_ds-Struktur
  (siehe 
shmctl(2)) wie folgt:
  
  - shm_atime wird auf die aktuelle Zeit gesetzt.
 
  
  - shm_lpid wird auf die Prozess-ID des aufrufenden
      Prozesses gesetzt.
 
  
  - shm_nattch wird um eins erhöht.
 
shmdt() löst das gemeinsame Speichersegment, das an der Adresse
  
shmaddr liegt aus dem Adressraum des aufrufenden Prozesses. Das zu
  entfernende gemeinsame Speichersegment muss momentan mit 
shmaddr
  eingeblendet sein, das dem Rückgabewert des einbendenden
  
shat()-Aufrufs entspricht.
Nach einem erfolgreichen 
shmdt()-Aufruf aktualisiert das System die
  Bestandteile der dem Speichersegment zugeordneten Struktur 
shmid_ds wie
  folgt:
  
  - shm_dtime wird auf die aktuelle Zeit gesetzt.
 
  
  - shm_lpid wird auf die Prozess-ID des aufrufenden
      Prozesses gesetzt.
 
  
  - shm_nattch wird um eins verringert. Wenn es dabei zu
      0 wird und das Segment zum Löschen markiert ist, wird es
      gelöscht.
 
Nach einem 
fork(2) erbt der Kindprozess das eingeblendete gemeinsame
  Speichersegment.
 
Nach einem 
exec(2) sind alle eingeblendeten gemeinsamen Speichersegmente
  vom Prozess abgelöst.
 
Bei einem 
exit(2) sind alle eingeblendeten gemeinsamen Speichersegmente
  vom Prozess abgelöst.
RÜCKGABEWERT¶
Bei Erfolg gibt 
shmat() die Adresse des eingeblendeten gemeinsamen
  Speichersegments zurück; bei einem Fehler wird
  
(void *) -1 zurückgegeben und 
errno so gesetzt,
  dass es den Grund des Fehlers anzeigt.
 
Bei Erfolg gibt 
shmdt() 0 zurück; bei einem Fehler wird -1
  zurückgegeben und 
errno so gesetzt, dass es den Grund des Fehlers
  anzeigt.
FEHLER¶
Wenn 
shmat fehlschlägt, wird 
errno mit einem der folgenden
  Werte belegt:
  - EACCES
 
  - Dem aufrufenden Prozess fehlen die nötigen
      Zugriffsrechte für den angeforderten Einblendetyp und die
      CAP_IPC_OWNER-Fähigkeit.
 
  - EINVAL
 
  - ungültiger shmid-Wert, nicht ausgerichteter
      (d.h. nicht an die Seitengröße angepasst und SHM_RND
      wurde nicht angegeben) oder ungültiger shmaddr-Wert oder es
      wurde SHM_REMAP angegeben und shmaddr war NULL.
 
  - ENOMEM
 
  - Es konnte kein Speicher für den Deskriptor oder die
      Seitentabellen reserviert werden.
 
Wenn 
shmat() fehlschlägt, ist 
errno mit einem der folgenden
  Werte belegt:
  - EINVAL
 
  - Es ist kein gemeinsames Speichersegment an shmaddr
      eingeblendet oder shmaddr ist nicht an der Seitengrenze
      ausgerichtet.
 
SVr4, POSIX.1-2001.
 
In SVID 3 (oder vielleicht früher) wurde der Typ des Arguments
  
shmaddr von 
char * in 
const void * und der von
  
shmat() zurückgegebene Typ von 
char * in 
void *
  geändert. (Linux-Libc4 und -Libc5 haben die 
char *-Prototypen,
  Glibc2 hat 
void *.)
ANMERKUNGEN¶
Die bevorzugte, portierbare Möglichkeit ein gemeinsames Speichersegment
  einzublenden besteht darin, 
shmat() mit 
shmaddr gleich NULL zu
  benutzen. Sie sollten wissen, dass das eingeblendete gemeinsame
  Speichersegment auf diese Art an unterschiedliche Adressen in
  unterschiedlichen Prozessen eingeblendet werden kann. Deshalb müssen alle
  innerhalb des gemeinsamen Speichers verwalteten Zeiger relativ (typischerweise
  zur Startadresse des Segments) statt absolut sein.
Auf Linux ist es möglich, sogar ein gemeinsames Speichersegment
  einzublenden, wenn es bereits zum Löschen markiert ist. POSIX.1-2001
  spezifiziert dieses Verhalten jedoch nicht und andere Implementierungen
  unterstützen es nicht.
Der folgende Systemparameter beeinflusst 
shmat():
  - SHMLBA
 
  - Adress-Multiplikator der Segmentuntergrenze. Muss
      seitenkonform sein. In der aktuellen Implemtentierung ist der Wert von
      SHMBLA gleich PAGE_SIZE.
 
Die Implemtentierung hat keinen wesentlichen Einschränkungen der maximalen
  Anzahl von gemeinsamen Speichersegmenten pro Prozess ( 
SHMSEG)
SIEHE AUCH¶
brk(2), 
mmap(2), 
shmctl(2), 
shmget(2),
  
capabilities(7), 
shm_overview(7), 
svipc(7)
KOLOPHON¶
Diese Seite ist Teil der Veröffentlichung 3.42 des Projekts Linux-
  
man-pages. Eine Beschreibung des Projekts und Informationen, wie Fehler
  gemeldet werden können, finden sich unter
  
http://www.kernel.org/doc/man-pages/.
 
ÜBERSETZUNG¶
Die deutsche Übersetzung dieser Handbuchseite wurde von Ralf Demmer
  <rdemmer@rdemmer.de> und Chris Leick <c.leick@vollbio.de>
  erstellt.
 
Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public
  License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird
  KEINE HAFTUNG übernommen.
 
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken
  Sie bitte eine E-Mail an <debian-l10n-german@lists.debian.org>.