diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2024-09-06 21:49:37 +1000 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2024-09-06 13:56:41 +0200 |
commit | 11e29054fe91ceaf59d2a500e09c4da262c7b23e (patch) | |
tree | 9eec2b38db15bd35649366eb48ff88665b734ba9 | |
parent | 49fc4e0414610c6eadc6693fee4d5077d2e8097e (diff) | |
download | passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar.gz passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar.bz2 passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar.lz passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar.xz passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.tar.zst passt-11e29054fe91ceaf59d2a500e09c4da262c7b23e.zip |
tap: Improve handling of EINTR in tap_passt_input()
When tap_passt_input() gets an error from recv() it (correctly) does not
print any error message for EINTR, EAGAIN or EWOULDBLOCK. However in all
three cases it returns from the function. That makes sense for EAGAIN and
EWOULDBLOCK, since we then want to wait for the next EPOLLIN event before
trying again. For EINTR, however, it makes more sense to retry immediately
- as it stands we're likely to get a renewer EPOLLIN event immediately in
that case, since we're using level triggered signalling.
So, handle EINTR separately by immediately retrying until we succeed or
get a different type of error.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r-- | tap.c | 9 |
1 files changed, 6 insertions, 3 deletions
@@ -1003,10 +1003,13 @@ static void tap_passt_input(struct ctx *c, const struct timespec *now) memmove(pkt_buf, partial_frame, partial_len); } - n = recv(c->fd_tap, pkt_buf + partial_len, TAP_BUF_BYTES - partial_len, - MSG_DONTWAIT); + do { + n = recv(c->fd_tap, pkt_buf + partial_len, + TAP_BUF_BYTES - partial_len, MSG_DONTWAIT); + } while ((n < 0) && errno == EINTR); + if (n < 0) { - if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) { + if (errno != EAGAIN && errno != EWOULDBLOCK) { err_perror("Receive error on guest connection, reset"); tap_sock_reset(c); } |