summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2011-01-13 19:13:50 +0530
committerAmit Shah <amit.shah@redhat.com>2011-01-13 19:13:50 +0530
commit0c71cdee96971283c845423622d3d86bac787c89 (patch)
tree0880ca10f8fa2a97f1d231e887a89fde22b81af8
parent6633c3cd8a85e484e9a38420efec13d4a2813d78 (diff)
downloadtest-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.c32
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;