{
struct msghdr msg;
struct iovec iov[1];
- ssize_t ret;
+ ssize_t ret = -1;
+ size_t len_last;
memset(&msg, 0, sizeof(msg));
msg.msg_iovlen = 1;
do {
+ len_last = iov[0].iov_len;
ret = recvmsg(sock, &msg, 0);
- } while (ret < 0 && errno == EINTR);
+ if (ret > 0) {
+ iov[0].iov_base += ret;
+ iov[0].iov_len -= ret;
+ assert(ret <= len_last);
+ }
+ } while ((ret > 0 && ret < len_last) || (ret < 0 && errno == EINTR));
if (ret < 0) {
int shutret;
shutret = shutdown(sock, SHUT_RDWR);
if (shutret)
ERR("Socket shutdown error");
+ } else if (ret > 0) {
+ ret = len;
}
+ /* ret = 0 means an orderly shutdown. */
return ret;
}
msg.msg_iovlen = 1;
do {
- ret = sendmsg(sock, &msg, 0);
+ ret = sendmsg(sock, &msg, MSG_NOSIGNAL);
} while (ret < 0 && errno == EINTR);
if (ret < 0) {
/*
case 0: /* orderly shutdown */
return -EPIPE;
case sizeof(*lur):
+ {
+ int err = 0;
+
if (lur->handle != expected_handle) {
ERR("Unexpected result message handle: "
"expected: %u vs received: %u\n",
expected_handle, lur->handle);
- return -EINVAL;
+ err = 1;
}
if (lur->cmd != expected_cmd) {
ERR("Unexpected result message command "
"expected: %u vs received: %u\n",
expected_cmd, lur->cmd);
+ err = 1;
+ }
+ if (err) {
return -EINVAL;
+ } else {
+ return lur->ret_code;
}
- return lur->ret_code;
+ }
default:
if (len >= 0) {
ERR("incorrect message size: %zd\n", len);