]>
Commit | Line | Data |
---|---|---|
064af421 | 1 | /* |
71d7c22f | 2 | * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. |
064af421 | 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> | |
daf03c53 | 24 | #include <unistd.h> |
064af421 | 25 | #include "coverage.h" |
daf03c53 BP |
26 | #include "vlog.h" |
27 | ||
d98e6007 | 28 | VLOG_DEFINE_THIS_MODULE(util); |
5136ce49 | 29 | |
d76f09ea BP |
30 | COVERAGE_DEFINE(util_xalloc); |
31 | ||
064af421 BP |
32 | const char *program_name; |
33 | ||
34 | void | |
d295e8e9 | 35 | out_of_memory(void) |
064af421 | 36 | { |
c1c8308a | 37 | ovs_abort(0, "virtual memory exhausted"); |
064af421 BP |
38 | } |
39 | ||
40 | void * | |
d295e8e9 | 41 | xcalloc(size_t count, size_t size) |
064af421 BP |
42 | { |
43 | void *p = count && size ? calloc(count, size) : malloc(1); | |
44 | COVERAGE_INC(util_xalloc); | |
45 | if (p == NULL) { | |
46 | out_of_memory(); | |
47 | } | |
48 | return p; | |
49 | } | |
50 | ||
ec6fde61 BP |
51 | void * |
52 | xzalloc(size_t size) | |
53 | { | |
54 | return xcalloc(1, size); | |
55 | } | |
56 | ||
064af421 | 57 | void * |
d295e8e9 | 58 | xmalloc(size_t size) |
064af421 BP |
59 | { |
60 | void *p = malloc(size ? size : 1); | |
61 | COVERAGE_INC(util_xalloc); | |
62 | if (p == NULL) { | |
63 | out_of_memory(); | |
64 | } | |
65 | return p; | |
66 | } | |
67 | ||
68 | void * | |
d295e8e9 | 69 | xrealloc(void *p, size_t size) |
064af421 BP |
70 | { |
71 | p = realloc(p, size ? size : 1); | |
72 | COVERAGE_INC(util_xalloc); | |
73 | if (p == NULL) { | |
74 | out_of_memory(); | |
75 | } | |
76 | return p; | |
77 | } | |
78 | ||
79 | void * | |
80 | xmemdup(const void *p_, size_t size) | |
81 | { | |
82 | void *p = xmalloc(size); | |
83 | memcpy(p, p_, size); | |
84 | return p; | |
85 | } | |
86 | ||
87 | char * | |
88 | xmemdup0(const char *p_, size_t length) | |
89 | { | |
90 | char *p = xmalloc(length + 1); | |
91 | memcpy(p, p_, length); | |
92 | p[length] = '\0'; | |
93 | return p; | |
94 | } | |
95 | ||
96 | char * | |
d295e8e9 | 97 | xstrdup(const char *s) |
064af421 BP |
98 | { |
99 | return xmemdup0(s, strlen(s)); | |
100 | } | |
101 | ||
102 | char * | |
103 | xvasprintf(const char *format, va_list args) | |
104 | { | |
105 | va_list args2; | |
106 | size_t needed; | |
107 | char *s; | |
108 | ||
109 | va_copy(args2, args); | |
110 | needed = vsnprintf(NULL, 0, format, args); | |
111 | ||
112 | s = xmalloc(needed + 1); | |
113 | ||
114 | vsnprintf(s, needed + 1, format, args2); | |
115 | va_end(args2); | |
116 | ||
117 | return s; | |
118 | } | |
119 | ||
120 | void * | |
121 | x2nrealloc(void *p, size_t *n, size_t s) | |
122 | { | |
123 | *n = *n == 0 ? 1 : 2 * *n; | |
124 | return xrealloc(p, *n * s); | |
125 | } | |
126 | ||
127 | char * | |
128 | xasprintf(const char *format, ...) | |
129 | { | |
130 | va_list args; | |
131 | char *s; | |
132 | ||
133 | va_start(args, format); | |
134 | s = xvasprintf(format, args); | |
135 | va_end(args); | |
136 | ||
137 | return s; | |
138 | } | |
139 | ||
e868fb3d BP |
140 | /* Similar to strlcpy() from OpenBSD, but it never reads more than 'size - 1' |
141 | * bytes from 'src' and doesn't return anything. */ | |
064af421 BP |
142 | void |
143 | ovs_strlcpy(char *dst, const char *src, size_t size) | |
144 | { | |
145 | if (size > 0) { | |
e868fb3d BP |
146 | size_t len = strnlen(src, size - 1); |
147 | memcpy(dst, src, len); | |
148 | dst[len] = '\0'; | |
064af421 BP |
149 | } |
150 | } | |
151 | ||
71d7c22f BP |
152 | /* Copies 'src' to 'dst'. Reads no more than 'size - 1' bytes from 'src'. |
153 | * Always null-terminates 'dst' (if 'size' is nonzero), and writes a zero byte | |
154 | * to every otherwise unused byte in 'dst'. | |
155 | * | |
156 | * Except for performance, the following call: | |
157 | * ovs_strzcpy(dst, src, size); | |
158 | * is equivalent to these two calls: | |
159 | * memset(dst, '\0', size); | |
160 | * ovs_strlcpy(dst, src, size); | |
161 | * | |
162 | * (Thus, ovs_strzcpy() is similar to strncpy() without some of the pitfalls.) | |
163 | */ | |
164 | void | |
165 | ovs_strzcpy(char *dst, const char *src, size_t size) | |
166 | { | |
167 | if (size > 0) { | |
168 | size_t len = strnlen(src, size - 1); | |
169 | memcpy(dst, src, len); | |
170 | memset(dst + len, '\0', size - len); | |
171 | } | |
172 | } | |
173 | ||
c1c8308a BP |
174 | /* Prints 'format' on stderr, formatting it like printf() does. If 'err_no' is |
175 | * nonzero, then it is formatted with ovs_retval_to_string() and appended to | |
176 | * the message inside parentheses. Then, terminates with abort(). | |
177 | * | |
178 | * This function is preferred to ovs_fatal() in a situation where it would make | |
179 | * sense for a monitoring process to restart the daemon. | |
180 | * | |
181 | * 'format' should not end with a new-line, because this function will add one | |
182 | * itself. */ | |
183 | void | |
184 | ovs_abort(int err_no, const char *format, ...) | |
185 | { | |
186 | va_list args; | |
187 | ||
188 | va_start(args, format); | |
189 | ovs_error_valist(err_no, format, args); | |
190 | va_end(args); | |
191 | ||
192 | abort(); | |
193 | } | |
194 | ||
195 | /* Prints 'format' on stderr, formatting it like printf() does. If 'err_no' is | |
196 | * nonzero, then it is formatted with ovs_retval_to_string() and appended to | |
197 | * the message inside parentheses. Then, terminates with EXIT_FAILURE. | |
198 | * | |
199 | * 'format' should not end with a new-line, because this function will add one | |
200 | * itself. */ | |
064af421 BP |
201 | void |
202 | ovs_fatal(int err_no, const char *format, ...) | |
203 | { | |
204 | va_list args; | |
205 | ||
064af421 | 206 | va_start(args, format); |
fcaddd4d BP |
207 | ovs_fatal_valist(err_no, format, args); |
208 | } | |
064af421 | 209 | |
fcaddd4d BP |
210 | /* Same as ovs_fatal() except that the arguments are supplied as a va_list. */ |
211 | void | |
212 | ovs_fatal_valist(int err_no, const char *format, va_list args) | |
213 | { | |
214 | ovs_error_valist(err_no, format, args); | |
064af421 BP |
215 | exit(EXIT_FAILURE); |
216 | } | |
217 | ||
c1c8308a BP |
218 | /* Prints 'format' on stderr, formatting it like printf() does. If 'err_no' is |
219 | * nonzero, then it is formatted with ovs_retval_to_string() and appended to | |
220 | * the message inside parentheses. | |
221 | * | |
222 | * 'format' should not end with a new-line, because this function will add one | |
223 | * itself. */ | |
064af421 BP |
224 | void |
225 | ovs_error(int err_no, const char *format, ...) | |
226 | { | |
064af421 BP |
227 | va_list args; |
228 | ||
064af421 | 229 | va_start(args, format); |
c1c8308a | 230 | ovs_error_valist(err_no, format, args); |
064af421 | 231 | va_end(args); |
c1c8308a BP |
232 | } |
233 | ||
234 | /* Same as ovs_error() except that the arguments are supplied as a va_list. */ | |
235 | void | |
236 | ovs_error_valist(int err_no, const char *format, va_list args) | |
237 | { | |
238 | int save_errno = errno; | |
239 | ||
240 | fprintf(stderr, "%s: ", program_name); | |
241 | vfprintf(stderr, format, args); | |
0fec26b0 | 242 | if (err_no != 0) { |
c18ea70d | 243 | fprintf(stderr, " (%s)", ovs_retval_to_string(err_no)); |
0fec26b0 | 244 | } |
064af421 BP |
245 | putc('\n', stderr); |
246 | ||
247 | errno = save_errno; | |
248 | } | |
249 | ||
c18ea70d AE |
250 | /* Many OVS functions return an int which is one of: |
251 | * - 0: no error yet | |
252 | * - >0: errno value | |
253 | * - EOF: end of file (not necessarily an error; depends on the function called) | |
254 | * | |
255 | * Returns the appropriate human-readable string. The caller must copy the | |
256 | * string if it wants to hold onto it, as the storage may be overwritten on | |
257 | * subsequent function calls. | |
258 | */ | |
259 | const char * | |
260 | ovs_retval_to_string(int retval) | |
261 | { | |
262 | static char unknown[48]; | |
263 | ||
264 | if (!retval) { | |
265 | return ""; | |
266 | } | |
267 | if (retval > 0) { | |
268 | return strerror(retval); | |
269 | } | |
270 | if (retval == EOF) { | |
271 | return "End of file"; | |
272 | } | |
273 | snprintf(unknown, sizeof unknown, "***unknown return value: %d***", retval); | |
274 | return unknown; | |
275 | } | |
276 | ||
064af421 BP |
277 | /* Sets program_name based on 'argv0'. Should be called at the beginning of |
278 | * main(), as "set_program_name(argv[0]);". */ | |
279 | void set_program_name(const char *argv0) | |
280 | { | |
281 | const char *slash = strrchr(argv0, '/'); | |
282 | program_name = slash ? slash + 1 : argv0; | |
283 | } | |
284 | ||
285 | /* Print the version information for the program. */ | |
286 | void | |
d295e8e9 | 287 | ovs_print_version(char *date, char *time, |
064af421 BP |
288 | uint8_t min_ofp, uint8_t max_ofp) |
289 | { | |
290 | printf("%s (Open vSwitch) "VERSION BUILDNR"\n", program_name); | |
291 | printf("Compiled %s %s\n", date, time); | |
292 | if (min_ofp || max_ofp) { | |
293 | printf("OpenFlow versions %#x:%#x\n", min_ofp, max_ofp); | |
294 | } | |
295 | } | |
296 | ||
297 | /* Writes the 'size' bytes in 'buf' to 'stream' as hex bytes arranged 16 per | |
298 | * line. Numeric offsets are also included, starting at 'ofs' for the first | |
299 | * byte in 'buf'. If 'ascii' is true then the corresponding ASCII characters | |
300 | * are also rendered alongside. */ | |
301 | void | |
302 | ovs_hex_dump(FILE *stream, const void *buf_, size_t size, | |
303 | uintptr_t ofs, bool ascii) | |
304 | { | |
305 | const uint8_t *buf = buf_; | |
306 | const size_t per_line = 16; /* Maximum bytes per line. */ | |
307 | ||
308 | while (size > 0) | |
309 | { | |
310 | size_t start, end, n; | |
311 | size_t i; | |
312 | ||
313 | /* Number of bytes on this line. */ | |
314 | start = ofs % per_line; | |
315 | end = per_line; | |
316 | if (end - start > size) | |
317 | end = start + size; | |
318 | n = end - start; | |
319 | ||
320 | /* Print line. */ | |
321 | fprintf(stream, "%08jx ", (uintmax_t) ROUND_DOWN(ofs, per_line)); | |
322 | for (i = 0; i < start; i++) | |
323 | fprintf(stream, " "); | |
324 | for (; i < end; i++) | |
325 | fprintf(stream, "%02hhx%c", | |
326 | buf[i - start], i == per_line / 2 - 1? '-' : ' '); | |
327 | if (ascii) | |
328 | { | |
329 | for (; i < per_line; i++) | |
330 | fprintf(stream, " "); | |
331 | fprintf(stream, "|"); | |
332 | for (i = 0; i < start; i++) | |
333 | fprintf(stream, " "); | |
334 | for (; i < end; i++) { | |
335 | int c = buf[i - start]; | |
336 | putc(c >= 32 && c < 127 ? c : '.', stream); | |
337 | } | |
338 | for (; i < per_line; i++) | |
339 | fprintf(stream, " "); | |
340 | fprintf(stream, "|"); | |
341 | } | |
342 | fprintf(stream, "\n"); | |
343 | ||
344 | ofs += n; | |
345 | buf += n; | |
346 | size -= n; | |
347 | } | |
348 | } | |
349 | ||
350 | bool | |
351 | str_to_int(const char *s, int base, int *i) | |
352 | { | |
353 | long long ll; | |
354 | bool ok = str_to_llong(s, base, &ll); | |
355 | *i = ll; | |
356 | return ok; | |
357 | } | |
358 | ||
359 | bool | |
360 | str_to_long(const char *s, int base, long *li) | |
361 | { | |
362 | long long ll; | |
363 | bool ok = str_to_llong(s, base, &ll); | |
364 | *li = ll; | |
365 | return ok; | |
366 | } | |
367 | ||
368 | bool | |
369 | str_to_llong(const char *s, int base, long long *x) | |
370 | { | |
371 | int save_errno = errno; | |
372 | char *tail; | |
373 | errno = 0; | |
374 | *x = strtoll(s, &tail, base); | |
375 | if (errno == EINVAL || errno == ERANGE || tail == s || *tail != '\0') { | |
376 | errno = save_errno; | |
377 | *x = 0; | |
378 | return false; | |
379 | } else { | |
380 | errno = save_errno; | |
381 | return true; | |
382 | } | |
383 | } | |
384 | ||
385 | bool | |
386 | str_to_uint(const char *s, int base, unsigned int *u) | |
387 | { | |
388 | return str_to_int(s, base, (int *) u); | |
389 | } | |
390 | ||
391 | bool | |
392 | str_to_ulong(const char *s, int base, unsigned long *ul) | |
393 | { | |
394 | return str_to_long(s, base, (long *) ul); | |
395 | } | |
396 | ||
397 | bool | |
398 | str_to_ullong(const char *s, int base, unsigned long long *ull) | |
399 | { | |
400 | return str_to_llong(s, base, (long long *) ull); | |
401 | } | |
f38b84ea BP |
402 | |
403 | /* Converts floating-point string 's' into a double. If successful, stores | |
404 | * the double in '*d' and returns true; on failure, stores 0 in '*d' and | |
405 | * returns false. | |
406 | * | |
407 | * Underflow (e.g. "1e-9999") is not considered an error, but overflow | |
408 | * (e.g. "1e9999)" is. */ | |
409 | bool | |
410 | str_to_double(const char *s, double *d) | |
411 | { | |
412 | int save_errno = errno; | |
413 | char *tail; | |
414 | errno = 0; | |
415 | *d = strtod(s, &tail); | |
416 | if (errno == EINVAL || (errno == ERANGE && *d != 0) | |
417 | || tail == s || *tail != '\0') { | |
418 | errno = save_errno; | |
419 | *d = 0; | |
420 | return false; | |
421 | } else { | |
422 | errno = save_errno; | |
423 | return true; | |
424 | } | |
425 | } | |
426 | ||
427 | /* Returns the value of 'c' as a hexadecimal digit. */ | |
428 | int | |
429 | hexit_value(int c) | |
430 | { | |
431 | switch (c) { | |
432 | case '0': case '1': case '2': case '3': case '4': | |
433 | case '5': case '6': case '7': case '8': case '9': | |
434 | return c - '0'; | |
435 | ||
436 | case 'a': case 'A': | |
437 | return 0xa; | |
438 | ||
439 | case 'b': case 'B': | |
440 | return 0xb; | |
441 | ||
442 | case 'c': case 'C': | |
443 | return 0xc; | |
444 | ||
445 | case 'd': case 'D': | |
446 | return 0xd; | |
447 | ||
448 | case 'e': case 'E': | |
449 | return 0xe; | |
450 | ||
451 | case 'f': case 'F': | |
452 | return 0xf; | |
f38b84ea | 453 | |
09246b99 BP |
454 | default: |
455 | return -1; | |
456 | } | |
f38b84ea | 457 | } |
29d4af60 | 458 | |
bf971267 BP |
459 | /* Returns the integer value of the 'n' hexadecimal digits starting at 's', or |
460 | * UINT_MAX if one of those "digits" is not really a hex digit. If 'ok' is | |
461 | * nonnull, '*ok' is set to true if the conversion succeeds or to false if a | |
462 | * non-hex digit is detected. */ | |
463 | unsigned int | |
464 | hexits_value(const char *s, size_t n, bool *ok) | |
465 | { | |
466 | unsigned int value; | |
467 | size_t i; | |
468 | ||
469 | value = 0; | |
470 | for (i = 0; i < n; i++) { | |
471 | int hexit = hexit_value(s[i]); | |
472 | if (hexit < 0) { | |
473 | if (ok) { | |
474 | *ok = false; | |
475 | } | |
476 | return UINT_MAX; | |
477 | } | |
478 | value = (value << 4) + hexit; | |
479 | } | |
480 | if (ok) { | |
481 | *ok = true; | |
482 | } | |
483 | return value; | |
484 | } | |
485 | ||
daf03c53 BP |
486 | /* Returns the current working directory as a malloc()'d string, or a null |
487 | * pointer if the current working directory cannot be determined. */ | |
488 | char * | |
489 | get_cwd(void) | |
490 | { | |
491 | long int path_max; | |
492 | size_t size; | |
493 | ||
494 | /* Get maximum path length or at least a reasonable estimate. */ | |
495 | path_max = pathconf(".", _PC_PATH_MAX); | |
496 | size = (path_max < 0 ? 1024 | |
497 | : path_max > 10240 ? 10240 | |
498 | : path_max); | |
499 | ||
500 | /* Get current working directory. */ | |
501 | for (;;) { | |
502 | char *buf = xmalloc(size); | |
503 | if (getcwd(buf, size)) { | |
504 | return xrealloc(buf, strlen(buf) + 1); | |
505 | } else { | |
506 | int error = errno; | |
507 | free(buf); | |
508 | if (error != ERANGE) { | |
509 | VLOG_WARN("getcwd failed (%s)", strerror(error)); | |
510 | return NULL; | |
511 | } | |
512 | size *= 2; | |
513 | } | |
514 | } | |
515 | } | |
516 | ||
e1aff6f9 BP |
517 | static char * |
518 | all_slashes_name(const char *s) | |
519 | { | |
520 | return xstrdup(s[0] == '/' && s[1] == '/' && s[2] != '/' ? "//" | |
521 | : s[0] == '/' ? "/" | |
522 | : "."); | |
523 | } | |
524 | ||
29d4af60 BP |
525 | /* Returns the directory name portion of 'file_name' as a malloc()'d string, |
526 | * similar to the POSIX dirname() function but thread-safe. */ | |
527 | char * | |
528 | dir_name(const char *file_name) | |
529 | { | |
530 | size_t len = strlen(file_name); | |
531 | while (len > 0 && file_name[len - 1] == '/') { | |
532 | len--; | |
533 | } | |
534 | while (len > 0 && file_name[len - 1] != '/') { | |
535 | len--; | |
536 | } | |
537 | while (len > 0 && file_name[len - 1] == '/') { | |
538 | len--; | |
539 | } | |
e1aff6f9 BP |
540 | return len ? xmemdup0(file_name, len) : all_slashes_name(file_name); |
541 | } | |
542 | ||
543 | /* Returns the file name portion of 'file_name' as a malloc()'d string, | |
544 | * similar to the POSIX basename() function but thread-safe. */ | |
545 | char * | |
546 | base_name(const char *file_name) | |
547 | { | |
548 | size_t end, start; | |
549 | ||
550 | end = strlen(file_name); | |
551 | while (end > 0 && file_name[end - 1] == '/') { | |
552 | end--; | |
553 | } | |
554 | ||
555 | if (!end) { | |
556 | return all_slashes_name(file_name); | |
29d4af60 | 557 | } |
e1aff6f9 BP |
558 | |
559 | start = end; | |
560 | while (start > 0 && file_name[start - 1] != '/') { | |
561 | start--; | |
562 | } | |
563 | ||
564 | return xmemdup0(file_name + start, end - start); | |
29d4af60 | 565 | } |
18b9283b | 566 | |
daf03c53 BP |
567 | /* If 'file_name' starts with '/', returns a copy of 'file_name'. Otherwise, |
568 | * returns an absolute path to 'file_name' considering it relative to 'dir', | |
569 | * which itself must be absolute. 'dir' may be null or the empty string, in | |
570 | * which case the current working directory is used. | |
571 | * | |
572 | * Returns a null pointer if 'dir' is null and getcwd() fails. */ | |
573 | char * | |
574 | abs_file_name(const char *dir, const char *file_name) | |
575 | { | |
576 | if (file_name[0] == '/') { | |
577 | return xstrdup(file_name); | |
578 | } else if (dir && dir[0]) { | |
579 | char *separator = dir[strlen(dir) - 1] == '/' ? "" : "/"; | |
580 | return xasprintf("%s%s%s", dir, separator, file_name); | |
581 | } else { | |
582 | char *cwd = get_cwd(); | |
583 | if (cwd) { | |
584 | char *abs_name = xasprintf("%s/%s", cwd, file_name); | |
585 | free(cwd); | |
586 | return abs_name; | |
587 | } else { | |
588 | return NULL; | |
589 | } | |
590 | } | |
591 | } | |
592 | ||
593 | ||
18b9283b | 594 | /* Pass a value to this function if it is marked with |
d295e8e9 JP |
595 | * __attribute__((warn_unused_result)) and you genuinely want to ignore |
596 | * its return value. (Note that every scalar type can be implicitly | |
18b9283b | 597 | * converted to bool.) */ |
c69ee87c | 598 | void ignore(bool x OVS_UNUSED) { } |
44b4d050 BP |
599 | |
600 | /* Returns an appropriate delimiter for inserting just before the 0-based item | |
601 | * 'index' in a list that has 'total' items in it. */ | |
602 | const char * | |
603 | english_list_delimiter(size_t index, size_t total) | |
604 | { | |
605 | return (index == 0 ? "" | |
606 | : index < total - 1 ? ", " | |
607 | : total > 2 ? ", and " | |
608 | : " and "); | |
609 | } |