diff --git a/kernel/poll.c b/kernel/poll.c index 8a91be47ae..e5a7add3a4 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -53,6 +53,8 @@ dword_t sys_select(fd_t nfds, addr_t readfds_addr, addr_t writefds_addr, addr_t timeout_ts.tv_sec = timeout_timeval.sec; timeout_ts.tv_nsec = timeout_timeval.usec * 1000; } + // Emacs likes to pass invalid timeout values + timeout_ts = timespec_normalize(timeout_ts); STRACE("select(%d, 0x%x, 0x%x, 0x%x, 0x%x {%lds %ldns}) ", nfds, readfds_addr, writefds_addr, exceptfds_addr, diff --git a/util/timer.h b/util/timer.h index 8de98895fc..1a8c6711b3 100644 --- a/util/timer.h +++ b/util/timer.h @@ -43,6 +43,12 @@ static inline bool timespec_positive(struct timespec ts) { return ts.tv_sec > 0 || (ts.tv_sec == 0 && ts.tv_nsec > 0); } +static inline struct timespec timespec_normalize(struct timespec ts) { + ts.tv_sec += ts.tv_nsec / 1000000000; + ts.tv_nsec %= 1000000000; + return ts; +} + typedef void (*timer_callback_t)(void *data); struct timer { clockid_t clockid;