blob: ec60c1eb269681e6586ea14b930ebe590b2361df (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
/* See LICENSE file for copyright and license details. */
#include "libsimple.h"
int
libsimple_multimespec(struct timespec *prod, const struct timespec *multiplicand, int multiplier) /* TODO test */
{
time_t s = multiplicand->tv_sec;
long long int ns = (long long int)(multiplicand->tv_nsec);
long long int xs;
int neg = (s < 0) ^ (multiplier < 0);
if (multiplier == 0 || multiplier == 1) {
prod->tv_sec = multiplier * multiplicand->tv_sec;
prod->tv_nsec = multiplier * multiplicand->tv_nsec;
return 0;
}
if (s < 0) {
if (TIME_MIN != -TIME_MAX && s == TIME_MIN)
goto overflow;
s = -s;
if (ns)
ns = 1000000000L - ns;
}
if (multiplier < 0)
multiplier = -multiplier;
ns *= multiplier;
xs = ns / 1000000000L;
ns %= 1000000000L;
if (s > TIME_MAX / multiplier)
goto overflow;
s *= multiplier;
if (s > TIME_MAX - (time_t)xs)
goto overflow;
s += (time_t)xs;
if (neg) {
s = -s;
if (ns) {
if (s == TIME_MIN)
goto overflow;
ns = 1000000000L - ns;
s -= 1;
}
}
prod->tv_sec = s;
prod->tv_nsec = ns;
return 0;
overflow:
if (neg) {
prod->tv_sec = TIME_MIN;
prod->tv_nsec = 0;
} else {
prod->tv_sec = TIME_MAX;
prod->tv_nsec = 999999999L;
}
errno = ERANGE;
return -1;
}
|