| 547 | }; |
| 548 | |
| 549 | static int recv_fd_int(int sockfd, void *data, size_t nbytes, int *fd_recvd) |
| 550 | { |
| 551 | ssize_t rc; |
| 552 | size_t bytesleft; |
| 553 | char *cdata; |
| 554 | struct msghdr msg; |
| 555 | struct iovec iov[1]; |
| 556 | int recvfd; |
| 557 | #ifdef HAVE_MSGHDR_MSG_CONTROL |
| 558 | union { |
| 559 | struct cmsghdr cm; |
| 560 | unsigned char control[CMSG_SPACE(sizeof(int))]; |
| 561 | } control_un; |
| 562 | struct cmsghdr *cmsgptr; |
| 563 | #endif |
| 564 | |
| 565 | *fd_recvd = -1; |
| 566 | cdata = data; |
| 567 | bytesleft = nbytes; |
| 568 | |
| 569 | while (bytesleft > 0) { |
| 570 | #ifdef HAVE_MSGHDR_MSG_CONTROL |
| 571 | msg.msg_control = control_un.control; |
| 572 | msg.msg_controllen = sizeof(control_un.control); |
| 573 | msg.msg_flags = 0; |
| 574 | #else |
| 575 | msg.msg_accrights = (caddr_t)&recvfd; |
| 576 | msg.msg_accrightslen = sizeof(int); |
| 577 | #endif |
| 578 | msg.msg_name = NULL; |
| 579 | msg.msg_namelen = 0; |
| 580 | msg.msg_iov = iov; |
| 581 | msg.msg_iovlen = 1; |
| 582 | iov[0].iov_base = cdata; |
| 583 | iov[0].iov_len = bytesleft; |
| 584 | |
| 585 | rc = recvmsg(sockfd, &msg, 0); |
| 586 | |
| 587 | if (rc == -1) { |
| 588 | if (errno == EINTR || errno == EAGAIN) |
| 589 | continue; |
| 590 | return PASSFD_RECVMSG; |
| 591 | } |
| 592 | |
| 593 | if (rc == 0) { |
| 594 | /* Premature eof */ |
| 595 | return PASSFD_EOF; |
| 596 | } |
| 597 | |
| 598 | cdata += rc; |
| 599 | bytesleft -= rc; |
| 600 | |
| 601 | /* See if we got a descriptor with this message */ |
| 602 | #ifdef HAVE_MSGHDR_MSG_CONTROL |
| 603 | cmsgptr = CMSG_FIRSTHDR(&msg); |
| 604 | if (cmsgptr) { |
| 605 | if (cmsgptr->cmsg_len != CMSG_LEN(sizeof(int)) || |
| 606 | cmsgptr->cmsg_level != SOL_SOCKET || |