The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 7e1e674ee5f3d9591584d48549d23319681af595 $
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  */
36 void 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  */
62 int fr_timeval_from_str(struct timeval *out, char const *in)
63 {
64  int sec;
65  char *end;
66  struct timeval tv;
67 
68  sec = strtoul(in, &end, 10);
69  if (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 
82  len = strlen(end + 1);
83 
84  if (len > 6) {
85  fr_strerror_const("Too much precision for timeval");
86  return -1;
87  }
88 
89  /*
90  * If they write "0.1", that means
91  * "10000" microseconds.
92  */
93  sec = strtoul(end + 1, &end, 10);
94  if (in == end) {
95  fr_strerror_printf("Failed parsing fractional component \"%s\" of timeval", in);
96  return -1;
97  }
98  while (len < 6) {
99  sec *= 10;
100  len++;
101  }
102  tv.tv_usec = sec;
103  }
104  *out = tv;
105  return 0;
106 }
static fr_slen_t in
Definition: dict.h:821
#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:997