diff options
author | Amit Shah <amit.shah@redhat.com> | 2011-01-13 19:13:50 +0530 |
---|---|---|
committer | Amit Shah <amit.shah@redhat.com> | 2011-01-13 19:13:50 +0530 |
commit | 0c71cdee96971283c845423622d3d86bac787c89 (patch) | |
tree | 0880ca10f8fa2a97f1d231e887a89fde22b81af8 | |
parent | 6633c3cd8a85e484e9a38420efec13d4a2813d78 (diff) | |
download | test-virtserial-0c71cdee96971283c845423622d3d86bac787c89.tar.gz test-virtserial-0c71cdee96971283c845423622d3d86bac787c89.tar.xz test-virtserial-0c71cdee96971283c845423622d3d86bac787c89.zip |
auto-virtserial: Ensure we handle EINTR/EAGAIN on local file descriptors
For the guest and host file send functions, we could get EINTR or EAGAIN
on local file descriptors. Ensure we handle that.
Also, add a timeout to read() on the local descriptor to ensure we don't
block forever on a guest that gets stuck.
Signed-off-by: Amit Shah <amit.shah@redhat.com>
-rw-r--r-- | auto-virtserial.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/auto-virtserial.c b/auto-virtserial.c index 03c3090..560a3e4 100644 --- a/auto-virtserial.c +++ b/auto-virtserial.c @@ -1097,8 +1097,18 @@ static int test_host_file_send(int nr) guest_cmd_only(&gpkt); /* The guest now is waiting for our data */ - while ((ret = read(fd, buf, BUF_LENGTH))) + while (1) { + ret = read(fd, buf, BUF_LENGTH); + if (ret < 0 && (errno == EINTR || errno == EAGAIN)) + continue; + else if (ret < 0) { + fprintf(stderr, "read error %d\n", errno); + break; + } + if (ret == 0) + break; write(chardevs[nr].sock, buf, ret); + } close(fd); /* guest will stop reading only if read() returns 0 */ @@ -1180,6 +1190,7 @@ static int test_guest_file_send(int nr) { char buf[BUF_LENGTH]; char csum[BUF_LENGTH]; + struct pollfd pollfds[1]; struct guest_packet gpkt; int err, ret, fd, csum_fd; @@ -1210,7 +1221,24 @@ static int test_guest_file_send(int nr) guest_cmd_only(&gpkt); /* The guest now is sending us data */ - while ((ret = read(chardevs[nr].sock, buf, BUF_LENGTH))) { + pollfds[0].fd = chardevs[nr].sock; + pollfds[0].events = POLLIN; + while (1) { + /* If no response received for 5s, assume guest is stuck. */ + ret = poll(pollfds, 1, 5000); + if (ret <= 0) { + debug("poll returned %d\n", ret); + break; + } + ret = read(chardevs[nr].sock, buf, BUF_LENGTH); + if (ret == 0) + break; + if (ret < 0 && (errno == EINTR || errno == EAGAIN)) + continue; + else if (ret < 0) { + fprintf(stderr, "read error %d\n", errno); + break; + } write(fd, buf, ret); if (ret > 0 && ret < BUF_LENGTH) break; |