Coverage Report

Created: 2026-02-26 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/lib/util/timeval.c
Line
Count
Source
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
0
{
38
0
  out->tv_sec = end->tv_sec - start->tv_sec;
39
0
  if (out->tv_sec > 0) {
40
0
    out->tv_sec--;
41
0
    out->tv_usec = USEC;
42
0
  } else {
43
0
    out->tv_usec = 0;
44
0
  }
45
0
  out->tv_usec += end->tv_usec;
46
0
  out->tv_usec -= start->tv_usec;
47
48
0
  if (out->tv_usec >= USEC) {
49
0
    out->tv_usec -= USEC;
50
0
    out->tv_sec++;
51
0
  }
52
0
}
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
0
{
64
0
  int sec;
65
0
  char  *end;
66
0
  struct  timeval tv;
67
68
0
  sec = strtoul(in, &end, 10);
69
0
  if (in == end) {
70
0
  failed:
71
0
    fr_strerror_printf("Failed parsing \"%s\" as timeval", in);
72
0
    return -1;
73
0
  }
74
0
  tv.tv_sec = sec;
75
0
  tv.tv_usec = 0;
76
77
0
  if (*end && (*end != '.')) goto failed;
78
79
0
  if (*end == '.') {
80
0
    size_t len;
81
82
0
    len = strlen(end + 1);
83
84
0
    if (len > 6) {
85
0
      fr_strerror_const("Too much precision for timeval");
86
0
      return -1;
87
0
    }
88
89
    /*
90
     *  If they write "0.1", that means
91
     *  "10000" microseconds.
92
     */
93
0
    sec = strtoul(end + 1, &end, 10);
94
0
    if (in == end) {
95
0
      fr_strerror_printf("Failed parsing fractional component \"%s\" of timeval", in);
96
0
      return -1;
97
0
    }
98
0
    while (len < 6) {
99
0
      sec *= 10;
100
0
      len++;
101
0
    }
102
0
    tv.tv_usec = sec;
103
0
  }
104
0
  *out = tv;
105
0
  return 0;
106
0
}