NAZWA¶
CMSG_ALIGN, CMSG_SPACE, CMSG_NXTHDR, CMSG_FIRSTHDR - dostęp do danych
  pomocniczych
SKŁADNIA¶
#include <sys/socket.h>
 
 
struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
 
struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh, struct cmsghdr
  *cmsg);
 
size_t CMSG_ALIGN(size_t length);
 
size_t CMSG_SPACE(size_t length);
 
size_t CMSG_LEN(size_t length);
 
unsigned char *CMSG_DATA(struct cmsghdr *cmsg);
 
struct cmsghdr {
	socklen_t	cmsg_len;	/* liczba bajtów danych, włączając nagłówek */
	int	cmsg_level;	/* protokół źródłowy */
	int	cmsg_type;	/* zależny od protokołu typ */
/* następuje po nim  unsigned char	cmsg_data[]; */
};
OPIS¶
Makrodefinicje te służą do tworzenia i dostępu do
  komunikatów sterujących (zwanych również danymi
  pomocniczymi), które nie są częścią gniazda. Te
  informacje sterujące mogą zawierać: interfejs, przez który
  pakiet został odebrany, różne rzadko używane pola
  nagłówka, rozszerzony opis błędu, zestaw deskryptorów
  plików lub uwierzytelnień uniksowych. Na przykład, komunikaty
  sterujące mogą służyć do ustawiania dodatkowych
  pól nagłówka, takich jak opcje IP, dla wysyłanych
  pakietów. Dane pomocnicze są wysyłane poprzez wywołanie
  
sendmsg(2) a otrzymywane poprzez wywołanie 
recvmsg(2).
  Więcej informacji znajduje się na stronach podręcznika man dla
  tych poleceń.
Dane pomocnicze są ciągiem struktur 
struct cmsghdr z dodanymi
  danymi. Dostęp do tego ciągu powinien się odbywać
  wyłącznie poprzez opisane na tej stronie podręcznika
  makrodefinicje, nigdy zaś bezpośrednio. Dostępne rodzaje
  komunikatów sterujących opisano na stronach podręcznika dla
  poszczególnych protokołów. Maksymalny rozmiar bufora danych
  pomocniczych dla gniazda można ustawić za pomocą sysctl-a
  
net.core.optmem_max; patrz 
socket(7).
CMSG_FIRSTHDR zwraca wskaźnik do pierwszego 
cmsghdr w buforze
  danych pomocniczych związanym z przekazanym 
msghdr.
CMSG_NXTHDR zwraca następny poprawny 
cmsghdr po przekazanym
  
cmsghdr. Zwraca 
NULL, gdy brak dostatecznej ilości miejsca
  w buforze.
CMSG_ALIGN, zadana długość, zwraca ją
  włączając niezbędne wyrównanie. Jest to
  wyrażenie stałe.
CMSG_SPACE zwraca liczbę bajtów elementu pomocniczego
  włączając długość, jaką zajmują
  przekazane dane. Jest to wyrażenie stałe.
CMSG_DATA zwraca wskaźnik do części 
cmsghdr
  zawierającej dane.
CMSG_LEN zwraca wartość, która ma być przechowywana w
  elemencie 
cmsg_len struktury 
cmsghdr, biorąc pod uwagę
  wszelkie niezbędne wyrównania. Jako argument pobiera
  długość danych. Jest to wyrażenie stałe.
Aby utworzyć dane pomocnicze, należy najpierw zainicjalizować
  element 
msg_controllen struktury 
msghdr długością
  bufora komunikatów sterujących. Należy użyć
  
CMSG_FIRSTHDR dla 
msghdr, aby otrzymać pierwszy komunikat
  sterujący oraz 
CMSG_NEXTHDR, aby otrzymać wszystkie
  następne. Dla każdego komunikatu sterującego należy
  zainicjalizować 
cmsg_len (za pomocą 
CMSG_LEN), inne
  pola nagłówka 
cmsghdr oraz część
  zawierającą dane za pomocą 
CMSG_DATA. Ostatecznie pole
  
msg_controllen struktury 
msghdr powinno zawierać sumę
  
CMSG_SPACE dla długości wszystkich komunikatów
  sterujących w buforze. Więcej informacji dotyczących
  
msghdr, znajduje się w 
recvmsg(2).
Gdy bufor komunikatów sterujących jest za krótki, aby
  przechować wszystkie komunikaty, ustawiany jest znacznik
  
MSG_CTRUNC elementu 
msg_flags struktury 
msghdr.
PRZYKŁAD¶
Następujący kod poszukuje opcji 
IP_TTL w otrzymanym buforze
  pomocniczym:
struct msghdr msgh;
struct cmsghdr *cmsg;
int *ttlptr;
int received_ttl;
/* Otrzymywanie danych z zewnątrz do msgh */
for (cmsg = CMSG_FIRSTHDR(&msgh);
     cmsg != NULL;
     cmsg = CMSG_NXTHDR(&msgh,cmsg) {
	if (cmsg->cmsg_level == SOL_IP
	  && cmsg->cmsg_type == IP_TTL) {
		ttlptr = (int *) CMSG_DATA(cmsg);
		received_ttl = *ttlptr;
		break;
	}
}
if (cmsg == NULL) {
	/*
	 * Błąd: IP_TTL not jest włączone, za mały bufor lub
	 * błąd I/O.
	 */
}
 
Poniższy kod przekazuje tablicę deskryptorów plików poprzez
  gniazdo Uniksa 
SCM_RIGHTS:
struct msghdr msg = {0};
struct cmsghdr *cmsg;
int myfds[NUM_FD]; /* Zawiera przekazywane deskryptory plików. */
char buf[CMSG_SPACE(sizeof myfds)];  /* bufor danych pomocniczych */
int *fdptr;
msg.msg_control = buf;
msg.msg_controllen = sizeof buf;
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD);
/* Inicjalizacja: */
fdptr = (int *)CMSG_DATA(cmsg);
memcpy(fdptr, myfds, NUM_FD * sizeof(int));
/* Suma długości wszystkich komunikatów sterujących w buforze: */
msg.msg_controllen = cmsg->cmsg_len;
 
UWAGI¶
Dla przenośności, dostęp do danych pomocniczych powinien się
  odbywać jedynie za pomocą opisanych tu makrodefinicji.
  
CMSG_ALIGN jest rozszerzeniem Linuksa i nie powinno być
  używane w przenośnych programach.
W Linuksie, 
CMSG_LEN, 
CMSG_DATA, i 
CMSG_ALIGN są
  wyrażeniami stałymi (zakładając, że ich argument jest
  stały) - można to wykorzystać do zadeklarowania rozmiaru
  zmiennych globalnych. Jednakże, może się to okazać
  nieprzenośnym.
ZGODNE Z¶
Ten model danych pomocniczych jest zgodny ze szkicem POSIX.1003.1g, z
  4.4BSD-Lite, z zaawansowanym API dla IPv6 opisanym w RFC2292 oraz ze
  specyfikacją Single Unix v2. 
CMSG_ALIGN jest rozszerzeniem
  Linuksa.
ZOBACZ TAKŻE¶
sendmsg(2), 
recvmsg(2)
RFC 2292