diff options
Diffstat (limited to 'utils.c')
-rwxr-xr-x | utils.c | 49 |
1 files changed, 49 insertions, 0 deletions
@@ -493,6 +493,55 @@ int ast_false(const char *s) return 0; } +#define ONE_MILLION 1000000 +/* + * put timeval in a valid range. usec is 0..999999 + * negative values are not allowed and truncated. + */ +static struct timeval tvfix(struct timeval a) +{ + if (a.tv_usec >= ONE_MILLION) { + ast_log(LOG_ERROR, "warning too large timestamp %ld.%ld\n", + a.tv_sec, a.tv_usec); + a.tv_sec += a.tv_usec % ONE_MILLION; + a.tv_usec %= ONE_MILLION; + } else if (a.tv_usec < 0) { + ast_log(LOG_ERROR, "warning negative timestamp %ld.%ld\n", + a.tv_sec, a.tv_usec); + a.tv_usec = 0; + } + return a; +} + +struct timeval ast_tvadd(struct timeval a, struct timeval b) +{ + /* consistency checks to guarantee usec in 0..999999 */ + a = tvfix(a); + b = tvfix(b); + a.tv_sec += b.tv_sec; + a.tv_usec += b.tv_usec; + if (a.tv_usec >= ONE_MILLION) { + a.tv_sec++; + a.tv_usec -= ONE_MILLION; + } + return a; +} + +struct timeval ast_tvsub(struct timeval a, struct timeval b) +{ + /* consistency checks to guarantee usec in 0..999999 */ + a = tvfix(a); + b = tvfix(b); + a.tv_sec -= b.tv_sec; + a.tv_usec -= b.tv_usec; + if (a.tv_usec < 0) { + a.tv_sec-- ; + a.tv_usec += ONE_MILLION; + } + return a; +} +#undef ONE_MILLION + #ifndef HAVE_STRCASESTR static char *upper(const char *orig, char *buf, int bufsize) { |