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();
}