2013-06-24 4 views
2

У меня есть кусок кода, который использует сокеты домена 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); 

Любые подсказки? Заранее спасибо

ответ

0

Вы действительно используете материал cmsg, который получаете? Я заметил, что вы установили msg_controllen на 512. К чему вы установили msg_flags?

Можете ли вы попробовать одно и то же с помощью следующего дополнения.

msg = (struct msghdr *)pipe->msg; 

memset (msg, 0, sizeof(msghdr)); /* added this */ 

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); 

 Смежные вопросы

  • Нет связанных вопросов^_^