У меня есть кусок кода, который использует сокеты домена Unix и sendmsg/recvmsg для отправки fd между двумя процессами. Этот код должен работать как на Linux, так и на Mac (он выполняется отдельно для обеих платформ). Я использую SOCK_DGRAM (датаграммы) сокеты.Mac OS X: recvmsg возвращает EMSGSIZE при отправке fd через сокет datagram домена Unix
Я отправляю один fd за раз в своем коде. На Mac, после того, как он отправил пару fd успешно, recvmsg() терпит неудачу с EMSGSIZE. Согласно man-странице для recvmsg, это может произойти только в том случае, если msg-> msg_iovlen < = 0 или> = константа, которая равна 2048 на Mac. В моем коде я всегда привязывал msg_iovlen к 1, я проверял это на отправителе и получателе, а также читал заголовок сообщения сразу после ошибок recvmsg(). Этот же код отлично работает в Linux.
Еще одна возможность, смотря на источник ядра XNU, заключается в том, что у получателя может закончиться fd, но я только отправил 4 или 5 fd, прежде чем произойдет ошибка, поэтому должно быть много fd слева.
Если я не отправляю fd и отправляю только данные, эта ошибка не возникает.
Вот что код, который упаковывает сообщение управления выглядит следующим образом:
// *obj is the fd, objSize is sizeof(*obj)
// cmsg was allocated earlier as a 512 byte buffer
cmsgLength = CMSG_LEN(objSize);
cmsgSpace = CMSG_SPACE(objSize);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = cmsgLength;
memcpy(CMSG_DATA(cmsg), obj, objSize);
msg->msg_control = cmsg;
msg->msg_controllen = cmsgSpace;
И вот приемник:
msg = (struct msghdr *)pipe->msg;
iov = msg->msg_iov;
iov->iov_base = buf;
iov->iov_len = size;
// msg->msg_control was set earlier
msg->msg_controllen = 512;
return recvmsg(sockFd, msg, 0);
Любые подсказки? Заранее спасибо