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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
/* SPDX-License-Identifier: GPL-2.0 */
#include "tf.h"
DEFINE_TF_ERRLIST;
int atoi64(const char *str, int64_t *value)
{
char *endptr;
long long tmp;
errno = 0; /* To distinguish success/failure after call */
tmp = strtoll(str, &endptr, 10);
if (errno == ERANGE && (tmp == LLONG_MAX || tmp == LLONG_MIN))
return -E_ATOI_OVERFLOW;
/*
* If there were no digits at all, strtoll() stores the original value
* of str in *endptr.
*/
if (endptr == str)
return -E_ATOI_NO_DIGITS;
/*
* The implementation may also set errno and return 0 in case no
* conversion was performed.
*/
if (errno != 0 && tmp == 0)
return -E_ATOI_NO_DIGITS;
if (*endptr != '\0') /* Further characters after number */
return -E_ATOI_JUNK_AT_END;
*value = tmp;
return 1;
}
__attribute__ ((warn_unused_result))
void *xrealloc(void *p, size_t size)
{
/*
* No need to check for NULL pointers: If p is NULL, the call
* to realloc is equivalent to malloc(size)
*/
assert(size);
if (!(p = realloc(p, size))) {
EMERG_LOG("realloc failed (size = %zu), aborting\n", size);
exit(EXIT_FAILURE);
}
return p;
}
__attribute__ ((warn_unused_result))
void *xmalloc(size_t size)
{
return xrealloc(NULL, size);
}
__attribute__ ((warn_unused_result))
void *xcalloc(size_t size)
{
void *p = xmalloc(size);
memset(p, 0, size);
return p;
}
/*
* Print a formated message to a dynamically allocated string.
*
* This function is similar to vasprintf(), a GNU extension which is not in C
* or POSIX. It allocates a string large enough to hold the output including
* the terminating null byte. The allocated string is returned via the first
* argument and must be freed by the caller. However, unlike vasprintf(), this
* function calls exit() if insufficient memory is available, while vasprintf()
* returns -1 in this case.
*
* It returns the number of bytes written, not including the terminating \p
* NULL character.
*/
__attribute__ ((format (printf, 2, 0)))
unsigned xvasprintf(char **result, const char *fmt, va_list ap)
{
int ret;
size_t size = 150;
va_list aq;
*result = xmalloc(size + 1);
va_copy(aq, ap);
ret = vsnprintf(*result, size, fmt, aq);
va_end(aq);
assert(ret >= 0);
if ((size_t)ret < size)
return ret;
size = ret + 1;
*result = xrealloc(*result, size);
va_copy(aq, ap);
ret = vsnprintf(*result, size, fmt, aq);
va_end(aq);
assert(ret >= 0 && (size_t)ret < size);
return ret;
}
__attribute__ ((format (printf, 2, 3)))
/* Print to a dynamically allocated string, variable number of arguments. */
unsigned xasprintf(char **result, const char *fmt, ...)
{
va_list ap;
unsigned ret;
va_start(ap, fmt);
ret = xvasprintf(result, fmt, ap);
va_end(ap);
return ret;
}
/*
* Compile a regular expression.
*
* This simple wrapper calls regcomp(3) and logs a message on errors.
*/
int xregcomp(regex_t *preg, const char *regex, int cflags)
{
char *buf;
size_t size;
int ret = regcomp(preg, regex, cflags);
if (ret == 0)
return 1;
size = regerror(ret, preg, NULL, 0);
buf = xmalloc(size);
regerror(ret, preg, buf, size);
ERROR_LOG("%s\n", buf);
free(buf);
return -E_REGEX;
}
static int loglevel_arg_val;
__attribute__ ((format (printf, 2, 3)))
void txp_log(int ll, const char* fmt,...)
{
va_list argp;
if (ll < loglevel_arg_val)
return;
va_start(argp, fmt);
vfprintf(stderr, fmt, argp);
va_end(argp);
}
|