diff options
author | Mattias Andrée <maandree@kth.se> | 2018-11-19 21:39:11 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2018-11-19 21:39:11 +0100 |
commit | e8a7e1c358caec60751460d337f634ff6957ff9d (patch) | |
tree | b0fe92173edbf210d2890ecd35141cc39decf8dc /difftimeval.c | |
parent | Add memelemscan (diff) | |
download | libsimple-e8a7e1c358caec60751460d337f634ff6957ff9d.tar.gz libsimple-e8a7e1c358caec60751460d337f634ff6957ff9d.tar.bz2 libsimple-e8a7e1c358caec60751460d337f634ff6957ff9d.tar.xz |
Add a bunch of function and macros
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'difftimeval.c')
-rw-r--r-- | difftimeval.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/difftimeval.c b/difftimeval.c index 0cd8cda..2f633a2 100644 --- a/difftimeval.c +++ b/difftimeval.c @@ -6,16 +6,36 @@ int libsimple_difftimeval(struct timeval *diff, const struct timeval *minuend, const struct timeval *subtrahend) { - struct timespec a, b, d; - int r; - libsimple_timeval2timespec(&a, minuend); - libsimple_timeval2timespec(&b, subtrahend); - r = libsimple_difftimespec(&d, &a, &b); - if (r && errno != ERANGE) - return r; - if (libsimple_timespec2timeval(diff, &d) && r) - errno = ERANGE; - return r; + time_t s; + + if (LIBSIMPLE_SSUB_OVERFLOW(minuend->tv_sec, subtrahend->tv_sec, &s, TIME_MIN, TIME_MAX)) { + if (subtrahend->tv_sec < 0) + goto too_large; + else + goto too_small; + } + + diff->tv_usec = minuend->tv_usec - subtrahend->tv_usec; + if (diff->tv_usec < 0) { + if (LIBSIMPLE_SDECR_OVERFLOW(&s, TIME_MIN)) + goto too_small; + diff->tv_usec += 1000000L; + } + + diff->tv_sec = s; + return 0; + +too_large: + diff->tv_sec = TIME_MAX; + diff->tv_usec = 999999L; + errno = ERANGE; + return -1; + +too_small: + diff->tv_sec = TIME_MIN; + diff->tv_usec = 0; + errno = ERANGE; + return -1; } |