The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
timeval.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 784564df23e556b7a616cab60ea1e7a16e9c43f1 $
19 *
20 * @brief Platform independent time functions
21 * @file util/timeval.c
22 *
23 * @copyright 2019 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 */
25
26#include <freeradius-devel/util/strerror.h>
27#include <freeradius-devel/util/time.h>
28#include <freeradius-devel/util/timeval.h>
29
30/** Subtract one timeval from another
31 *
32 * @param[out] out Where to write difference.
33 * @param[in] end Time closest to the present.
34 * @param[in] start Time furthest in the past.
35 */
36void fr_timeval_subtract(struct timeval *out, struct timeval const *end, struct timeval const *start)
37{
38 out->tv_sec = end->tv_sec - start->tv_sec;
39 if (out->tv_sec > 0) {
40 out->tv_sec--;
41 out->tv_usec = USEC;
42 } else {
43 out->tv_usec = 0;
44 }
45 out->tv_usec += end->tv_usec;
46 out->tv_usec -= start->tv_usec;
47
48 if (out->tv_usec >= USEC) {
49 out->tv_usec -= USEC;
50 out->tv_sec++;
51 }
52}
53
54/** Create timeval from a string
55 *
56 * @param[out] out Where to write timeval.
57 * @param[in] in String to parse.
58 * @return
59 * - 0 on success.
60 * - -1 on failure.
61 */
62int fr_timeval_from_str(struct timeval *out, char const *in)
63{
64 unsigned long sec;
65 char *end;
66 struct timeval tv;
67
68 sec = strtoul(in, &end, 10);
69 if ((sec == ULONG_MAX) || (in == end)) {
70 failed:
71 fr_strerror_printf("Failed parsing \"%s\" as timeval", in);
72 return -1;
73 }
74 tv.tv_sec = sec;
75 tv.tv_usec = 0;
76
77 if (*end && (*end != '.')) goto failed;
78
79 if (*end == '.') {
80 size_t len;
81 char const *frac;
82
83 len = strlen(end + 1);
84
85 if (len > 6) {
86 fr_strerror_const("Too much precision for timeval");
87 return -1;
88 }
89
90 /*
91 * If they write "0.1", that means
92 * "10000" microseconds.
93 */
94 frac = end + 1;
95
96 sec = strtoul(frac, &end, 10);
97 if ((sec == ULONG_MAX) || (frac == end)) {
98 fr_strerror_printf("Failed parsing fractional component \"%s\" of timeval", in);
99 return -1;
100 }
101 while (len < 6) {
102 sec *= 10;
103 len++;
104 }
105 tv.tv_usec = sec;
106 }
107 *out = tv;
108 return 0;
109}
static fr_slen_t in
Definition dict.h:882
#define USEC
Definition time.h:380
int fr_timeval_from_str(struct timeval *out, char const *in)
Create timeval from a string.
Definition timeval.c:62
void fr_timeval_subtract(struct timeval *out, struct timeval const *end, struct timeval const *start)
Subtract one timeval from another.
Definition timeval.c:36
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64
#define fr_strerror_const(_msg)
Definition strerror.h:223
static size_t char ** out
Definition value.h:1030