| 260 | } |
| 261 | |
| 262 | static int |
| 263 | read_msg(int fd, struct mp_msg_internal *m, struct sockaddr_un *s) |
| 264 | { |
| 265 | int msglen; |
| 266 | struct iovec iov; |
| 267 | struct msghdr msgh; |
| 268 | char control[CMSG_SPACE(sizeof(m->msg.fds))]; |
| 269 | struct cmsghdr *cmsg; |
| 270 | int buflen = sizeof(*m) - sizeof(m->msg.fds); |
| 271 | |
| 272 | memset(&msgh, 0, sizeof(msgh)); |
| 273 | iov.iov_base = m; |
| 274 | iov.iov_len = buflen; |
| 275 | |
| 276 | msgh.msg_name = s; |
| 277 | msgh.msg_namelen = sizeof(*s); |
| 278 | msgh.msg_iov = &iov; |
| 279 | msgh.msg_iovlen = 1; |
| 280 | msgh.msg_control = control; |
| 281 | msgh.msg_controllen = sizeof(control); |
| 282 | |
| 283 | retry: |
| 284 | msglen = recvmsg(fd, &msgh, 0); |
| 285 | |
| 286 | /* zero length message means socket was closed */ |
| 287 | if (msglen == 0) |
| 288 | return 0; |
| 289 | |
| 290 | if (msglen < 0) { |
| 291 | if (errno == EINTR) |
| 292 | goto retry; |
| 293 | |
| 294 | RTE_LOG(ERR, EAL, "recvmsg failed, %s\n", strerror(errno)); |
| 295 | return -1; |
| 296 | } |
| 297 | |
| 298 | if (msglen != buflen || (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) { |
| 299 | RTE_LOG(ERR, EAL, "truncated msg\n"); |
| 300 | return -1; |
| 301 | } |
| 302 | |
| 303 | /* read auxiliary FDs if any */ |
| 304 | for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; |
| 305 | cmsg = CMSG_NXTHDR(&msgh, cmsg)) { |
| 306 | if ((cmsg->cmsg_level == SOL_SOCKET) && |
| 307 | (cmsg->cmsg_type == SCM_RIGHTS)) { |
| 308 | memcpy(m->msg.fds, CMSG_DATA(cmsg), sizeof(m->msg.fds)); |
| 309 | break; |
| 310 | } |
| 311 | } |
| 312 | /* sanity-check the response */ |
| 313 | if (m->msg.num_fds < 0 || m->msg.num_fds > RTE_MP_MAX_FD_NUM) { |
| 314 | RTE_LOG(ERR, EAL, "invalid number of fd's received\n"); |
| 315 | return -1; |
| 316 | } |
| 317 | if (m->msg.len_param < 0 || m->msg.len_param > RTE_MP_MAX_PARAM_LEN) { |
| 318 | RTE_LOG(ERR, EAL, "invalid received data length\n"); |
| 319 | return -1; |