static proto_t read_with_timeout()

in watchman.c [387:430]


static proto_t read_with_timeout(int fd, char* buf, size_t bytes, struct timeval timeout)
{
    size_t read_so_far = 0;
    ssize_t bytes_read = 0;

    while (read_so_far < bytes) {
        if (timeout.tv_sec || timeout.tv_usec) {
            if (timeout.tv_sec < 0 || timeout.tv_usec < 0) {
                /* Timeout */
                return proto_null();
            }

            if (1 == block_on_read(fd, &timeout)) {
                bytes_read = read(fd, buf, bytes - read_so_far);
            } else {
                return proto_null(); /* timeout or error */
            }
        } else {
            bytes_read = read(fd, buf, bytes - read_so_far);
        }
        if (bytes_read < 0) {
            return proto_null();
        }
        if (bytes_read == 0) {
            /* EOF, but we couldn't parse the JSON we have so far */
            return proto_null();
        }
        read_so_far += bytes_read;

        /* try to parse this */
        buf[read_so_far] = 0;
        proto_t proto;
        if (buf[0] <= 0x0b) {
            bser_t* bser = bser_parse_buffer((uint8_t*)buf, read_so_far, NULL);
            proto = proto_from_bser(bser);
        } else {
            json_error_t jerror;
            json_t* json = json_loads(buf, JSON_DISABLE_EOF_CHECK, &jerror);
            proto = proto_from_json(json);
        }
        return proto;
    }
    return proto_null();
}