]>
Commit | Line | Data |
---|---|---|
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 | ||
26 | const char *program_name; | |
27 | ||
28 | void | |
29 | out_of_memory(void) | |
30 | { | |
31 | ovs_fatal(0, "virtual memory exhausted"); | |
32 | } | |
33 | ||
34 | void * | |
35 | xcalloc(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 | ||
45 | void * | |
46 | xmalloc(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 | ||
56 | void * | |
57 | xrealloc(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 | ||
67 | void * | |
68 | xmemdup(const void *p_, size_t size) | |
69 | { | |
70 | void *p = xmalloc(size); | |
71 | memcpy(p, p_, size); | |
72 | return p; | |
73 | } | |
74 | ||
75 | char * | |
76 | xmemdup0(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 | ||
84 | char * | |
85 | xstrdup(const char *s) | |
86 | { | |
87 | return xmemdup0(s, strlen(s)); | |
88 | } | |
89 | ||
90 | char * | |
91 | xvasprintf(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 | ||
108 | void * | |
109 | x2nrealloc(void *p, size_t *n, size_t s) | |
110 | { | |
111 | *n = *n == 0 ? 1 : 2 * *n; | |
112 | return xrealloc(p, *n * s); | |
113 | } | |
114 | ||
115 | char * | |
116 | xasprintf(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 | ||
128 | void | |
129 | ovs_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 | ||
139 | void | |
140 | ovs_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 | ||
155 | void | |
156 | ovs_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]);". */ | |
174 | void 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. */ | |
181 | void | |
182 | ovs_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. */ | |
196 | void | |
197 | ovs_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 | ||
245 | bool | |
246 | str_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 | ||
254 | bool | |
255 | str_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 | ||
263 | bool | |
264 | str_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 | ||
280 | bool | |
281 | str_to_uint(const char *s, int base, unsigned int *u) | |
282 | { | |
283 | return str_to_int(s, base, (int *) u); | |
284 | } | |
285 | ||
286 | bool | |
287 | str_to_ulong(const char *s, int base, unsigned long *ul) | |
288 | { | |
289 | return str_to_long(s, base, (long *) ul); | |
290 | } | |
291 | ||
292 | bool | |
293 | str_to_ullong(const char *s, int base, unsigned long long *ull) | |
294 | { | |
295 | return str_to_llong(s, base, (long long *) ull); | |
296 | } |