mirror of
https://github.com/clearlinux/hyperstart.git
synced 2026-10-03 23:48:25 +00:00
introduce nonblock_read()
and call it in hyper_event_read() Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
This commit is contained in:
+25
-49
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user