introduce nonblock_read()

and call it in hyper_event_read()

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
This commit is contained in:
Lai Jiangshan
2016-09-21 16:59:18 +08:00
parent 6224d6b779
commit 28ea806216
3 changed files with 48 additions and 49 deletions
+25 -49
View File
@@ -130,41 +130,30 @@ static int hyper_getmsg_len(struct hyper_event *he, uint32_t *len)
int hyper_event_read(struct hyper_event *he, int efd)
{
struct hyper_buf *buf = &he->rbuf;
uint32_t len = 4;
uint32_t len = he->ops->len_offset + 4;
uint8_t data[4];
int offset = he->ops->len_offset;
int end = offset + 4;
int size;
int ret;
fprintf(stdout, "%s\n", __func__);
while (hyper_getmsg_len(he, &len) < 0) {
size = read(he->fd, buf->data + buf->get, end - buf->get);
if (size > 0) {
buf->get += size;
fprintf(stdout, "already read %" PRIu32 " bytes data\n",
buf->get);
if (he->ops->ack) {
/* control channel, need ack */
hyper_set_be32(data, size);
hyper_send_msg(he->fd, NEXT, 4, data);
}
continue;
if (buf->get < len) {
size = nonblock_read(he->fd, buf->data + buf->get, len - buf->get);
if (size < 0) {
return size;
}
if (errno == EINTR)
continue;
if (errno != EAGAIN && size != 0) {
perror("fail to read");
return -1;
if (size > 0 && he->ops->ack) {
/* control channel, need ack */
hyper_set_be32(data, size);
hyper_send_msg(he->fd, NEXT, 4, data);
}
buf->get += size;
if (buf->get < len) {
return 0;
}
return 0;
}
hyper_getmsg_len(he, &len);
fprintf(stdout, "get length %" PRIu32"\n", len);
// test it with '>=' to leave at least one byte in handle(),
// so that handle() can convert the data to c-string inplace.
@@ -173,30 +162,17 @@ int hyper_event_read(struct hyper_event *he, int efd)
return -1;
}
while (buf->get < len) {
size = read(he->fd, buf->data + buf->get, len - buf->get);
if (size > 0) {
buf->get += size;
fprintf(stdout, "read %d bytes data, total data %" PRIu32 "\n",
size, buf->get);
if (he->ops->ack) {
/* control channel, need ack */
hyper_set_be32(data, size);
hyper_send_msg(he->fd, NEXT, 4, data);
}
continue;
}
if (errno == EINTR)
continue;
if (errno != EAGAIN && size != 0) {
perror("fail to read");
return -1;
}
/* size == 0 : No one connect to qemu socket */
size = nonblock_read(he->fd, buf->data + buf->get, len - buf->get);
if (size < 0) {
return size;
}
if (size > 0 && he->ops->ack) {
/* control channel, need ack */
hyper_set_be32(data, size);
hyper_send_msg(he->fd, NEXT, 4, data);
}
buf->get += size;
if (buf->get < len) {
return 0;
}
+22
View File
@@ -709,3 +709,25 @@ int hyper_cmd(char *cmd)
return -1;
}
ssize_t nonblock_read(int fd, void *buf, size_t count)
{
ssize_t len = 0, ret = 0;
while (len < count) {
ret = read(fd, buf + len, count - len);
if (ret <= 0) {
if (errno == EINTR) {
continue;
}
if (errno == EAGAIN) {
ret = 0;
}
break;
}
len += ret;
}
return len > 0 ? len : ret;
}
+1
View File
@@ -40,4 +40,5 @@ int hyper_insmod(char *module);
struct passwd *hyper_getpwnam(const char *name);
struct group *hyper_getgrnam(const char *name);
int hyper_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
ssize_t nonblock_read(int fd, void *buf, size_t count);
#endif