ssize_t UnixSocketRawData::Receive(int aFd) { if (!GetTrailingSpace()) { if (!GetLeadingSpace()) { return -1; /* buffer is full */ } /* free up space at the end of data buffer */ if (GetSize() <= GetLeadingSpace()) { memcpy(mData, GetData(), GetSize()); } else { memmove(mData, GetData(), GetSize()); } mOffset = 0; } ssize_t res = TEMP_FAILURE_RETRY(read(aFd, GetTrailingBytes(), GetTrailingSpace())); if (res < 0) { /* I/O error */ return -1; } else if (!res) { /* EOF or peer shutdown sending */ return 0; } mSize += res; return res; }
ssize_t DaemonSocketPDU::Send(int aFd) { struct iovec iv; memset(&iv, 0, sizeof(iv)); iv.iov_base = GetData(GetLeadingSpace()); iv.iov_len = GetSize(); struct msghdr msg; memset(&msg, 0, sizeof(msg)); msg.msg_iov = &iv; msg.msg_iovlen = 1; msg.msg_control = nullptr; msg.msg_controllen = 0; ssize_t res = TEMP_FAILURE_RETRY(sendmsg(aFd, &msg, 0)); if (res < 0) { MOZ_ASSERT(errno != EBADF); /* internal error */ OnError("sendmsg", errno); return -1; } Consume(res); if (mConsumer) { // We successfully sent a PDU, now store the // result runnable in the consumer. mConsumer->StoreUserData(*this); } return res; }