Provided by:
manpages-pl-dev_20060617-1_all 
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 charcmsg_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