Używam gniazda domeny UNIX do przeniesienia deskryptora pliku do innego procesu. Działa to dobrze, ale kiedy po raz pierwszy spróbuję sprawdzić, czy gniazdo można zapisać za pomocą funkcji select(), wywołanie sendmsg() kończy się niepowodzeniem z błędem deskryptora uszkodzonego pliku.Wysyłanie deskryptora pliku przez gniazdo domeny UNIX i wybieranie()
Funkcja sendmsg() działa dobrze w połączeniu z select(), jeśli nie dodaję informacji o deskryptorze pliku do struktury msghdr, więc konflikt wydaje się być pomiędzy select() i przenoszenie deskryptorów plików.
Nie mogłem znaleźć żadnych informacji na ten temat na stronach man dla select(), recvmsg() lub innych. Ponieważ musi to stać się serwerem, który przekazuje deskryptory plików do wielu procesów, nadal chciałbym móc użyć select().
Czy jest coś, co mogę zrobić, aby to zadziałało, czy ktoś wie o alternatywnych rozwiązaniach?
Platforma to Ubuntu 10.4.
Jest to kod, który inicjuje struktur:
struct cmsghdr_fd : public cmsghdr
{
int fd;
};
int sendfd(int sock, int fd)
{
struct msghdr hdr;
struct iovec data;
struct cmsghdr_fd msgdata;
char dummy = '*';
data.iov_base = &dummy;
data.iov_len = sizeof(dummy);
hdr.msg_name = NULL;
hdr.msg_namelen = 0;
hdr.msg_iov = &data;
hdr.msg_iovlen = 1;
hdr.msg_flags = 0;
hdr.msg_control = &msgdata;
hdr.msg_controllen = sizeof(msgdata);
struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
cmsg->cmsg_len = hdr.msg_controllen;
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
*(int*)CMSG_DATA(cmsg) = fd;
int n = sendmsg(sock, &hdr, 0);
if(n == -1)
printf("sendmsg() failed: %s (socket fd = %d)\n", strerror(errno), sock);
return n;
}
Ponownie, to działa, jak długo nie nazywają select() najpierw sprawdzić, czy gniazdo jest gotowe do zapisu.
Czy możesz dołączyć kod, który wypełnia 'msghdr' i' cmsghdr'? –
Sprawdziłbym, czy twój otaczający kod nie psuje długości pliku msghdr (lub samych danych), ponieważ od bardzo krótkiego przeczytania obsługi jądra, myślę, że byłby to prawdopodobny problem. – Hasturkun
Dodałem kod, który zapełnia struktury na to pytanie. – svdree