예제 #1
0
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;
}
예제 #3
0
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;
}