diff --git a/src/init.c b/src/init.c index d2457a6..7adfa40 100644 --- a/src/init.c +++ b/src/init.c @@ -1097,7 +1097,7 @@ static int hyper_channel_handle(struct hyper_event *de, uint32_t len) uint8_t *data = NULL; int i, ret = 0; - // append a null byte to it. hyper_event_read() left this room for us. + // append a null byte to it. hyper_channel_read() left this room for us. buf->data[buf->get] = 0; for (i = 0; i < buf->get; i++) fprintf(stdout, "%0x ", buf->data[i]); @@ -1176,8 +1176,64 @@ static int hyper_channel_handle(struct hyper_event *de, uint32_t len) return 0; } +static int hyper_channel_read(struct hyper_event *he, int efd) +{ + struct hyper_buf *buf = &he->rbuf; + uint32_t len = he->ops->len_offset + 4; + uint8_t data[4]; + int size; + int ret; + + fprintf(stdout, "%s\n", __func__); + + if (buf->get < len) { + size = nonblock_read(he->fd, buf->data + buf->get, len - buf->get); + if (size < 0) { + return size; + } + if (size > 0) { + /* 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; + } + } + + 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. + if (len >= buf->size) { + fprintf(stderr, "get length %" PRIu32", too long\n", len); + return -1; + } + + size = nonblock_read(he->fd, buf->data + buf->get, len - buf->get); + if (size < 0) { + return size; + } + if (size > 0) { + /* 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; + } + + /* get and consume the whole data */ + ret = he->ops->handle(he, len); + buf->get = 0; + + return ret == 0 ? 0 : -1; +} + static struct hyper_event_ops hyper_channel_ops = { - .read = hyper_event_read, + .read = hyper_channel_read, .handle = hyper_channel_handle, .rbuf_size = 10240, .len_offset = 4,