added read_timed

This commit is contained in:
Dominik Maier
2020-03-30 00:50:04 +02:00
parent ef3a13fa63
commit f4844e2c0c
7 changed files with 112 additions and 81 deletions

View File

@ -29,6 +29,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include "types.h"
#include "stdbool.h"
@ -390,5 +391,54 @@ static u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
}
/* Wrapper for select() and read(), reading exactly len bytes.
Returns the time passed to read.
If the wait times out, returns timeout_ms + 1;
Returns 0 if an error occurred (fd closed, signal, ...); */
static inline u32 read_timed(s32 fd, void *buf, size_t len, u32 timeout_ms) {
struct timeval timeout;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
timeout.tv_sec = (timeout_ms / 1000);
timeout.tv_usec = (timeout_ms % 1000) * 1000;
size_t read_total = 0;
size_t len_read = 0;
while (len_read < len) {
/* set exceptfds as well to return when a child exited/closed the pipe. */
int sret = select(fd + 1, &readfds, NULL, NULL, &timeout);
if (!sret) {
// printf("Timeout in sret.");
return timeout_ms + 1;
} else if (sret < 0) {
// perror("sret malloc");
// TODO: catch other (errno == EINTR) than ctrl+c?
return 0;
}
len_read = read(fd, buf + len_read, len - len_read);
if (!len_read) { return 0; }
read_total += len_read;
}
s32 exec_ms =
MIN(timeout_ms,
((u64)timeout_ms - (timeout.tv_sec * 1000 + timeout.tv_usec / 1000)));
return exec_ms > 0 ? exec_ms
: 1; // at least 1 milli must have passed (0 is an error)
}
#endif