ssize_t DaemonSocketPDU::Receive(int aFd) { struct iovec iv; memset(&iv, 0, sizeof(iv)); iv.iov_base = GetData(0); iv.iov_len = GetAvailableSpace(); uint8_t cmsgbuf[CMSG_SPACE(sizeof(int)* MAX_NFDS)]; struct msghdr msg; memset(&msg, 0, sizeof(msg)); msg.msg_iov = &iv; msg.msg_iovlen = 1; msg.msg_control = cmsgbuf; msg.msg_controllen = sizeof(cmsgbuf); ssize_t res = TEMP_FAILURE_RETRY(recvmsg(aFd, &msg, MSG_NOSIGNAL)); if (res < 0) { MOZ_ASSERT(errno != EBADF); /* internal error */ OnError("recvmsg", errno); return -1; } if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) { return -1; } SetRange(0, res); struct cmsghdr* chdr = CMSG_FIRSTHDR(&msg); for (; chdr; chdr = CMSG_NXTHDR(&msg, chdr)) { if (NS_WARN_IF(!CMSGHDR_CONTAINS_FD(chdr))) { continue; } // Retrieve sent file descriptors. size_t fdCount = (chdr->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr))) / sizeof(int); for (size_t i = 0; i < fdCount; i++) { int* receivedFd = static_cast<int*>(CMSG_DATA(chdr)) + i; mReceivedFds.AppendElement(*receivedFd); } } return res; }
BluetoothStatus SocketMessageWatcher::RecvMsg2() { struct iovec iv; memset(&iv, 0, sizeof(iv)); iv.iov_base = mBuf + MSG1_SIZE; iv.iov_len = MSG2_SIZE; struct msghdr msg; struct cmsghdr cmsgbuf[CMSG_SPACE(sizeof(int))]; memset(&msg, 0, sizeof(msg)); msg.msg_iov = &iv; msg.msg_iovlen = 1; msg.msg_control = cmsgbuf; msg.msg_controllen = sizeof(cmsgbuf); ssize_t res = TEMP_FAILURE_RETRY(recvmsg(mFd, &msg, MSG_NOSIGNAL)); if (res <= 0) { return STATUS_FAIL; } mLen += res; if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) { return STATUS_FAIL; } struct cmsghdr *cmsgptr = CMSG_FIRSTHDR(&msg); // Extract client fd from message header for (; cmsgptr; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { if (CMSGHDR_CONTAINS_FD(cmsgptr)) { // if multiple file descriptors have been sent, we close // all but the final one. if (mClientFd != -1) { TEMP_FAILURE_RETRY(close(mClientFd)); } // retrieve sent client fd memcpy(&mClientFd, CMSG_DATA(cmsgptr), sizeof(mClientFd)); } } return STATUS_SUCCESS; }
ssize_t DaemonSocketPDU::Receive(int aFd) { struct iovec iv; memset(&iv, 0, sizeof(iv)); iv.iov_base = GetData(0); iv.iov_len = GetAvailableSpace(); uint8_t cmsgbuf[CMSG_SPACE(sizeof(int))]; struct msghdr msg; memset(&msg, 0, sizeof(msg)); msg.msg_iov = &iv; msg.msg_iovlen = 1; msg.msg_control = cmsgbuf; msg.msg_controllen = sizeof(cmsgbuf); ssize_t res = TEMP_FAILURE_RETRY(recvmsg(aFd, &msg, MSG_NOSIGNAL)); if (res < 0) { MOZ_ASSERT(errno != EBADF); /* internal error */ OnError("recvmsg", errno); return -1; } if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) { return -1; } SetRange(0, res); struct cmsghdr *chdr = CMSG_FIRSTHDR(&msg); for (; chdr; chdr = CMSG_NXTHDR(&msg, chdr)) { if (NS_WARN_IF(!CMSGHDR_CONTAINS_FD(chdr))) { continue; } // Retrieve sent file descriptor. If multiple file descriptors // have been sent, we close all but the final one. mReceivedFd = *(static_cast<int*>(CMSG_DATA(chdr))); } return res; }