diff options
author | Dominik Maier <domenukk@gmail.com> | 2020-03-30 00:50:04 +0200 |
---|---|---|
committer | Dominik Maier <domenukk@gmail.com> | 2020-04-01 13:10:06 +0200 |
commit | 452067ffca0de664fa4a11211c54f34c3842f20e (patch) | |
tree | 5796aa0fb75091579be89ac48fe364b553e31555 /include/common.h | |
parent | 3ce5efc44b9d3e41d2928553fee2e51681c955d2 (diff) | |
download | afl++-452067ffca0de664fa4a11211c54f34c3842f20e.tar.gz |
added read_timed
Diffstat (limited to 'include/common.h')
-rw-r--r-- | include/common.h | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/include/common.h b/include/common.h index 8b21b55f..e8558e24 100644 --- a/include/common.h +++ b/include/common.h @@ -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 |