]> git.proxmox.com Git - mirror_ovs.git/blame - lib/util.c
Implement library for lockfiles and use it in cfg code.
[mirror_ovs.git] / lib / util.c
CommitLineData
064af421
BP
1/*
2 * Copyright (c) 2008, 2009 Nicira Networks.
3 *
a14bc59f
BP
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
064af421 7 *
a14bc59f
BP
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
064af421
BP
15 */
16
17#include <config.h>
18#include "util.h"
19#include <errno.h>
20#include <stdarg.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include "coverage.h"
25
26const char *program_name;
27
28void
29out_of_memory(void)
30{
31 ovs_fatal(0, "virtual memory exhausted");
32}
33
34void *
35xcalloc(size_t count, size_t size)
36{
37 void *p = count && size ? calloc(count, size) : malloc(1);
38 COVERAGE_INC(util_xalloc);
39 if (p == NULL) {
40 out_of_memory();
41 }
42 return p;
43}
44
45void *
46xmalloc(size_t size)
47{
48 void *p = malloc(size ? size : 1);
49 COVERAGE_INC(util_xalloc);
50 if (p == NULL) {
51 out_of_memory();
52 }
53 return p;
54}
55
56void *
57xrealloc(void *p, size_t size)
58{
59 p = realloc(p, size ? size : 1);
60 COVERAGE_INC(util_xalloc);
61 if (p == NULL) {
62 out_of_memory();
63 }
64 return p;
65}
66
67void *
68xmemdup(const void *p_, size_t size)
69{
70 void *p = xmalloc(size);
71 memcpy(p, p_, size);
72 return p;
73}
74
75char *
76xmemdup0(const char *p_, size_t length)
77{
78 char *p = xmalloc(length + 1);
79 memcpy(p, p_, length);
80 p[length] = '\0';
81 return p;
82}
83
84char *
85xstrdup(const char *s)
86{
87 return xmemdup0(s, strlen(s));
88}
89
90char *
91xvasprintf(const char *format, va_list args)
92{
93 va_list args2;
94 size_t needed;
95 char *s;
96
97 va_copy(args2, args);
98 needed = vsnprintf(NULL, 0, format, args);
99
100 s = xmalloc(needed + 1);
101
102 vsnprintf(s, needed + 1, format, args2);
103 va_end(args2);
104
105 return s;
106}
107
108void *
109x2nrealloc(void *p, size_t *n, size_t s)
110{
111 *n = *n == 0 ? 1 : 2 * *n;
112 return xrealloc(p, *n * s);
113}
114
115char *
116xasprintf(const char *format, ...)
117{
118 va_list args;
119 char *s;
120
121 va_start(args, format);
122 s = xvasprintf(format, args);
123 va_end(args);
124
125 return s;
126}
127
128void
129ovs_strlcpy(char *dst, const char *src, size_t size)
130{
131 if (size > 0) {
132 size_t n = strlen(src);
133 size_t n_copy = MIN(n, size - 1);
134 memcpy(dst, src, n_copy);
135 dst[n_copy] = '\0';
136 }
137}
138
139void
140ovs_fatal(int err_no, const char *format, ...)
141{
142 va_list args;
143
144 fprintf(stderr, "%s: ", program_name);
145 va_start(args, format);
146 vfprintf(stderr, format, args);
147 va_end(args);
148 if (err_no != 0)
149 fprintf(stderr, " (%s)", strerror(err_no));
150 putc('\n', stderr);
151
152 exit(EXIT_FAILURE);
153}
154
155void
156ovs_error(int err_no, const char *format, ...)
157{
158 int save_errno = errno;
159 va_list args;
160
161 fprintf(stderr, "%s: ", program_name);
162 va_start(args, format);
163 vfprintf(stderr, format, args);
164 va_end(args);
165 if (err_no != 0)
166 fprintf(stderr, " (%s)", strerror(err_no));
167 putc('\n', stderr);
168
169 errno = save_errno;
170}
171
172/* Sets program_name based on 'argv0'. Should be called at the beginning of
173 * main(), as "set_program_name(argv[0]);". */
174void set_program_name(const char *argv0)
175{
176 const char *slash = strrchr(argv0, '/');
177 program_name = slash ? slash + 1 : argv0;
178}
179
180/* Print the version information for the program. */
181void
182ovs_print_version(char *date, char *time,
183 uint8_t min_ofp, uint8_t max_ofp)
184{
185 printf("%s (Open vSwitch) "VERSION BUILDNR"\n", program_name);
186 printf("Compiled %s %s\n", date, time);
187 if (min_ofp || max_ofp) {
188 printf("OpenFlow versions %#x:%#x\n", min_ofp, max_ofp);
189 }
190}
191
192/* Writes the 'size' bytes in 'buf' to 'stream' as hex bytes arranged 16 per
193 * line. Numeric offsets are also included, starting at 'ofs' for the first
194 * byte in 'buf'. If 'ascii' is true then the corresponding ASCII characters
195 * are also rendered alongside. */
196void
197ovs_hex_dump(FILE *stream, const void *buf_, size_t size,
198 uintptr_t ofs, bool ascii)
199{
200 const uint8_t *buf = buf_;
201 const size_t per_line = 16; /* Maximum bytes per line. */
202
203 while (size > 0)
204 {
205 size_t start, end, n;
206 size_t i;
207
208 /* Number of bytes on this line. */
209 start = ofs % per_line;
210 end = per_line;
211 if (end - start > size)
212 end = start + size;
213 n = end - start;
214
215 /* Print line. */
216 fprintf(stream, "%08jx ", (uintmax_t) ROUND_DOWN(ofs, per_line));
217 for (i = 0; i < start; i++)
218 fprintf(stream, " ");
219 for (; i < end; i++)
220 fprintf(stream, "%02hhx%c",
221 buf[i - start], i == per_line / 2 - 1? '-' : ' ');
222 if (ascii)
223 {
224 for (; i < per_line; i++)
225 fprintf(stream, " ");
226 fprintf(stream, "|");
227 for (i = 0; i < start; i++)
228 fprintf(stream, " ");
229 for (; i < end; i++) {
230 int c = buf[i - start];
231 putc(c >= 32 && c < 127 ? c : '.', stream);
232 }
233 for (; i < per_line; i++)
234 fprintf(stream, " ");
235 fprintf(stream, "|");
236 }
237 fprintf(stream, "\n");
238
239 ofs += n;
240 buf += n;
241 size -= n;
242 }
243}
244
245bool
246str_to_int(const char *s, int base, int *i)
247{
248 long long ll;
249 bool ok = str_to_llong(s, base, &ll);
250 *i = ll;
251 return ok;
252}
253
254bool
255str_to_long(const char *s, int base, long *li)
256{
257 long long ll;
258 bool ok = str_to_llong(s, base, &ll);
259 *li = ll;
260 return ok;
261}
262
263bool
264str_to_llong(const char *s, int base, long long *x)
265{
266 int save_errno = errno;
267 char *tail;
268 errno = 0;
269 *x = strtoll(s, &tail, base);
270 if (errno == EINVAL || errno == ERANGE || tail == s || *tail != '\0') {
271 errno = save_errno;
272 *x = 0;
273 return false;
274 } else {
275 errno = save_errno;
276 return true;
277 }
278}
279
280bool
281str_to_uint(const char *s, int base, unsigned int *u)
282{
283 return str_to_int(s, base, (int *) u);
284}
285
286bool
287str_to_ulong(const char *s, int base, unsigned long *ul)
288{
289 return str_to_long(s, base, (long *) ul);
290}
291
292bool
293str_to_ullong(const char *s, int base, unsigned long long *ull)
294{
295 return str_to_llong(s, base, (long long *) ull);
296}