/src/openvswitch/lib/util.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc. |
3 | | * |
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: |
7 | | * |
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. |
15 | | */ |
16 | | |
17 | | #include <config.h> |
18 | | #include "util.h" |
19 | | #include <ctype.h> |
20 | | #include <errno.h> |
21 | | #include <limits.h> |
22 | | #include <pthread.h> |
23 | | #include <stdarg.h> |
24 | | #include <stdint.h> |
25 | | #include <stdio.h> |
26 | | #include <stdlib.h> |
27 | | #include <string.h> |
28 | | #ifdef __linux__ |
29 | | #include <sys/prctl.h> |
30 | | #include <sys/utsname.h> |
31 | | #endif |
32 | | #include <sys/stat.h> |
33 | | #include <unistd.h> |
34 | | #include "bitmap.h" |
35 | | #include "byte-order.h" |
36 | | #include "coverage.h" |
37 | | #include "ovs-rcu.h" |
38 | | #include "ovs-thread.h" |
39 | | #include "socket-util.h" |
40 | | #include "timeval.h" |
41 | | #include "openvswitch/vlog.h" |
42 | | #ifdef HAVE_PTHREAD_SET_NAME_NP |
43 | | #include <pthread_np.h> |
44 | | #endif |
45 | | |
46 | | VLOG_DEFINE_THIS_MODULE(util); |
47 | | |
48 | | #ifdef __linux__ |
49 | 0 | #define LINUX 1 |
50 | | #include <asm/param.h> |
51 | | #else |
52 | | #define LINUX 0 |
53 | | #endif |
54 | | |
55 | | COVERAGE_DEFINE(util_xalloc); |
56 | | |
57 | | /* argv[0] without directory names. */ |
58 | | char *program_name; |
59 | | |
60 | | /* Name for the currently running thread or process, for log messages, process |
61 | | * listings, and debuggers. */ |
62 | 0 | DEFINE_PER_THREAD_MALLOCED_DATA(char *, subprogram_name); |
63 | | |
64 | | /* --version option output. */ |
65 | | static char *program_version; |
66 | | |
67 | | /* 'true' if mlockall() succeeded, but doesn't support ONFAULT. */ |
68 | | static bool is_all_memory_locked = false; |
69 | | |
70 | | /* Buffer used by ovs_strerror() and ovs_format_message(). */ |
71 | | DEFINE_STATIC_PER_THREAD_DATA(struct { char s[128]; }, |
72 | | strerror_buffer, |
73 | | { "" }); |
74 | | |
75 | | static char *xreadlink(const char *filename); |
76 | | |
77 | | void |
78 | | ovs_assert_failure(const char *where, const char *function, |
79 | | const char *condition) |
80 | 0 | { |
81 | | /* Prevent an infinite loop (or stack overflow) in case VLOG_ABORT happens |
82 | | * to trigger an assertion failure of its own. */ |
83 | 0 | static int reentry = 0; |
84 | |
|
85 | 0 | switch (reentry++) { |
86 | 0 | case 0: |
87 | 0 | VLOG_ABORT("%s: assertion %s failed in %s()", |
88 | 0 | where, condition, function); |
89 | 0 | OVS_NOT_REACHED(); |
90 | | |
91 | 0 | case 1: |
92 | 0 | fprintf(stderr, "%s: assertion %s failed in %s()", |
93 | 0 | where, condition, function); |
94 | 0 | abort(); |
95 | | |
96 | 0 | default: |
97 | 0 | abort(); |
98 | 0 | } |
99 | 0 | } |
100 | | |
101 | | void |
102 | | set_all_memory_locked(void) |
103 | 0 | { |
104 | 0 | is_all_memory_locked = true; |
105 | 0 | } |
106 | | |
107 | | bool |
108 | | memory_all_locked(void) |
109 | 0 | { |
110 | 0 | return is_all_memory_locked; |
111 | 0 | } |
112 | | |
113 | | void |
114 | | out_of_memory(void) |
115 | 0 | { |
116 | 0 | ovs_abort(0, "virtual memory exhausted"); |
117 | 0 | } |
118 | | |
119 | | void * |
120 | | xcalloc__(size_t count, size_t size) |
121 | 23.7k | { |
122 | 23.7k | void *p = count && size ? calloc(count, size) : malloc(1); |
123 | 23.7k | if (p == NULL) { |
124 | 0 | out_of_memory(); |
125 | 0 | } |
126 | 23.7k | return p; |
127 | 23.7k | } |
128 | | |
129 | | void * |
130 | | xzalloc__(size_t size) |
131 | 16.9k | { |
132 | 16.9k | return xcalloc__(1, size); |
133 | 16.9k | } |
134 | | |
135 | | void * |
136 | | xmalloc__(size_t size) |
137 | 21.0M | { |
138 | 21.0M | void *p = malloc(size ? size : 1); |
139 | 21.0M | if (p == NULL) { |
140 | 0 | out_of_memory(); |
141 | 0 | } |
142 | 21.0M | return p; |
143 | 21.0M | } |
144 | | |
145 | | void * |
146 | | xrealloc__(void *p, size_t size) |
147 | 10.6M | { |
148 | 10.6M | p = realloc(p, size ? size : 1); |
149 | 10.6M | if (p == NULL) { |
150 | 0 | out_of_memory(); |
151 | 0 | } |
152 | 10.6M | return p; |
153 | 10.6M | } |
154 | | |
155 | | void * |
156 | | xcalloc(size_t count, size_t size) |
157 | 6.86k | { |
158 | 6.86k | COVERAGE_INC(util_xalloc); |
159 | 6.86k | return xcalloc__(count, size); |
160 | 6.86k | } |
161 | | |
162 | | void * |
163 | | xzalloc(size_t size) |
164 | 16.9k | { |
165 | 16.9k | COVERAGE_INC(util_xalloc); |
166 | 16.9k | return xzalloc__(size); |
167 | 16.9k | } |
168 | | |
169 | | void * |
170 | | xmalloc(size_t size) |
171 | 21.0M | { |
172 | 21.0M | COVERAGE_INC(util_xalloc); |
173 | 21.0M | return xmalloc__(size); |
174 | 21.0M | } |
175 | | |
176 | | void * |
177 | | xrealloc(void *p, size_t size) |
178 | 10.6M | { |
179 | 10.6M | COVERAGE_INC(util_xalloc); |
180 | 10.6M | return xrealloc__(p, size); |
181 | 10.6M | } |
182 | | |
183 | | void * |
184 | | xmemdup(const void *p_, size_t size) |
185 | 4.30k | { |
186 | 4.30k | void *p = xmalloc(size); |
187 | 4.30k | nullable_memcpy(p, p_, size); |
188 | 4.30k | return p; |
189 | 4.30k | } |
190 | | |
191 | | char * |
192 | | xmemdup0(const char *p_, size_t length) |
193 | 186k | { |
194 | 186k | char *p = xmalloc(length + 1); |
195 | 186k | memcpy(p, p_, length); |
196 | 186k | p[length] = '\0'; |
197 | 186k | return p; |
198 | 186k | } |
199 | | |
200 | | char * |
201 | | xstrdup(const char *s) |
202 | 186k | { |
203 | 186k | return xmemdup0(s, strlen(s)); |
204 | 186k | } |
205 | | |
206 | | char * MALLOC_LIKE |
207 | | nullable_xstrdup(const char *s) |
208 | 0 | { |
209 | 0 | return s ? xstrdup(s) : NULL; |
210 | 0 | } |
211 | | |
212 | | bool |
213 | | nullable_string_is_equal(const char *a, const char *b) |
214 | 0 | { |
215 | 0 | return a ? b && !strcmp(a, b) : !b; |
216 | 0 | } |
217 | | |
218 | | char * |
219 | | xvasprintf(const char *format, va_list args) |
220 | 69.6k | { |
221 | 69.6k | va_list args2; |
222 | 69.6k | size_t needed; |
223 | 69.6k | char *s; |
224 | | |
225 | 69.6k | ovs_assert(format); |
226 | | |
227 | 69.6k | va_copy(args2, args); |
228 | 69.6k | needed = vsnprintf(NULL, 0, format, args); |
229 | | |
230 | 69.6k | s = xmalloc(needed + 1); |
231 | | |
232 | 69.6k | vsnprintf(s, needed + 1, format, args2); |
233 | 69.6k | va_end(args2); |
234 | | |
235 | 69.6k | return s; |
236 | 69.6k | } |
237 | | |
238 | | void * |
239 | | x2nrealloc(void *p, size_t *n, size_t s) |
240 | 53.9k | { |
241 | 53.9k | *n = *n == 0 ? 1 : 2 * *n; |
242 | 53.9k | return xrealloc(p, *n * s); |
243 | 53.9k | } |
244 | | |
245 | | /* Allocates and returns 'size' bytes of memory aligned to 'alignment' bytes. |
246 | | * 'alignment' must be a power of two and a multiple of sizeof(void *). |
247 | | * |
248 | | * Use free_size_align() to free the returned memory block. */ |
249 | | void * |
250 | | xmalloc_size_align(size_t size, size_t alignment) |
251 | 0 | { |
252 | 0 | #ifdef HAVE_POSIX_MEMALIGN |
253 | 0 | void *p; |
254 | 0 | int error; |
255 | |
|
256 | 0 | COVERAGE_INC(util_xalloc); |
257 | 0 | error = posix_memalign(&p, alignment, size ? size : 1); |
258 | 0 | if (error != 0) { |
259 | 0 | out_of_memory(); |
260 | 0 | } |
261 | 0 | return p; |
262 | | #else |
263 | | /* Allocate room for: |
264 | | * |
265 | | * - Header padding: Up to alignment - 1 bytes, to allow the |
266 | | * pointer 'q' to be aligned exactly sizeof(void *) bytes before the |
267 | | * beginning of the alignment. |
268 | | * |
269 | | * - Pointer: A pointer to the start of the header padding, to allow us |
270 | | * to free() the block later. |
271 | | * |
272 | | * - User data: 'size' bytes. |
273 | | * |
274 | | * - Trailer padding: Enough to bring the user data up to a alignment |
275 | | * multiple. |
276 | | * |
277 | | * +---------------+---------+------------------------+---------+ |
278 | | * | header | pointer | user data | trailer | |
279 | | * +---------------+---------+------------------------+---------+ |
280 | | * ^ ^ ^ |
281 | | * | | | |
282 | | * p q r |
283 | | * |
284 | | */ |
285 | | void *p, *r, **q; |
286 | | bool runt; |
287 | | |
288 | | if (!IS_POW2(alignment) || (alignment % sizeof(void *) != 0)) { |
289 | | ovs_abort(0, "Invalid alignment"); |
290 | | } |
291 | | |
292 | | p = xmalloc((alignment - 1) |
293 | | + sizeof(void *) |
294 | | + ROUND_UP(size, alignment)); |
295 | | |
296 | | runt = PAD_SIZE((uintptr_t) p, alignment) < sizeof(void *); |
297 | | /* When the padding size < sizeof(void*), we don't have enough room for |
298 | | * pointer 'q'. As a reuslt, need to move 'r' to the next alignment. |
299 | | * So ROUND_UP when xmalloc above, and ROUND_UP again when calculate 'r' |
300 | | * below. |
301 | | */ |
302 | | r = (void *) ROUND_UP((uintptr_t) p + (runt ? alignment : 0), alignment); |
303 | | q = (void **) r - 1; |
304 | | *q = p; |
305 | | |
306 | | return r; |
307 | | #endif |
308 | 0 | } |
309 | | |
310 | | void |
311 | | free_size_align(void *p) |
312 | 0 | { |
313 | 0 | #ifdef HAVE_POSIX_MEMALIGN |
314 | 0 | free(p); |
315 | | #else |
316 | | if (p) { |
317 | | void **q = (void **) p - 1; |
318 | | free(*q); |
319 | | } |
320 | | #endif |
321 | 0 | } |
322 | | |
323 | | /* Allocates and returns 'size' bytes of memory aligned to a cache line and in |
324 | | * dedicated cache lines. That is, the memory block returned will not share a |
325 | | * cache line with other data, avoiding "false sharing". |
326 | | * |
327 | | * Use free_cacheline() to free the returned memory block. */ |
328 | | void * |
329 | | xmalloc_cacheline(size_t size) |
330 | 0 | { |
331 | 0 | return xmalloc_size_align(size, CACHE_LINE_SIZE); |
332 | 0 | } |
333 | | |
334 | | /* Like xmalloc_cacheline() but clears the allocated memory to all zero |
335 | | * bytes. */ |
336 | | void * |
337 | | xzalloc_cacheline(size_t size) |
338 | 0 | { |
339 | 0 | void *p = xmalloc_cacheline(size); |
340 | 0 | memset(p, 0, size); |
341 | 0 | return p; |
342 | 0 | } |
343 | | |
344 | | /* Frees a memory block allocated with xmalloc_cacheline() or |
345 | | * xzalloc_cacheline(). */ |
346 | | void |
347 | | free_cacheline(void *p) |
348 | 0 | { |
349 | 0 | free_size_align(p); |
350 | 0 | } |
351 | | |
352 | | void * |
353 | | xmalloc_pagealign(size_t size) |
354 | 0 | { |
355 | 0 | return xmalloc_size_align(size, get_page_size()); |
356 | 0 | } |
357 | | |
358 | | void |
359 | | free_pagealign(void *p) |
360 | 0 | { |
361 | 0 | free_size_align(p); |
362 | 0 | } |
363 | | |
364 | | char * |
365 | | xasprintf(const char *format, ...) |
366 | 63.1k | { |
367 | 63.1k | va_list args; |
368 | 63.1k | char *s; |
369 | | |
370 | 63.1k | va_start(args, format); |
371 | 63.1k | s = xvasprintf(format, args); |
372 | 63.1k | va_end(args); |
373 | | |
374 | 63.1k | return s; |
375 | 63.1k | } |
376 | | |
377 | | /* Similar to strlcpy() from OpenBSD, but it never reads more than 'size - 1' |
378 | | * bytes from 'src' and doesn't return anything. */ |
379 | | void |
380 | | ovs_strlcpy(char *dst, const char *src, size_t size) |
381 | 70.8k | { |
382 | 70.8k | if (size > 0) { |
383 | 70.8k | size_t len = strnlen(src, size - 1); |
384 | 70.8k | memcpy(dst, src, len); |
385 | 70.8k | dst[len] = '\0'; |
386 | 70.8k | } |
387 | 70.8k | } |
388 | | |
389 | | /* Copies 'src' to 'dst'. Reads no more than 'size - 1' bytes from 'src'. |
390 | | * Always null-terminates 'dst' (if 'size' is nonzero), and writes a zero byte |
391 | | * to every otherwise unused byte in 'dst'. |
392 | | * |
393 | | * Except for performance, the following call: |
394 | | * ovs_strzcpy(dst, src, size); |
395 | | * is equivalent to these two calls: |
396 | | * memset(dst, '\0', size); |
397 | | * ovs_strlcpy(dst, src, size); |
398 | | * |
399 | | * (Thus, ovs_strzcpy() is similar to strncpy() without some of the pitfalls.) |
400 | | */ |
401 | | void |
402 | | ovs_strzcpy(char *dst, const char *src, size_t size) |
403 | 0 | { |
404 | 0 | if (size > 0) { |
405 | 0 | size_t len = strnlen(src, size - 1); |
406 | 0 | memcpy(dst, src, len); |
407 | 0 | memset(dst + len, '\0', size - len); |
408 | 0 | } |
409 | 0 | } |
410 | | |
411 | | /* |
412 | | * Returns true if 'str' ends with given 'suffix'. |
413 | | */ |
414 | | int |
415 | | string_ends_with(const char *str, const char *suffix) |
416 | 0 | { |
417 | 0 | int str_len = strlen(str); |
418 | 0 | int suffix_len = strlen(suffix); |
419 | |
|
420 | 0 | return (str_len >= suffix_len) && |
421 | 0 | (0 == strcmp(str + (str_len - suffix_len), suffix)); |
422 | 0 | } |
423 | | |
424 | | /* Prints 'format' on stderr, formatting it like printf() does. If 'err_no' is |
425 | | * nonzero, then it is formatted with ovs_retval_to_string() and appended to |
426 | | * the message inside parentheses. Then, terminates with abort(). |
427 | | * |
428 | | * This function is preferred to ovs_fatal() in a situation where it would make |
429 | | * sense for a monitoring process to restart the daemon. |
430 | | * |
431 | | * 'format' should not end with a new-line, because this function will add one |
432 | | * itself. */ |
433 | | void |
434 | | ovs_abort(int err_no, const char *format, ...) |
435 | 0 | { |
436 | 0 | va_list args; |
437 | |
|
438 | 0 | va_start(args, format); |
439 | 0 | ovs_abort_valist(err_no, format, args); |
440 | 0 | } |
441 | | |
442 | | /* Same as ovs_abort() except that the arguments are supplied as a va_list. */ |
443 | | void |
444 | | ovs_abort_valist(int err_no, const char *format, va_list args) |
445 | 0 | { |
446 | 0 | ovs_error_valist(err_no, format, args); |
447 | 0 | abort(); |
448 | 0 | } |
449 | | |
450 | | /* Prints 'format' on stderr, formatting it like printf() does. If 'err_no' is |
451 | | * nonzero, then it is formatted with ovs_retval_to_string() and appended to |
452 | | * the message inside parentheses. Then, terminates with EXIT_FAILURE. |
453 | | * |
454 | | * 'format' should not end with a new-line, because this function will add one |
455 | | * itself. */ |
456 | | void |
457 | | ovs_fatal(int err_no, const char *format, ...) |
458 | 0 | { |
459 | 0 | va_list args; |
460 | |
|
461 | 0 | va_start(args, format); |
462 | 0 | ovs_fatal_valist(err_no, format, args); |
463 | 0 | } |
464 | | |
465 | | /* Same as ovs_fatal() except that the arguments are supplied as a va_list. */ |
466 | | void |
467 | | ovs_fatal_valist(int err_no, const char *format, va_list args) |
468 | 0 | { |
469 | 0 | ovs_error_valist(err_no, format, args); |
470 | 0 | exit(EXIT_FAILURE); |
471 | 0 | } |
472 | | |
473 | | /* Prints 'format' on stderr, formatting it like printf() does. If 'err_no' is |
474 | | * nonzero, then it is formatted with ovs_retval_to_string() and appended to |
475 | | * the message inside parentheses. |
476 | | * |
477 | | * 'format' should not end with a new-line, because this function will add one |
478 | | * itself. */ |
479 | | void |
480 | | ovs_error(int err_no, const char *format, ...) |
481 | 0 | { |
482 | 0 | va_list args; |
483 | |
|
484 | 0 | va_start(args, format); |
485 | 0 | ovs_error_valist(err_no, format, args); |
486 | 0 | va_end(args); |
487 | 0 | } |
488 | | |
489 | | /* Same as ovs_error() except that the arguments are supplied as a va_list. */ |
490 | | void |
491 | | ovs_error_valist(int err_no, const char *format, va_list args) |
492 | 0 | { |
493 | 0 | const char *subprogram_name = get_subprogram_name(); |
494 | 0 | int save_errno = errno; |
495 | |
|
496 | 0 | if (subprogram_name[0]) { |
497 | 0 | fprintf(stderr, "%s(%s): ", program_name, subprogram_name); |
498 | 0 | } else { |
499 | 0 | fprintf(stderr, "%s: ", program_name); |
500 | 0 | } |
501 | |
|
502 | 0 | vfprintf(stderr, format, args); |
503 | 0 | if (err_no != 0) { |
504 | 0 | fprintf(stderr, " (%s)", ovs_retval_to_string(err_no)); |
505 | 0 | } |
506 | 0 | putc('\n', stderr); |
507 | |
|
508 | 0 | errno = save_errno; |
509 | 0 | } |
510 | | |
511 | | /* Many OVS functions return an int which is one of: |
512 | | * - 0: no error yet |
513 | | * - >0: errno value |
514 | | * - EOF: end of file (not necessarily an error; depends on the function called) |
515 | | * |
516 | | * Returns the appropriate human-readable string. The caller must copy the |
517 | | * string if it wants to hold onto it, as the storage may be overwritten on |
518 | | * subsequent function calls. |
519 | | */ |
520 | | const char * |
521 | | ovs_retval_to_string(int retval) |
522 | 0 | { |
523 | 0 | return (!retval ? "" |
524 | 0 | : retval == EOF ? "End of file" |
525 | 0 | : ovs_strerror(retval)); |
526 | 0 | } |
527 | | |
528 | | /* This function returns the string describing the error number in 'error'. */ |
529 | | const char * |
530 | | ovs_strerror(int error) |
531 | 0 | { |
532 | 0 | enum { BUFSIZE = sizeof strerror_buffer_get()->s }; |
533 | 0 | int save_errno; |
534 | 0 | char *buffer; |
535 | 0 | char *s; |
536 | |
|
537 | 0 | if (error == 0) { |
538 | | /* |
539 | | * strerror(0) varies among platforms: |
540 | | * |
541 | | * Success |
542 | | * No error |
543 | | * Undefined error: 0 |
544 | | * |
545 | | * We want to provide a consistent result here because |
546 | | * our testsuite has test cases which strictly matches |
547 | | * log messages containing this string. |
548 | | */ |
549 | 0 | return "Success"; |
550 | 0 | } |
551 | | |
552 | 0 | save_errno = errno; |
553 | 0 | buffer = strerror_buffer_get()->s; |
554 | |
|
555 | 0 | #if STRERROR_R_CHAR_P |
556 | | /* GNU style strerror_r() might return an immutable static string, or it |
557 | | * might write and return 'buffer', but in either case we can pass the |
558 | | * returned string directly to the caller. */ |
559 | 0 | s = strerror_r(error, buffer, BUFSIZE); |
560 | | #else /* strerror_r() returns an int. */ |
561 | | s = buffer; |
562 | | if (strerror_r(error, buffer, BUFSIZE)) { |
563 | | /* strerror_r() is only allowed to fail on ERANGE (because the buffer |
564 | | * is too short). We don't check the actual failure reason because |
565 | | * POSIX requires strerror_r() to return the error but old glibc |
566 | | * (before 2.13) returns -1 and sets errno. */ |
567 | | snprintf(buffer, BUFSIZE, "Unknown error %d", error); |
568 | | } |
569 | | #endif |
570 | |
|
571 | 0 | errno = save_errno; |
572 | |
|
573 | 0 | return s; |
574 | 0 | } |
575 | | |
576 | | /* Sets global "program_name" and "program_version" variables. Should |
577 | | * be called at the beginning of main() with "argv[0]" as the argument |
578 | | * to 'argv0'. |
579 | | * |
580 | | * 'version' should contain the version of the caller's program. If 'version' |
581 | | * is the same as the VERSION #define, the caller is assumed to be part of Open |
582 | | * vSwitch. Otherwise, it is assumed to be an external program linking against |
583 | | * the Open vSwitch libraries. |
584 | | * |
585 | | */ |
586 | | void |
587 | | ovs_set_program_name(const char *argv0, const char *version) |
588 | 0 | { |
589 | 0 | const char *slash = strrchr(argv0, '/'); |
590 | 0 | char *basename; |
591 | |
|
592 | 0 | basename = xstrdup(slash ? slash + 1 : argv0); |
593 | |
|
594 | 0 | assert_single_threaded(); |
595 | 0 | free(program_name); |
596 | | /* Remove libtool prefix, if it is there */ |
597 | 0 | if (strncmp(basename, "lt-", 3) == 0) { |
598 | 0 | char *tmp_name = basename; |
599 | 0 | basename = xstrdup(basename + 3); |
600 | 0 | free(tmp_name); |
601 | 0 | } |
602 | 0 | program_name = basename; |
603 | |
|
604 | 0 | free(program_version); |
605 | 0 | if (!strcmp(version, VERSION VERSION_SUFFIX)) { |
606 | 0 | program_version = xasprintf("%s (Open vSwitch) "VERSION |
607 | 0 | VERSION_SUFFIX, |
608 | 0 | program_name); |
609 | 0 | } else { |
610 | 0 | program_version = xasprintf("%s %s\n" |
611 | 0 | "Open vSwitch Library "VERSION |
612 | 0 | VERSION_SUFFIX, |
613 | 0 | program_name, version); |
614 | 0 | } |
615 | 0 | } |
616 | | |
617 | | /* Returns the name of the currently running thread or process. */ |
618 | | const char * |
619 | | get_subprogram_name(void) |
620 | 0 | { |
621 | 0 | const char *name = subprogram_name_get(); |
622 | 0 | return name ? name : ""; |
623 | 0 | } |
624 | | |
625 | | /* Sets 'subprogram_name' as the name of the currently running thread or |
626 | | * process. (This appears in log messages and may also be visible in system |
627 | | * process listings and debuggers.) */ |
628 | | void |
629 | | set_subprogram_name(const char *subprogram_name) |
630 | 0 | { |
631 | 0 | char *pname = xstrdup(subprogram_name ? subprogram_name : program_name); |
632 | 0 | free(subprogram_name_set(pname)); |
633 | |
|
634 | 0 | #if HAVE_GLIBC_PTHREAD_SETNAME_NP |
635 | | /* The maximum supported thread name including '\0' is 16. |
636 | | * Add '>' at 0th position to highlight that the name was truncated. */ |
637 | 0 | if (strlen(pname) > 15) { |
638 | 0 | memmove(pname, &pname[strlen(pname) - 15], 15 + 1); |
639 | 0 | pname[0] = '>'; |
640 | 0 | } |
641 | 0 | pthread_setname_np(pthread_self(), pname); |
642 | | #elif HAVE_NETBSD_PTHREAD_SETNAME_NP |
643 | | pthread_setname_np(pthread_self(), "%s", pname); |
644 | | #elif HAVE_PTHREAD_SET_NAME_NP |
645 | | pthread_set_name_np(pthread_self(), pname); |
646 | | #endif |
647 | 0 | } |
648 | | |
649 | | unsigned int |
650 | | get_page_size(void) |
651 | 0 | { |
652 | 0 | static unsigned int cached; |
653 | |
|
654 | 0 | if (!cached) { |
655 | 0 | long int value = sysconf(_SC_PAGESIZE); |
656 | |
|
657 | 0 | if (value >= 0) { |
658 | 0 | cached = value; |
659 | 0 | } |
660 | 0 | } |
661 | |
|
662 | 0 | return cached; |
663 | 0 | } |
664 | | |
665 | | /* Returns the time at which the system booted, as the number of milliseconds |
666 | | * since the epoch, or 0 if the time of boot cannot be determined. */ |
667 | | long long int |
668 | | get_boot_time(void) |
669 | 0 | { |
670 | 0 | static long long int cache_expiration = LLONG_MIN; |
671 | 0 | static long long int boot_time; |
672 | |
|
673 | 0 | ovs_assert(LINUX); |
674 | |
|
675 | 0 | if (time_msec() >= cache_expiration) { |
676 | 0 | static const char stat_file[] = "/proc/stat"; |
677 | 0 | char line[128]; |
678 | 0 | FILE *stream; |
679 | |
|
680 | 0 | cache_expiration = time_msec() + 5 * 1000; |
681 | |
|
682 | 0 | stream = fopen(stat_file, "r"); |
683 | 0 | if (!stream) { |
684 | 0 | VLOG_ERR_ONCE("%s: open failed (%s)", |
685 | 0 | stat_file, ovs_strerror(errno)); |
686 | 0 | return boot_time; |
687 | 0 | } |
688 | | |
689 | 0 | while (fgets(line, sizeof line, stream)) { |
690 | 0 | long long int btime; |
691 | 0 | if (ovs_scan(line, "btime %lld", &btime)) { |
692 | 0 | boot_time = btime * 1000; |
693 | 0 | goto done; |
694 | 0 | } |
695 | 0 | } |
696 | 0 | VLOG_ERR_ONCE("%s: btime not found", stat_file); |
697 | 0 | done: |
698 | 0 | fclose(stream); |
699 | 0 | } |
700 | 0 | return boot_time; |
701 | 0 | } |
702 | | |
703 | | /* This is a wrapper for setting timeout in control utils. |
704 | | * The value of OVS_CTL_TIMEOUT environment variable will be used by |
705 | | * default if 'secs' is not specified. */ |
706 | | void |
707 | | ctl_timeout_setup(unsigned int secs) |
708 | 0 | { |
709 | 0 | if (!secs) { |
710 | 0 | char *env = getenv("OVS_CTL_TIMEOUT"); |
711 | |
|
712 | 0 | if (env && env[0]) { |
713 | 0 | ovs_ignore(str_to_uint(env, 10, &secs)); |
714 | 0 | } |
715 | 0 | } |
716 | 0 | if (secs) { |
717 | 0 | time_alarm(secs); |
718 | 0 | } |
719 | 0 | } |
720 | | |
721 | | /* Returns a pointer to a string describing the program version. The |
722 | | * caller must not modify or free the returned string. |
723 | | */ |
724 | | const char * |
725 | | ovs_get_program_version(void) |
726 | 0 | { |
727 | 0 | return program_version; |
728 | 0 | } |
729 | | |
730 | | /* Returns a pointer to a string describing the program name. The |
731 | | * caller must not modify or free the returned string. |
732 | | */ |
733 | | const char * |
734 | | ovs_get_program_name(void) |
735 | 0 | { |
736 | 0 | return program_name; |
737 | 0 | } |
738 | | |
739 | | /* Print the version information for the program. */ |
740 | | void |
741 | | ovs_print_version(uint8_t min_ofp, uint8_t max_ofp) |
742 | 0 | { |
743 | 0 | printf("%s\n", program_version); |
744 | 0 | if (min_ofp || max_ofp) { |
745 | 0 | printf("OpenFlow versions %#x:%#x\n", min_ofp, max_ofp); |
746 | 0 | } |
747 | 0 | } |
748 | | |
749 | | /* Writes the 'size' bytes in 'buf' to 'stream' as hex bytes arranged 16 per |
750 | | * line. Numeric offsets are also included, starting at 'ofs' for the first |
751 | | * byte in 'buf'. If 'ascii' is true then the corresponding ASCII characters |
752 | | * are also rendered alongside. */ |
753 | | void |
754 | | ovs_hex_dump(FILE *stream, const void *buf_, size_t size, |
755 | | uintptr_t ofs, bool ascii) |
756 | 4.34k | { |
757 | 4.34k | const uint8_t *buf = buf_; |
758 | 4.34k | const size_t per_line = 16; /* Maximum bytes per line. */ |
759 | | |
760 | 1.95M | while (size > 0) { |
761 | 1.95M | size_t i; |
762 | | |
763 | | /* Number of bytes on this line. */ |
764 | 1.95M | size_t start = ofs % per_line; |
765 | 1.95M | size_t end = per_line; |
766 | 1.95M | if (end - start > size) { |
767 | 4.29k | end = start + size; |
768 | 4.29k | } |
769 | 1.95M | size_t n = end - start; |
770 | | |
771 | | /* Print line. */ |
772 | 1.95M | fprintf(stream, "%08"PRIxMAX" ", |
773 | 1.95M | (uintmax_t) ROUND_DOWN(ofs, per_line)); |
774 | 1.95M | for (i = 0; i < start; i++) { |
775 | 0 | fprintf(stream, " "); |
776 | 0 | } |
777 | 33.2M | for (; i < end; i++) { |
778 | 31.2M | fprintf(stream, "%c%02x", |
779 | 31.2M | i == per_line / 2 ? '-' : ' ', buf[i - start]); |
780 | 31.2M | } |
781 | 1.95M | if (ascii) { |
782 | 1.94M | fprintf(stream, " "); |
783 | 1.96M | for (; i < per_line; i++) { |
784 | 16.5k | fprintf(stream, " "); |
785 | 16.5k | } |
786 | 1.94M | fprintf(stream, "|"); |
787 | 1.94M | for (i = 0; i < start; i++) { |
788 | 0 | fprintf(stream, " "); |
789 | 0 | } |
790 | 33.1M | for (; i < end; i++) { |
791 | 31.1M | int c = buf[i - start]; |
792 | 31.1M | putc(c >= 32 && c < 127 ? c : '.', stream); |
793 | 31.1M | } |
794 | 1.96M | for (; i < per_line; i++) { |
795 | 16.5k | fprintf(stream, " "); |
796 | 16.5k | } |
797 | 1.94M | fprintf(stream, "|"); |
798 | 1.94M | } |
799 | 1.95M | fprintf(stream, "\n"); |
800 | | |
801 | 1.95M | ofs += n; |
802 | 1.95M | buf += n; |
803 | 1.95M | size -= n; |
804 | 1.95M | } |
805 | 4.34k | } |
806 | | |
807 | | bool |
808 | | str_to_int(const char *s, int base, int *i) |
809 | 37.4k | { |
810 | 37.4k | long long ll; |
811 | 37.4k | bool ok = str_to_llong(s, base, &ll); |
812 | | |
813 | 37.4k | if (!ok || ll < INT_MIN || ll > INT_MAX) { |
814 | 423 | *i = 0; |
815 | 423 | return false; |
816 | 423 | } |
817 | 37.0k | *i = ll; |
818 | 37.0k | return true; |
819 | 37.4k | } |
820 | | |
821 | | bool |
822 | | str_to_long(const char *s, int base, long *li) |
823 | 0 | { |
824 | 0 | long long ll; |
825 | 0 | bool ok = str_to_llong(s, base, &ll); |
826 | |
|
827 | 0 | if (!ok || ll < LONG_MIN || ll > LONG_MAX) { |
828 | 0 | *li = 0; |
829 | 0 | return false; |
830 | 0 | } |
831 | 0 | *li = ll; |
832 | 0 | return true; |
833 | 0 | } |
834 | | |
835 | | bool |
836 | | str_to_llong(const char *s, int base, long long *x) |
837 | 276k | { |
838 | 276k | char *tail; |
839 | 276k | bool ok = str_to_llong_with_tail(s, &tail, base, x); |
840 | 276k | if (*tail != '\0') { |
841 | 15.0k | *x = 0; |
842 | 15.0k | return false; |
843 | 15.0k | } |
844 | 261k | return ok; |
845 | 276k | } |
846 | | |
847 | | bool |
848 | | str_to_llong_with_tail(const char *s, char **tail, int base, long long *x) |
849 | 276k | { |
850 | 276k | int save_errno = errno; |
851 | 276k | errno = 0; |
852 | 276k | *x = strtoll(s, tail, base); |
853 | 276k | if (errno == EINVAL || errno == ERANGE || *tail == s) { |
854 | 15.0k | errno = save_errno; |
855 | 15.0k | *x = 0; |
856 | 15.0k | return false; |
857 | 261k | } else { |
858 | 261k | errno = save_errno; |
859 | 261k | return true; |
860 | 261k | } |
861 | 276k | } |
862 | | |
863 | | bool |
864 | | str_to_uint(const char *s, int base, unsigned int *u) |
865 | 238k | { |
866 | 238k | long long ll; |
867 | 238k | bool ok = str_to_llong(s, base, &ll); |
868 | 238k | if (!ok || ll < 0 || ll > UINT_MAX) { |
869 | 14.7k | *u = 0; |
870 | 14.7k | return false; |
871 | 223k | } else { |
872 | 223k | *u = ll; |
873 | 223k | return true; |
874 | 223k | } |
875 | 238k | } |
876 | | |
877 | | bool |
878 | | str_to_ullong(const char *s, int base, unsigned long long *x) |
879 | 7.47k | { |
880 | 7.47k | int save_errno = errno; |
881 | 7.47k | char *tail; |
882 | | |
883 | 7.47k | errno = 0; |
884 | 7.47k | *x = strtoull(s, &tail, base); |
885 | 7.47k | if (errno == EINVAL || errno == ERANGE || tail == s || *tail != '\0') { |
886 | 693 | errno = save_errno; |
887 | 693 | *x = 0; |
888 | 693 | return false; |
889 | 6.78k | } else { |
890 | 6.78k | errno = save_errno; |
891 | 6.78k | return true; |
892 | 6.78k | } |
893 | 7.47k | } |
894 | | |
895 | | bool |
896 | | str_to_llong_range(const char *s, int base, long long *begin, |
897 | | long long *end) |
898 | 0 | { |
899 | 0 | char *tail; |
900 | 0 | if (str_to_llong_with_tail(s, &tail, base, begin) |
901 | 0 | && *tail == '-' |
902 | 0 | && str_to_llong(tail + 1, base, end)) { |
903 | 0 | return true; |
904 | 0 | } |
905 | 0 | *begin = 0; |
906 | 0 | *end = 0; |
907 | 0 | return false; |
908 | 0 | } |
909 | | |
910 | | /* Converts floating-point string 's' into a double. If successful, stores |
911 | | * the double in '*d' and returns true; on failure, stores 0 in '*d' and |
912 | | * returns false. |
913 | | * |
914 | | * Underflow (e.g. "1e-9999") is not considered an error, but overflow |
915 | | * (e.g. "1e9999)" is. */ |
916 | | bool |
917 | | str_to_double(const char *s, double *d) |
918 | 64.1k | { |
919 | 64.1k | int save_errno = errno; |
920 | 64.1k | char *tail; |
921 | 64.1k | errno = 0; |
922 | 64.1k | *d = strtod(s, &tail); |
923 | 64.1k | if (errno == EINVAL || (errno == ERANGE && *d != 0) |
924 | 64.0k | || tail == s || *tail != '\0') { |
925 | 61 | errno = save_errno; |
926 | 61 | *d = 0; |
927 | 61 | return false; |
928 | 64.0k | } else { |
929 | 64.0k | errno = save_errno; |
930 | 64.0k | return true; |
931 | 64.0k | } |
932 | 64.1k | } |
933 | | |
934 | | /* Returns the value of 'c' as a hexadecimal digit. */ |
935 | | int |
936 | | hexit_value(unsigned char c) |
937 | 112M | { |
938 | 112M | static const signed char tbl[UCHAR_MAX + 1] = { |
939 | 112M | #define TBL(x) \ |
940 | 28.8G | ( x >= '0' && x <= '9' ? x - '0' \ |
941 | 28.8G | : x >= 'a' && x <= 'f' ? x - 'a' + 0xa \ |
942 | 28.8G | : x >= 'A' && x <= 'F' ? x - 'A' + 0xa \ |
943 | 28.8G | : -1) |
944 | 7.20G | #define TBL0(x) TBL(x), TBL((x) + 1), TBL((x) + 2), TBL((x) + 3) |
945 | 1.80G | #define TBL1(x) TBL0(x), TBL0((x) + 4), TBL0((x) + 8), TBL0((x) + 12) |
946 | 450M | #define TBL2(x) TBL1(x), TBL1((x) + 16), TBL1((x) + 32), TBL1((x) + 48) |
947 | 112M | TBL2(0), TBL2(64), TBL2(128), TBL2(192) |
948 | 112M | }; |
949 | | |
950 | 112M | return tbl[c]; |
951 | 112M | } |
952 | | |
953 | | /* Returns the integer value of the 'n' hexadecimal digits starting at 's', or |
954 | | * UINTMAX_MAX if one of those "digits" is not really a hex digit. Sets '*ok' |
955 | | * to true if the conversion succeeds or to false if a non-hex digit is |
956 | | * detected. */ |
957 | | uintmax_t |
958 | | hexits_value(const char *s, size_t n, bool *ok) |
959 | 2.97M | { |
960 | 2.97M | uintmax_t value; |
961 | 2.97M | size_t i; |
962 | | |
963 | 2.97M | value = 0; |
964 | 8.66M | for (i = 0; i < n; i++) { |
965 | 5.71M | int hexit = hexit_value(s[i]); |
966 | 5.71M | if (hexit < 0) { |
967 | 21.4k | *ok = false; |
968 | 21.4k | return UINTMAX_MAX; |
969 | 21.4k | } |
970 | 5.69M | value = (value << 4) + hexit; |
971 | 5.69M | } |
972 | 2.95M | *ok = true; |
973 | 2.95M | return value; |
974 | 2.97M | } |
975 | | |
976 | | /* Parses the string in 's' as an integer in either hex or decimal format and |
977 | | * puts the result right justified in the array 'valuep' that is 'field_width' |
978 | | * big. If the string is in hex format, the value may be arbitrarily large; |
979 | | * integers are limited to 64-bit values. (The rationale is that decimal is |
980 | | * likely to represent a number and 64 bits is a reasonable maximum whereas |
981 | | * hex could either be a number or a byte string.) |
982 | | * |
983 | | * On return 'tail' points to the first character in the string that was |
984 | | * not parsed as part of the value. ERANGE is returned if the value is too |
985 | | * large to fit in the given field. */ |
986 | | int |
987 | | parse_int_string(const char *s, uint8_t *valuep, int field_width, char **tail) |
988 | 282k | { |
989 | 282k | unsigned long long int integer; |
990 | 282k | int i; |
991 | | |
992 | 282k | if (!strncmp(s, "0x", 2) || !strncmp(s, "0X", 2)) { |
993 | 14.5k | uint8_t *hexit_str; |
994 | 14.5k | int len = 0; |
995 | 14.5k | int val_idx; |
996 | 14.5k | int err = 0; |
997 | | |
998 | 14.5k | s += 2; |
999 | 14.5k | hexit_str = xmalloc(field_width * 2); |
1000 | | |
1001 | 329k | for (;;) { |
1002 | 329k | uint8_t hexit; |
1003 | 329k | bool ok; |
1004 | | |
1005 | 329k | s += strspn(s, " \t\r\n"); |
1006 | 329k | hexit = hexits_value(s, 1, &ok); |
1007 | 329k | if (!ok) { |
1008 | 14.5k | *tail = CONST_CAST(char *, s); |
1009 | 14.5k | break; |
1010 | 14.5k | } |
1011 | | |
1012 | 315k | if (hexit != 0 || len) { |
1013 | 133k | if (DIV_ROUND_UP(len + 1, 2) > field_width) { |
1014 | 8 | err = ERANGE; |
1015 | 8 | goto free; |
1016 | 8 | } |
1017 | | |
1018 | 133k | hexit_str[len] = hexit; |
1019 | 133k | len++; |
1020 | 133k | } |
1021 | 315k | s++; |
1022 | 315k | } |
1023 | | |
1024 | 14.5k | val_idx = field_width; |
1025 | 84.2k | for (i = len - 1; i >= 0; i -= 2) { |
1026 | 69.6k | val_idx--; |
1027 | 69.6k | valuep[val_idx] = hexit_str[i]; |
1028 | 69.6k | if (i > 0) { |
1029 | 64.1k | valuep[val_idx] += hexit_str[i - 1] << 4; |
1030 | 64.1k | } |
1031 | 69.6k | } |
1032 | | |
1033 | 14.5k | memset(valuep, 0, val_idx); |
1034 | | |
1035 | 14.5k | free: |
1036 | 14.5k | free(hexit_str); |
1037 | 14.5k | return err; |
1038 | 14.5k | } |
1039 | | |
1040 | 282k | errno = 0; |
1041 | 267k | integer = strtoull(s, tail, 0); |
1042 | 267k | if (errno || s == *tail) { |
1043 | 589 | return errno ? errno : EINVAL; |
1044 | 589 | } |
1045 | | |
1046 | 7.13M | for (i = field_width - 1; i >= 0; i--) { |
1047 | 6.86M | valuep[i] = integer; |
1048 | 6.86M | integer >>= 8; |
1049 | 6.86M | } |
1050 | 267k | if (integer) { |
1051 | 190 | return ERANGE; |
1052 | 190 | } |
1053 | | |
1054 | 267k | return 0; |
1055 | 267k | } |
1056 | | |
1057 | | /* Returns the current working directory as a malloc()'d string, or a null |
1058 | | * pointer if the current working directory cannot be determined. */ |
1059 | | char * |
1060 | | get_cwd(void) |
1061 | 0 | { |
1062 | 0 | long int path_max; |
1063 | 0 | size_t size; |
1064 | | |
1065 | | /* Get maximum path length or at least a reasonable estimate. */ |
1066 | 0 | path_max = pathconf(".", _PC_PATH_MAX); |
1067 | 0 | size = (path_max < 0 ? 1024 |
1068 | 0 | : path_max > 10240 ? 10240 |
1069 | 0 | : path_max); |
1070 | | |
1071 | | /* Get current working directory. */ |
1072 | 0 | for (;;) { |
1073 | 0 | char *buf = xmalloc(size); |
1074 | 0 | if (getcwd(buf, size)) { |
1075 | 0 | return xrealloc(buf, strlen(buf) + 1); |
1076 | 0 | } else { |
1077 | 0 | int error = errno; |
1078 | 0 | free(buf); |
1079 | 0 | if (error != ERANGE) { |
1080 | 0 | VLOG_WARN("getcwd failed (%s)", ovs_strerror(error)); |
1081 | 0 | return NULL; |
1082 | 0 | } |
1083 | 0 | size *= 2; |
1084 | 0 | } |
1085 | 0 | } |
1086 | 0 | } |
1087 | | |
1088 | | static char * |
1089 | | all_slashes_name(const char *s) |
1090 | 0 | { |
1091 | 0 | return xstrdup(s[0] == '/' && s[1] == '/' && s[2] != '/' ? "//" |
1092 | 0 | : s[0] == '/' ? "/" |
1093 | 0 | : "."); |
1094 | 0 | } |
1095 | | |
1096 | | /* Returns the directory name portion of 'file_name' as a malloc()'d string, |
1097 | | * similar to the POSIX dirname() function but thread-safe. */ |
1098 | | char * |
1099 | | dir_name(const char *file_name) |
1100 | 0 | { |
1101 | 0 | size_t len = strlen(file_name); |
1102 | 0 | while (len > 0 && file_name[len - 1] == '/') { |
1103 | 0 | len--; |
1104 | 0 | } |
1105 | 0 | while (len > 0 && file_name[len - 1] != '/') { |
1106 | 0 | len--; |
1107 | 0 | } |
1108 | 0 | while (len > 0 && file_name[len - 1] == '/') { |
1109 | 0 | len--; |
1110 | 0 | } |
1111 | 0 | return len ? xmemdup0(file_name, len) : all_slashes_name(file_name); |
1112 | 0 | } |
1113 | | |
1114 | | /* Returns the file name portion of 'file_name' as a malloc()'d string, |
1115 | | * similar to the POSIX basename() function but thread-safe. */ |
1116 | | char * |
1117 | | base_name(const char *file_name) |
1118 | 0 | { |
1119 | 0 | size_t end, start; |
1120 | |
|
1121 | 0 | end = strlen(file_name); |
1122 | 0 | while (end > 0 && file_name[end - 1] == '/') { |
1123 | 0 | end--; |
1124 | 0 | } |
1125 | |
|
1126 | 0 | if (!end) { |
1127 | 0 | return all_slashes_name(file_name); |
1128 | 0 | } |
1129 | | |
1130 | 0 | start = end; |
1131 | 0 | while (start > 0 && file_name[start - 1] != '/') { |
1132 | 0 | start--; |
1133 | 0 | } |
1134 | |
|
1135 | 0 | return xmemdup0(file_name + start, end - start); |
1136 | 0 | } |
1137 | | |
1138 | | bool |
1139 | | is_file_name_absolute(const char *fn) |
1140 | 0 | { |
1141 | | /* An absolute path begins with /. */ |
1142 | 0 | return fn[0] == '/'; |
1143 | 0 | } |
1144 | | |
1145 | | /* If 'file_name' is absolute, returns a copy of 'file_name'. Otherwise, |
1146 | | * returns an absolute path to 'file_name' considering it relative to 'dir', |
1147 | | * which itself must be absolute. 'dir' may be null or the empty string, in |
1148 | | * which case the current working directory is used. |
1149 | | * |
1150 | | * Returns a null pointer if 'dir' is null and getcwd() fails. */ |
1151 | | char * |
1152 | | abs_file_name(const char *dir, const char *file_name) |
1153 | 0 | { |
1154 | | /* If it's already absolute, return a copy. */ |
1155 | 0 | if (is_file_name_absolute(file_name)) { |
1156 | 0 | return xstrdup(file_name); |
1157 | 0 | } |
1158 | | |
1159 | | /* If a base dir was supplied, use it. We assume, without checking, that |
1160 | | * the base dir is absolute.*/ |
1161 | 0 | if (dir && dir[0]) { |
1162 | 0 | char *separator = dir[strlen(dir) - 1] == '/' ? "" : "/"; |
1163 | 0 | return xasprintf("%s%s%s", dir, separator, file_name); |
1164 | 0 | } |
1165 | | |
1166 | 0 | char *cwd = get_cwd(); |
1167 | 0 | if (!cwd) { |
1168 | 0 | return NULL; |
1169 | 0 | } |
1170 | 0 | char *abs_name = xasprintf("%s/%s", cwd, file_name); |
1171 | 0 | free(cwd); |
1172 | 0 | return abs_name; |
1173 | 0 | } |
1174 | | |
1175 | | /* Like readlink(), but returns the link name as a null-terminated string in |
1176 | | * allocated memory that the caller must eventually free (with free()). |
1177 | | * Returns NULL on error, in which case errno is set appropriately. */ |
1178 | | static char * |
1179 | | xreadlink(const char *filename) |
1180 | 0 | { |
1181 | 0 | size_t size; |
1182 | |
|
1183 | 0 | for (size = 64; ; size *= 2) { |
1184 | 0 | char *buf = xmalloc(size); |
1185 | 0 | ssize_t retval = readlink(filename, buf, size); |
1186 | 0 | int error = errno; |
1187 | |
|
1188 | 0 | if (retval >= 0 && retval < size) { |
1189 | 0 | buf[retval] = '\0'; |
1190 | 0 | return buf; |
1191 | 0 | } |
1192 | | |
1193 | 0 | free(buf); |
1194 | 0 | if (retval < 0) { |
1195 | 0 | errno = error; |
1196 | 0 | return NULL; |
1197 | 0 | } |
1198 | 0 | } |
1199 | 0 | } |
1200 | | |
1201 | | /* Returns a version of 'filename' with symlinks in the final component |
1202 | | * dereferenced. This differs from realpath() in that: |
1203 | | * |
1204 | | * - 'filename' need not exist. |
1205 | | * |
1206 | | * - If 'filename' does exist as a symlink, its referent need not exist. |
1207 | | * |
1208 | | * - Only symlinks in the final component of 'filename' are dereferenced. |
1209 | | * |
1210 | | * The caller must eventually free the returned string (with free()). */ |
1211 | | char * |
1212 | | follow_symlinks(const char *filename) |
1213 | 0 | { |
1214 | 0 | struct stat s; |
1215 | 0 | char *fn; |
1216 | 0 | int i; |
1217 | |
|
1218 | 0 | fn = xstrdup(filename); |
1219 | 0 | for (i = 0; i < 10; i++) { |
1220 | 0 | char *linkname; |
1221 | 0 | char *next_fn; |
1222 | |
|
1223 | 0 | if (lstat(fn, &s) != 0 || !S_ISLNK(s.st_mode)) { |
1224 | 0 | return fn; |
1225 | 0 | } |
1226 | | |
1227 | 0 | linkname = xreadlink(fn); |
1228 | 0 | if (!linkname) { |
1229 | 0 | VLOG_WARN("%s: readlink failed (%s)", |
1230 | 0 | filename, ovs_strerror(errno)); |
1231 | 0 | return fn; |
1232 | 0 | } |
1233 | | |
1234 | 0 | if (linkname[0] == '/') { |
1235 | | /* Target of symlink is absolute so use it raw. */ |
1236 | 0 | next_fn = linkname; |
1237 | 0 | } else { |
1238 | | /* Target of symlink is relative so add to 'fn''s directory. */ |
1239 | 0 | char *dir = dir_name(fn); |
1240 | |
|
1241 | 0 | if (!strcmp(dir, ".")) { |
1242 | 0 | next_fn = linkname; |
1243 | 0 | } else { |
1244 | 0 | char *separator = dir[strlen(dir) - 1] == '/' ? "" : "/"; |
1245 | 0 | next_fn = xasprintf("%s%s%s", dir, separator, linkname); |
1246 | 0 | free(linkname); |
1247 | 0 | } |
1248 | |
|
1249 | 0 | free(dir); |
1250 | 0 | } |
1251 | |
|
1252 | 0 | free(fn); |
1253 | 0 | fn = next_fn; |
1254 | 0 | } |
1255 | | |
1256 | 0 | VLOG_WARN("%s: too many levels of symlinks", filename); |
1257 | 0 | free(fn); |
1258 | 0 | return xstrdup(filename); |
1259 | 0 | } |
1260 | | |
1261 | | /* Pass a value to this function if it is marked with |
1262 | | * __attribute__((warn_unused_result)) and you genuinely want to ignore |
1263 | | * its return value. (Note that every scalar type can be implicitly |
1264 | | * converted to bool.) */ |
1265 | 100M | void ovs_ignore(bool x OVS_UNUSED) { } |
1266 | | |
1267 | | /* Returns an appropriate delimiter for inserting just before the 0-based item |
1268 | | * 'index' in a list that has 'total' items in it. */ |
1269 | | const char * |
1270 | | english_list_delimiter(size_t index, size_t total) |
1271 | 0 | { |
1272 | 0 | return (index == 0 ? "" |
1273 | 0 | : index < total - 1 ? ", " |
1274 | 0 | : total > 2 ? ", and " |
1275 | 0 | : " and "); |
1276 | 0 | } |
1277 | | |
1278 | | /* Returns the number of trailing 0-bits in 'n'. Undefined if 'n' == 0. */ |
1279 | | #if __GNUC__ >= 4 |
1280 | | /* Defined inline in util.h. */ |
1281 | | #else |
1282 | | /* Returns the number of trailing 0-bits in 'n'. Undefined if 'n' == 0. */ |
1283 | | int |
1284 | | raw_ctz(uint64_t n) |
1285 | | { |
1286 | | uint64_t k; |
1287 | | int count = 63; |
1288 | | |
1289 | | #define CTZ_STEP(X) \ |
1290 | | k = n << (X); \ |
1291 | | if (k) { \ |
1292 | | count -= X; \ |
1293 | | n = k; \ |
1294 | | } |
1295 | | CTZ_STEP(32); |
1296 | | CTZ_STEP(16); |
1297 | | CTZ_STEP(8); |
1298 | | CTZ_STEP(4); |
1299 | | CTZ_STEP(2); |
1300 | | CTZ_STEP(1); |
1301 | | #undef CTZ_STEP |
1302 | | |
1303 | | return count; |
1304 | | } |
1305 | | |
1306 | | /* Returns the number of leading 0-bits in 'n'. Undefined if 'n' == 0. */ |
1307 | | int |
1308 | | raw_clz64(uint64_t n) |
1309 | | { |
1310 | | uint64_t k; |
1311 | | int count = 63; |
1312 | | |
1313 | | #define CLZ_STEP(X) \ |
1314 | | k = n >> (X); \ |
1315 | | if (k) { \ |
1316 | | count -= X; \ |
1317 | | n = k; \ |
1318 | | } |
1319 | | CLZ_STEP(32); |
1320 | | CLZ_STEP(16); |
1321 | | CLZ_STEP(8); |
1322 | | CLZ_STEP(4); |
1323 | | CLZ_STEP(2); |
1324 | | CLZ_STEP(1); |
1325 | | #undef CLZ_STEP |
1326 | | |
1327 | | return count; |
1328 | | } |
1329 | | #endif |
1330 | | |
1331 | | #if NEED_COUNT_1BITS_8 |
1332 | | #define INIT1(X) \ |
1333 | | ((((X) & (1 << 0)) != 0) + \ |
1334 | | (((X) & (1 << 1)) != 0) + \ |
1335 | | (((X) & (1 << 2)) != 0) + \ |
1336 | | (((X) & (1 << 3)) != 0) + \ |
1337 | | (((X) & (1 << 4)) != 0) + \ |
1338 | | (((X) & (1 << 5)) != 0) + \ |
1339 | | (((X) & (1 << 6)) != 0) + \ |
1340 | | (((X) & (1 << 7)) != 0)) |
1341 | | #define INIT2(X) INIT1(X), INIT1((X) + 1) |
1342 | | #define INIT4(X) INIT2(X), INIT2((X) + 2) |
1343 | | #define INIT8(X) INIT4(X), INIT4((X) + 4) |
1344 | | #define INIT16(X) INIT8(X), INIT8((X) + 8) |
1345 | | #define INIT32(X) INIT16(X), INIT16((X) + 16) |
1346 | | #define INIT64(X) INIT32(X), INIT32((X) + 32) |
1347 | | |
1348 | | const uint8_t count_1bits_8[256] = { |
1349 | | INIT64(0), INIT64(64), INIT64(128), INIT64(192) |
1350 | | }; |
1351 | | #endif |
1352 | | |
1353 | | /* Returns true if the 'n' bytes starting at 'p' are 'byte'. */ |
1354 | | bool |
1355 | | is_all_byte(const void *p_, size_t n, uint8_t byte) |
1356 | 1.30M | { |
1357 | 1.30M | const uint8_t *p = p_; |
1358 | 1.30M | size_t i; |
1359 | | |
1360 | 22.7M | for (i = 0; i < n; i++) { |
1361 | 22.0M | if (p[i] != byte) { |
1362 | 590k | return false; |
1363 | 590k | } |
1364 | 22.0M | } |
1365 | 717k | return true; |
1366 | 1.30M | } |
1367 | | |
1368 | | /* Returns true if the 'n' bytes starting at 'p' are zeros. */ |
1369 | | bool |
1370 | | is_all_zeros(const void *p, size_t n) |
1371 | 644k | { |
1372 | 644k | return is_all_byte(p, n, 0); |
1373 | 644k | } |
1374 | | |
1375 | | /* Returns true if the 'n' bytes starting at 'p' are 0xff. */ |
1376 | | bool |
1377 | | is_all_ones(const void *p, size_t n) |
1378 | 560k | { |
1379 | 560k | return is_all_byte(p, n, 0xff); |
1380 | 560k | } |
1381 | | |
1382 | | /* *dst |= *src for 'n' bytes. */ |
1383 | | void |
1384 | | or_bytes(void *dst_, const void *src_, size_t n) |
1385 | 0 | { |
1386 | 0 | const uint8_t *src = src_; |
1387 | 0 | uint8_t *dst = dst_; |
1388 | 0 | size_t i; |
1389 | |
|
1390 | 0 | for (i = 0; i < n; i++) { |
1391 | 0 | *dst++ |= *src++; |
1392 | 0 | } |
1393 | 0 | } |
1394 | | |
1395 | | /* Copies 'n_bits' bits starting from bit 'src_ofs' in 'src' to the 'n_bits' |
1396 | | * starting from bit 'dst_ofs' in 'dst'. 'src' is 'src_len' bytes long and |
1397 | | * 'dst' is 'dst_len' bytes long. |
1398 | | * |
1399 | | * If you consider all of 'src' to be a single unsigned integer in network byte |
1400 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1401 | | * with value 1 in src[src_len - 1], bit 1 is the bit with value 2, bit 2 is |
1402 | | * the bit with value 4, ..., bit 8 is the bit with value 1 in src[src_len - |
1403 | | * 2], and so on. Similarly for 'dst'. |
1404 | | * |
1405 | | * Required invariants: |
1406 | | * src_ofs + n_bits <= src_len * 8 |
1407 | | * dst_ofs + n_bits <= dst_len * 8 |
1408 | | * 'src' and 'dst' must not overlap. |
1409 | | */ |
1410 | | void |
1411 | | bitwise_copy(const void *src_, unsigned int src_len, unsigned int src_ofs, |
1412 | | void *dst_, unsigned int dst_len, unsigned int dst_ofs, |
1413 | | unsigned int n_bits) |
1414 | 211k | { |
1415 | 211k | const uint8_t *src = src_; |
1416 | 211k | uint8_t *dst = dst_; |
1417 | | |
1418 | 211k | src += src_len - (src_ofs / 8 + 1); |
1419 | 211k | src_ofs %= 8; |
1420 | | |
1421 | 211k | dst += dst_len - (dst_ofs / 8 + 1); |
1422 | 211k | dst_ofs %= 8; |
1423 | | |
1424 | 211k | if (src_ofs == 0 && dst_ofs == 0) { |
1425 | 93.2k | unsigned int n_bytes = n_bits / 8; |
1426 | 93.2k | if (n_bytes) { |
1427 | 56.0k | dst -= n_bytes - 1; |
1428 | 56.0k | src -= n_bytes - 1; |
1429 | 56.0k | memcpy(dst, src, n_bytes); |
1430 | | |
1431 | 56.0k | n_bits %= 8; |
1432 | 56.0k | src--; |
1433 | 56.0k | dst--; |
1434 | 56.0k | } |
1435 | 93.2k | if (n_bits) { |
1436 | 44.7k | uint8_t mask = (1 << n_bits) - 1; |
1437 | 44.7k | *dst = (*dst & ~mask) | (*src & mask); |
1438 | 44.7k | } |
1439 | 118k | } else { |
1440 | 317k | while (n_bits > 0) { |
1441 | 198k | unsigned int max_copy = 8 - MAX(src_ofs, dst_ofs); |
1442 | 198k | unsigned int chunk = MIN(n_bits, max_copy); |
1443 | 198k | uint8_t mask = ((1 << chunk) - 1) << dst_ofs; |
1444 | | |
1445 | 198k | *dst &= ~mask; |
1446 | 198k | *dst |= ((*src >> src_ofs) << dst_ofs) & mask; |
1447 | | |
1448 | 198k | src_ofs += chunk; |
1449 | 198k | if (src_ofs == 8) { |
1450 | 43.7k | src--; |
1451 | 43.7k | src_ofs = 0; |
1452 | 43.7k | } |
1453 | 198k | dst_ofs += chunk; |
1454 | 198k | if (dst_ofs == 8) { |
1455 | 48.9k | dst--; |
1456 | 48.9k | dst_ofs = 0; |
1457 | 48.9k | } |
1458 | 198k | n_bits -= chunk; |
1459 | 198k | } |
1460 | 118k | } |
1461 | 211k | } |
1462 | | |
1463 | | /* Zeros the 'n_bits' bits starting from bit 'dst_ofs' in 'dst'. 'dst' is |
1464 | | * 'dst_len' bytes long. |
1465 | | * |
1466 | | * If you consider all of 'dst' to be a single unsigned integer in network byte |
1467 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1468 | | * with value 1 in dst[dst_len - 1], bit 1 is the bit with value 2, bit 2 is |
1469 | | * the bit with value 4, ..., bit 8 is the bit with value 1 in dst[dst_len - |
1470 | | * 2], and so on. |
1471 | | * |
1472 | | * Required invariant: |
1473 | | * dst_ofs + n_bits <= dst_len * 8 |
1474 | | */ |
1475 | | void |
1476 | | bitwise_zero(void *dst_, unsigned int dst_len, unsigned dst_ofs, |
1477 | | unsigned int n_bits) |
1478 | 0 | { |
1479 | 0 | uint8_t *dst = dst_; |
1480 | |
|
1481 | 0 | if (!n_bits) { |
1482 | 0 | return; |
1483 | 0 | } |
1484 | | |
1485 | 0 | dst += dst_len - (dst_ofs / 8 + 1); |
1486 | 0 | dst_ofs %= 8; |
1487 | |
|
1488 | 0 | if (dst_ofs) { |
1489 | 0 | unsigned int chunk = MIN(n_bits, 8 - dst_ofs); |
1490 | |
|
1491 | 0 | *dst &= ~(((1 << chunk) - 1) << dst_ofs); |
1492 | |
|
1493 | 0 | n_bits -= chunk; |
1494 | 0 | if (!n_bits) { |
1495 | 0 | return; |
1496 | 0 | } |
1497 | | |
1498 | 0 | dst--; |
1499 | 0 | } |
1500 | | |
1501 | 0 | while (n_bits >= 8) { |
1502 | 0 | *dst-- = 0; |
1503 | 0 | n_bits -= 8; |
1504 | 0 | } |
1505 | |
|
1506 | 0 | if (n_bits) { |
1507 | 0 | *dst &= ~((1 << n_bits) - 1); |
1508 | 0 | } |
1509 | 0 | } |
1510 | | |
1511 | | /* Sets to 1 all of the 'n_bits' bits starting from bit 'dst_ofs' in 'dst'. |
1512 | | * 'dst' is 'dst_len' bytes long. |
1513 | | * |
1514 | | * If you consider all of 'dst' to be a single unsigned integer in network byte |
1515 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1516 | | * with value 1 in dst[dst_len - 1], bit 1 is the bit with value 2, bit 2 is |
1517 | | * the bit with value 4, ..., bit 8 is the bit with value 1 in dst[dst_len - |
1518 | | * 2], and so on. |
1519 | | * |
1520 | | * Required invariant: |
1521 | | * dst_ofs + n_bits <= dst_len * 8 |
1522 | | */ |
1523 | | void |
1524 | | bitwise_one(void *dst_, unsigned int dst_len, unsigned dst_ofs, |
1525 | | unsigned int n_bits) |
1526 | 141k | { |
1527 | 141k | uint8_t *dst = dst_; |
1528 | | |
1529 | 141k | if (!n_bits) { |
1530 | 0 | return; |
1531 | 0 | } |
1532 | | |
1533 | 141k | dst += dst_len - (dst_ofs / 8 + 1); |
1534 | 141k | dst_ofs %= 8; |
1535 | | |
1536 | 141k | if (dst_ofs) { |
1537 | 63.8k | unsigned int chunk = MIN(n_bits, 8 - dst_ofs); |
1538 | | |
1539 | 63.8k | *dst |= ((1 << chunk) - 1) << dst_ofs; |
1540 | | |
1541 | 63.8k | n_bits -= chunk; |
1542 | 63.8k | if (!n_bits) { |
1543 | 49.8k | return; |
1544 | 49.8k | } |
1545 | | |
1546 | 13.9k | dst--; |
1547 | 13.9k | } |
1548 | | |
1549 | 2.71M | while (n_bits >= 8) { |
1550 | 2.62M | *dst-- = 0xff; |
1551 | 2.62M | n_bits -= 8; |
1552 | 2.62M | } |
1553 | | |
1554 | 91.8k | if (n_bits) { |
1555 | 45.9k | *dst |= (1 << n_bits) - 1; |
1556 | 45.9k | } |
1557 | 91.8k | } |
1558 | | |
1559 | | /* Scans the 'n_bits' bits starting from bit 'dst_ofs' in 'dst' for 1-bits. |
1560 | | * Returns false if any 1-bits are found, otherwise true. 'dst' is 'dst_len' |
1561 | | * bytes long. |
1562 | | * |
1563 | | * If you consider all of 'dst' to be a single unsigned integer in network byte |
1564 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1565 | | * with value 1 in dst[dst_len - 1], bit 1 is the bit with value 2, bit 2 is |
1566 | | * the bit with value 4, ..., bit 8 is the bit with value 1 in dst[dst_len - |
1567 | | * 2], and so on. |
1568 | | * |
1569 | | * Required invariant: |
1570 | | * dst_ofs + n_bits <= dst_len * 8 |
1571 | | */ |
1572 | | bool |
1573 | | bitwise_is_all_zeros(const void *p_, unsigned int len, unsigned int ofs, |
1574 | | unsigned int n_bits) |
1575 | 84.5k | { |
1576 | 84.5k | const uint8_t *p = p_; |
1577 | | |
1578 | 84.5k | if (!n_bits) { |
1579 | 11.1k | return true; |
1580 | 11.1k | } |
1581 | | |
1582 | 73.4k | p += len - (ofs / 8 + 1); |
1583 | 73.4k | ofs %= 8; |
1584 | | |
1585 | 73.4k | if (ofs) { |
1586 | 72.4k | unsigned int chunk = MIN(n_bits, 8 - ofs); |
1587 | | |
1588 | 72.4k | if (*p & (((1 << chunk) - 1) << ofs)) { |
1589 | 109 | return false; |
1590 | 109 | } |
1591 | | |
1592 | 72.3k | n_bits -= chunk; |
1593 | 72.3k | if (!n_bits) { |
1594 | 9.31k | return true; |
1595 | 9.31k | } |
1596 | | |
1597 | 63.0k | p--; |
1598 | 63.0k | } |
1599 | | |
1600 | 2.35M | while (n_bits >= 8) { |
1601 | 2.28M | if (*p) { |
1602 | 19 | return false; |
1603 | 19 | } |
1604 | 2.28M | n_bits -= 8; |
1605 | 2.28M | p--; |
1606 | 2.28M | } |
1607 | | |
1608 | 63.9k | if (n_bits && *p & ((1 << n_bits) - 1)) { |
1609 | 0 | return false; |
1610 | 0 | } |
1611 | | |
1612 | 63.9k | return true; |
1613 | 63.9k | } |
1614 | | |
1615 | | /* Scans the bits in 'p' that have bit offsets 'start' (inclusive) through |
1616 | | * 'end' (exclusive) for the first bit with value 'target'. If one is found, |
1617 | | * returns its offset, otherwise 'end'. 'p' is 'len' bytes long. |
1618 | | * |
1619 | | * If you consider all of 'p' to be a single unsigned integer in network byte |
1620 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1621 | | * with value 1 in p[len - 1], bit 1 is the bit with value 2, bit 2 is the bit |
1622 | | * with value 4, ..., bit 8 is the bit with value 1 in p[len - 2], and so on. |
1623 | | * |
1624 | | * Required invariant: |
1625 | | * start <= end |
1626 | | */ |
1627 | | unsigned int |
1628 | | bitwise_scan(const void *p, unsigned int len, bool target, unsigned int start, |
1629 | | unsigned int end) |
1630 | 138k | { |
1631 | 138k | unsigned int ofs; |
1632 | | |
1633 | 1.73M | for (ofs = start; ofs < end; ofs++) { |
1634 | 1.72M | if (bitwise_get_bit(p, len, ofs) == target) { |
1635 | 126k | break; |
1636 | 126k | } |
1637 | 1.72M | } |
1638 | 138k | return ofs; |
1639 | 138k | } |
1640 | | |
1641 | | /* Scans the bits in 'p' that have bit offsets 'start' (inclusive) through |
1642 | | * 'end' (exclusive) for the first bit with value 'target', in reverse order. |
1643 | | * If one is found, returns its offset, otherwise 'end'. 'p' is 'len' bytes |
1644 | | * long. |
1645 | | * |
1646 | | * If you consider all of 'p' to be a single unsigned integer in network byte |
1647 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1648 | | * with value 1 in p[len - 1], bit 1 is the bit with value 2, bit 2 is the bit |
1649 | | * with value 4, ..., bit 8 is the bit with value 1 in p[len - 2], and so on. |
1650 | | * |
1651 | | * To scan an entire bit array in reverse order, specify start == len * 8 - 1 |
1652 | | * and end == -1, in which case the return value is nonnegative if successful |
1653 | | * and -1 if no 'target' match is found. |
1654 | | * |
1655 | | * Required invariant: |
1656 | | * start >= end |
1657 | | */ |
1658 | | int |
1659 | | bitwise_rscan(const void *p, unsigned int len, bool target, int start, int end) |
1660 | 0 | { |
1661 | 0 | const uint8_t *s = p; |
1662 | 0 | int start_byte = len - (start / 8 + 1); |
1663 | 0 | int end_byte = len - (end / 8 + 1); |
1664 | 0 | int ofs_byte; |
1665 | 0 | int ofs; |
1666 | 0 | uint8_t the_byte; |
1667 | | |
1668 | | /* Find the target in the start_byte from starting offset */ |
1669 | 0 | ofs_byte = start_byte; |
1670 | 0 | the_byte = s[ofs_byte]; |
1671 | 0 | for (ofs = start % 8; ofs >= 0; ofs--) { |
1672 | 0 | if (((the_byte & (1u << ofs)) != 0) == target) { |
1673 | 0 | break; |
1674 | 0 | } |
1675 | 0 | } |
1676 | 0 | if (ofs < 0) { |
1677 | | /* Target not found in start byte, continue searching byte by byte */ |
1678 | 0 | for (ofs_byte = start_byte + 1; ofs_byte <= end_byte; ofs_byte++) { |
1679 | 0 | if ((target && s[ofs_byte]) |
1680 | 0 | || (!target && (s[ofs_byte] != 0xff))) { |
1681 | 0 | break; |
1682 | 0 | } |
1683 | 0 | } |
1684 | 0 | if (ofs_byte > end_byte) { |
1685 | 0 | return end; |
1686 | 0 | } |
1687 | 0 | the_byte = s[ofs_byte]; |
1688 | | /* Target is in the_byte, find it bit by bit */ |
1689 | 0 | for (ofs = 7; ofs >= 0; ofs--) { |
1690 | 0 | if (((the_byte & (1u << ofs)) != 0) == target) { |
1691 | 0 | break; |
1692 | 0 | } |
1693 | 0 | } |
1694 | 0 | } |
1695 | 0 | int ret = (len - ofs_byte) * 8 - (8 - ofs); |
1696 | 0 | if (ret < end) { |
1697 | 0 | return end; |
1698 | 0 | } |
1699 | 0 | return ret; |
1700 | 0 | } |
1701 | | |
1702 | | /* Copies the 'n_bits' low-order bits of 'value' into the 'n_bits' bits |
1703 | | * starting at bit 'dst_ofs' in 'dst', which is 'dst_len' bytes long. |
1704 | | * |
1705 | | * If you consider all of 'dst' to be a single unsigned integer in network byte |
1706 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1707 | | * with value 1 in dst[dst_len - 1], bit 1 is the bit with value 2, bit 2 is |
1708 | | * the bit with value 4, ..., bit 8 is the bit with value 1 in dst[dst_len - |
1709 | | * 2], and so on. |
1710 | | * |
1711 | | * Required invariants: |
1712 | | * dst_ofs + n_bits <= dst_len * 8 |
1713 | | * n_bits <= 64 |
1714 | | */ |
1715 | | void |
1716 | | bitwise_put(uint64_t value, |
1717 | | void *dst, unsigned int dst_len, unsigned int dst_ofs, |
1718 | | unsigned int n_bits) |
1719 | 4.27k | { |
1720 | 4.27k | ovs_be64 n_value = htonll(value); |
1721 | 4.27k | bitwise_copy(&n_value, sizeof n_value, 0, |
1722 | 4.27k | dst, dst_len, dst_ofs, |
1723 | 4.27k | n_bits); |
1724 | 4.27k | } |
1725 | | |
1726 | | /* Returns the value of the 'n_bits' bits starting at bit 'src_ofs' in 'src', |
1727 | | * which is 'src_len' bytes long. |
1728 | | * |
1729 | | * If you consider all of 'src' to be a single unsigned integer in network byte |
1730 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1731 | | * with value 1 in src[src_len - 1], bit 1 is the bit with value 2, bit 2 is |
1732 | | * the bit with value 4, ..., bit 8 is the bit with value 1 in src[src_len - |
1733 | | * 2], and so on. |
1734 | | * |
1735 | | * Required invariants: |
1736 | | * src_ofs + n_bits <= src_len * 8 |
1737 | | * n_bits <= 64 |
1738 | | */ |
1739 | | uint64_t |
1740 | | bitwise_get(const void *src, unsigned int src_len, |
1741 | | unsigned int src_ofs, unsigned int n_bits) |
1742 | 65.6k | { |
1743 | 65.6k | ovs_be64 value = htonll(0); |
1744 | | |
1745 | 65.6k | bitwise_copy(src, src_len, src_ofs, |
1746 | 65.6k | &value, sizeof value, 0, |
1747 | 65.6k | n_bits); |
1748 | 65.6k | return ntohll(value); |
1749 | 65.6k | } |
1750 | | |
1751 | | /* Returns the value of the bit with offset 'ofs' in 'src', which is 'len' |
1752 | | * bytes long. |
1753 | | * |
1754 | | * If you consider all of 'src' to be a single unsigned integer in network byte |
1755 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1756 | | * with value 1 in src[len - 1], bit 1 is the bit with value 2, bit 2 is the |
1757 | | * bit with value 4, ..., bit 8 is the bit with value 1 in src[len - 2], and so |
1758 | | * on. |
1759 | | * |
1760 | | * Required invariants: |
1761 | | * ofs < len * 8 |
1762 | | */ |
1763 | | bool |
1764 | | bitwise_get_bit(const void *src_, unsigned int len, unsigned int ofs) |
1765 | 1.72M | { |
1766 | 1.72M | const uint8_t *src = src_; |
1767 | | |
1768 | 1.72M | return (src[len - (ofs / 8 + 1)] & (1u << (ofs % 8))) != 0; |
1769 | 1.72M | } |
1770 | | |
1771 | | /* Sets the bit with offset 'ofs' in 'dst', which is 'len' bytes long, to 0. |
1772 | | * |
1773 | | * If you consider all of 'dst' to be a single unsigned integer in network byte |
1774 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1775 | | * with value 1 in dst[len - 1], bit 1 is the bit with value 2, bit 2 is the |
1776 | | * bit with value 4, ..., bit 8 is the bit with value 1 in dst[len - 2], and so |
1777 | | * on. |
1778 | | * |
1779 | | * Required invariants: |
1780 | | * ofs < len * 8 |
1781 | | */ |
1782 | | void |
1783 | | bitwise_put0(void *dst_, unsigned int len, unsigned int ofs) |
1784 | 0 | { |
1785 | 0 | uint8_t *dst = dst_; |
1786 | |
|
1787 | 0 | dst[len - (ofs / 8 + 1)] &= ~(1u << (ofs % 8)); |
1788 | 0 | } |
1789 | | |
1790 | | /* Sets the bit with offset 'ofs' in 'dst', which is 'len' bytes long, to 1. |
1791 | | * |
1792 | | * If you consider all of 'dst' to be a single unsigned integer in network byte |
1793 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1794 | | * with value 1 in dst[len - 1], bit 1 is the bit with value 2, bit 2 is the |
1795 | | * bit with value 4, ..., bit 8 is the bit with value 1 in dst[len - 2], and so |
1796 | | * on. |
1797 | | * |
1798 | | * Required invariants: |
1799 | | * ofs < len * 8 |
1800 | | */ |
1801 | | void |
1802 | | bitwise_put1(void *dst_, unsigned int len, unsigned int ofs) |
1803 | 0 | { |
1804 | 0 | uint8_t *dst = dst_; |
1805 | |
|
1806 | 0 | dst[len - (ofs / 8 + 1)] |= 1u << (ofs % 8); |
1807 | 0 | } |
1808 | | |
1809 | | /* Sets the bit with offset 'ofs' in 'dst', which is 'len' bytes long, to 'b'. |
1810 | | * |
1811 | | * If you consider all of 'dst' to be a single unsigned integer in network byte |
1812 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1813 | | * with value 1 in dst[len - 1], bit 1 is the bit with value 2, bit 2 is the |
1814 | | * bit with value 4, ..., bit 8 is the bit with value 1 in dst[len - 2], and so |
1815 | | * on. |
1816 | | * |
1817 | | * Required invariants: |
1818 | | * ofs < len * 8 |
1819 | | */ |
1820 | | void |
1821 | | bitwise_put_bit(void *dst, unsigned int len, unsigned int ofs, bool b) |
1822 | 0 | { |
1823 | 0 | if (b) { |
1824 | 0 | bitwise_put1(dst, len, ofs); |
1825 | 0 | } else { |
1826 | 0 | bitwise_put0(dst, len, ofs); |
1827 | 0 | } |
1828 | 0 | } |
1829 | | |
1830 | | /* Flips the bit with offset 'ofs' in 'dst', which is 'len' bytes long. |
1831 | | * |
1832 | | * If you consider all of 'dst' to be a single unsigned integer in network byte |
1833 | | * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit |
1834 | | * with value 1 in dst[len - 1], bit 1 is the bit with value 2, bit 2 is the |
1835 | | * bit with value 4, ..., bit 8 is the bit with value 1 in dst[len - 2], and so |
1836 | | * on. |
1837 | | * |
1838 | | * Required invariants: |
1839 | | * ofs < len * 8 |
1840 | | */ |
1841 | | void |
1842 | | bitwise_toggle_bit(void *dst_, unsigned int len, unsigned int ofs) |
1843 | 0 | { |
1844 | 0 | uint8_t *dst = dst_; |
1845 | |
|
1846 | 0 | dst[len - (ofs / 8 + 1)] ^= 1u << (ofs % 8); |
1847 | 0 | } |
1848 | | |
1849 | | /* ovs_scan */ |
1850 | | |
1851 | | struct scan_spec { |
1852 | | unsigned int width; |
1853 | | enum { |
1854 | | SCAN_DISCARD, |
1855 | | SCAN_CHAR, |
1856 | | SCAN_SHORT, |
1857 | | SCAN_INT, |
1858 | | SCAN_LONG, |
1859 | | SCAN_LLONG, |
1860 | | SCAN_INTMAX_T, |
1861 | | SCAN_PTRDIFF_T, |
1862 | | SCAN_SIZE_T |
1863 | | } type; |
1864 | | }; |
1865 | | |
1866 | | static const char * |
1867 | | skip_spaces(const char *s) |
1868 | 769k | { |
1869 | 769k | while (isspace((unsigned char) *s)) { |
1870 | 7.19k | s++; |
1871 | 7.19k | } |
1872 | 769k | return s; |
1873 | 769k | } |
1874 | | |
1875 | | static const char * |
1876 | | scan_int(const char *s, const struct scan_spec *spec, int base, va_list *args) |
1877 | 764k | { |
1878 | 764k | const char *start = s; |
1879 | 764k | uintmax_t value; |
1880 | 764k | bool negative; |
1881 | 764k | int n_digits; |
1882 | | |
1883 | 764k | negative = *s == '-'; |
1884 | 764k | s += *s == '-' || *s == '+'; |
1885 | | |
1886 | 764k | if ((!base || base == 16) && *s == '0' && (s[1] == 'x' || s[1] == 'X')) { |
1887 | 4.24k | base = 16; |
1888 | 4.24k | s += 2; |
1889 | 760k | } else if (!base) { |
1890 | 436k | base = *s == '0' ? 8 : 10; |
1891 | 436k | } |
1892 | | |
1893 | 764k | if (s - start >= spec->width) { |
1894 | 0 | return NULL; |
1895 | 0 | } |
1896 | | |
1897 | 764k | value = 0; |
1898 | 764k | n_digits = 0; |
1899 | 106M | while (s - start < spec->width) { |
1900 | 106M | int digit = hexit_value(*s); |
1901 | | |
1902 | 106M | if (digit < 0 || digit >= base) { |
1903 | 764k | break; |
1904 | 764k | } |
1905 | 106M | value = value * base + digit; |
1906 | 106M | n_digits++; |
1907 | 106M | s++; |
1908 | 106M | } |
1909 | 764k | if (!n_digits) { |
1910 | 102k | return NULL; |
1911 | 102k | } |
1912 | | |
1913 | 661k | if (negative) { |
1914 | 22.1k | value = -value; |
1915 | 22.1k | } |
1916 | | |
1917 | 661k | switch (spec->type) { |
1918 | 0 | case SCAN_DISCARD: |
1919 | 0 | break; |
1920 | 266k | case SCAN_CHAR: |
1921 | 266k | *va_arg(*args, char *) = value; |
1922 | 266k | break; |
1923 | 43.3k | case SCAN_SHORT: |
1924 | 43.3k | *va_arg(*args, short int *) = value; |
1925 | 43.3k | break; |
1926 | 279k | case SCAN_INT: |
1927 | 279k | *va_arg(*args, int *) = value; |
1928 | 279k | break; |
1929 | 41.7k | case SCAN_LONG: |
1930 | 41.7k | *va_arg(*args, long int *) = value; |
1931 | 41.7k | break; |
1932 | 30.9k | case SCAN_LLONG: |
1933 | 30.9k | *va_arg(*args, long long int *) = value; |
1934 | 30.9k | break; |
1935 | 0 | case SCAN_INTMAX_T: |
1936 | 0 | *va_arg(*args, intmax_t *) = value; |
1937 | 0 | break; |
1938 | 0 | case SCAN_PTRDIFF_T: |
1939 | 0 | *va_arg(*args, ptrdiff_t *) = value; |
1940 | 0 | break; |
1941 | 0 | case SCAN_SIZE_T: |
1942 | 0 | *va_arg(*args, size_t *) = value; |
1943 | 0 | break; |
1944 | 661k | } |
1945 | 661k | return s; |
1946 | 661k | } |
1947 | | |
1948 | | static const char * |
1949 | | skip_digits(const char *s) |
1950 | 134 | { |
1951 | 271k | while (*s >= '0' && *s <= '9') { |
1952 | 270k | s++; |
1953 | 270k | } |
1954 | 134 | return s; |
1955 | 134 | } |
1956 | | |
1957 | | static const char * |
1958 | | scan_float(const char *s, const struct scan_spec *spec, va_list *args) |
1959 | 83 | { |
1960 | 83 | const char *start = s; |
1961 | 83 | long double value; |
1962 | 83 | char *tail; |
1963 | 83 | char *copy; |
1964 | 83 | bool ok; |
1965 | | |
1966 | 83 | s += *s == '+' || *s == '-'; |
1967 | 83 | s = skip_digits(s); |
1968 | 83 | if (*s == '.') { |
1969 | 19 | s = skip_digits(s + 1); |
1970 | 19 | } |
1971 | 83 | if (*s == 'e' || *s == 'E') { |
1972 | 32 | s++; |
1973 | 32 | s += *s == '+' || *s == '-'; |
1974 | 32 | s = skip_digits(s); |
1975 | 32 | } |
1976 | | |
1977 | 83 | if (s - start > spec->width) { |
1978 | 0 | s = start + spec->width; |
1979 | 0 | } |
1980 | | |
1981 | 83 | copy = xmemdup0(start, s - start); |
1982 | 83 | value = strtold(copy, &tail); |
1983 | 83 | ok = *tail == '\0'; |
1984 | 83 | free(copy); |
1985 | 83 | if (!ok) { |
1986 | 39 | return NULL; |
1987 | 39 | } |
1988 | | |
1989 | 44 | switch (spec->type) { |
1990 | 0 | case SCAN_DISCARD: |
1991 | 0 | break; |
1992 | 0 | case SCAN_INT: |
1993 | 0 | *va_arg(*args, float *) = value; |
1994 | 0 | break; |
1995 | 44 | case SCAN_LONG: |
1996 | 44 | *va_arg(*args, double *) = value; |
1997 | 44 | break; |
1998 | 0 | case SCAN_LLONG: |
1999 | 0 | *va_arg(*args, long double *) = value; |
2000 | 0 | break; |
2001 | | |
2002 | 0 | case SCAN_CHAR: |
2003 | 0 | case SCAN_SHORT: |
2004 | 0 | case SCAN_INTMAX_T: |
2005 | 0 | case SCAN_PTRDIFF_T: |
2006 | 0 | case SCAN_SIZE_T: |
2007 | 0 | OVS_NOT_REACHED(); |
2008 | 44 | } |
2009 | 44 | return s; |
2010 | 44 | } |
2011 | | |
2012 | | static void |
2013 | | scan_output_string(const struct scan_spec *spec, |
2014 | | const char *s, size_t n, |
2015 | | va_list *args) |
2016 | 106k | { |
2017 | 106k | if (spec->type != SCAN_DISCARD) { |
2018 | 106k | char *out = va_arg(*args, char *); |
2019 | 106k | memcpy(out, s, n); |
2020 | 106k | out[n] = '\0'; |
2021 | 106k | } |
2022 | 106k | } |
2023 | | |
2024 | | static const char * |
2025 | | scan_string(const char *s, const struct scan_spec *spec, va_list *args) |
2026 | 0 | { |
2027 | 0 | size_t n; |
2028 | |
|
2029 | 0 | for (n = 0; n < spec->width; n++) { |
2030 | 0 | if (!s[n] || isspace((unsigned char) s[n])) { |
2031 | 0 | break; |
2032 | 0 | } |
2033 | 0 | } |
2034 | 0 | if (!n) { |
2035 | 0 | return NULL; |
2036 | 0 | } |
2037 | | |
2038 | 0 | scan_output_string(spec, s, n, args); |
2039 | 0 | return s + n; |
2040 | 0 | } |
2041 | | |
2042 | | static const char * |
2043 | | parse_scanset(const char *p_, unsigned long *set, bool *complemented) |
2044 | 113k | { |
2045 | 113k | const uint8_t *p = (const uint8_t *) p_; |
2046 | | |
2047 | 113k | *complemented = *p == '^'; |
2048 | 113k | p += *complemented; |
2049 | | |
2050 | 113k | if (*p == ']') { |
2051 | 0 | bitmap_set1(set, ']'); |
2052 | 0 | p++; |
2053 | 0 | } |
2054 | | |
2055 | 2.34M | while (*p && *p != ']') { |
2056 | 2.23M | if (p[1] == '-' && p[2] != ']' && p[2] > *p) { |
2057 | 22.2k | bitmap_set_multiple(set, *p, p[2] - *p + 1, true); |
2058 | 22.2k | p += 3; |
2059 | 2.20M | } else { |
2060 | 2.20M | bitmap_set1(set, *p++); |
2061 | 2.20M | } |
2062 | 2.23M | } |
2063 | 113k | if (*p == ']') { |
2064 | 113k | p++; |
2065 | 113k | } |
2066 | 113k | return (const char *) p; |
2067 | 113k | } |
2068 | | |
2069 | | static const char * |
2070 | | scan_set(const char *s, const struct scan_spec *spec, const char **pp, |
2071 | | va_list *args) |
2072 | 113k | { |
2073 | 113k | unsigned long set[BITMAP_N_LONGS(UCHAR_MAX + 1)]; |
2074 | 113k | bool complemented; |
2075 | 113k | unsigned int n; |
2076 | | |
2077 | | /* Parse the scan set. */ |
2078 | 113k | memset(set, 0, sizeof set); |
2079 | 113k | *pp = parse_scanset(*pp, set, &complemented); |
2080 | | |
2081 | | /* Parse the data. */ |
2082 | 113k | n = 0; |
2083 | 790k | while (s[n] |
2084 | 726k | && bitmap_is_set(set, (unsigned char) s[n]) == !complemented |
2085 | 676k | && n < spec->width) { |
2086 | 676k | n++; |
2087 | 676k | } |
2088 | 113k | if (!n) { |
2089 | 6.82k | return NULL; |
2090 | 6.82k | } |
2091 | 106k | scan_output_string(spec, s, n, args); |
2092 | 106k | return s + n; |
2093 | 113k | } |
2094 | | |
2095 | | static const char * |
2096 | | scan_chars(const char *s, const struct scan_spec *spec, va_list *args) |
2097 | 0 | { |
2098 | 0 | unsigned int n = spec->width == UINT_MAX ? 1 : spec->width; |
2099 | |
|
2100 | 0 | if (strlen(s) < n) { |
2101 | 0 | return NULL; |
2102 | 0 | } |
2103 | 0 | if (spec->type != SCAN_DISCARD) { |
2104 | 0 | memcpy(va_arg(*args, char *), s, n); |
2105 | 0 | } |
2106 | 0 | return s + n; |
2107 | 0 | } |
2108 | | |
2109 | | static bool |
2110 | | ovs_scan__(const char *s, int *n, const char *format, va_list *args) |
2111 | 1.72M | { |
2112 | 1.72M | const char *const start = s; |
2113 | 1.72M | bool ok = false; |
2114 | 1.72M | const char *p; |
2115 | | |
2116 | 1.72M | p = format; |
2117 | 3.69M | while (*p != '\0') { |
2118 | 3.06M | struct scan_spec spec; |
2119 | 3.06M | unsigned char c = *p++; |
2120 | 3.06M | bool discard; |
2121 | | |
2122 | 3.06M | if (isspace(c)) { |
2123 | 5.19k | s = skip_spaces(s); |
2124 | 5.19k | continue; |
2125 | 3.06M | } else if (c != '%') { |
2126 | 1.78M | if (*s != c) { |
2127 | 990k | goto exit; |
2128 | 990k | } |
2129 | 794k | s++; |
2130 | 794k | continue; |
2131 | 1.78M | } else if (*p == '%') { |
2132 | 44 | if (*s++ != '%') { |
2133 | 43 | goto exit; |
2134 | 43 | } |
2135 | 1 | p++; |
2136 | 1 | continue; |
2137 | 44 | } |
2138 | | |
2139 | | /* Parse '*' flag. */ |
2140 | 1.27M | discard = *p == '*'; |
2141 | 1.27M | p += discard; |
2142 | | |
2143 | | /* Parse field width. */ |
2144 | 1.27M | spec.width = 0; |
2145 | 1.48M | while (*p >= '0' && *p <= '9') { |
2146 | 206k | spec.width = spec.width * 10 + (*p++ - '0'); |
2147 | 206k | } |
2148 | 1.27M | if (spec.width == 0) { |
2149 | 1.16M | spec.width = UINT_MAX; |
2150 | 1.16M | } |
2151 | | |
2152 | | /* Parse type modifier. */ |
2153 | 1.27M | switch (*p) { |
2154 | 355k | case 'h': |
2155 | 355k | if (p[1] == 'h') { |
2156 | 312k | spec.type = SCAN_CHAR; |
2157 | 312k | p += 2; |
2158 | 312k | } else { |
2159 | 43.4k | spec.type = SCAN_SHORT; |
2160 | 43.4k | p++; |
2161 | 43.4k | } |
2162 | 355k | break; |
2163 | | |
2164 | 0 | case 'j': |
2165 | 0 | spec.type = SCAN_INTMAX_T; |
2166 | 0 | p++; |
2167 | 0 | break; |
2168 | | |
2169 | 76.3k | case 'l': |
2170 | 76.3k | if (p[1] == 'l') { |
2171 | 34.5k | spec.type = SCAN_LLONG; |
2172 | 34.5k | p += 2; |
2173 | 41.8k | } else { |
2174 | 41.8k | spec.type = SCAN_LONG; |
2175 | 41.8k | p++; |
2176 | 41.8k | } |
2177 | 76.3k | break; |
2178 | | |
2179 | 0 | case 'L': |
2180 | 0 | case 'q': |
2181 | 0 | spec.type = SCAN_LLONG; |
2182 | 0 | p++; |
2183 | 0 | break; |
2184 | | |
2185 | 0 | case 't': |
2186 | 0 | spec.type = SCAN_PTRDIFF_T; |
2187 | 0 | p++; |
2188 | 0 | break; |
2189 | | |
2190 | 0 | case 'z': |
2191 | 0 | spec.type = SCAN_SIZE_T; |
2192 | 0 | p++; |
2193 | 0 | break; |
2194 | | |
2195 | 846k | default: |
2196 | 846k | spec.type = SCAN_INT; |
2197 | 846k | break; |
2198 | 1.27M | } |
2199 | | |
2200 | 1.27M | if (discard) { |
2201 | 0 | spec.type = SCAN_DISCARD; |
2202 | 0 | } |
2203 | | |
2204 | 1.27M | c = *p++; |
2205 | 1.27M | if (c != 'c' && c != 'n' && c != '[') { |
2206 | 764k | s = skip_spaces(s); |
2207 | 764k | } |
2208 | 1.27M | switch (c) { |
2209 | 144k | case 'd': |
2210 | 144k | s = scan_int(s, &spec, 10, args); |
2211 | 144k | break; |
2212 | | |
2213 | 441k | case 'i': |
2214 | 441k | s = scan_int(s, &spec, 0, args); |
2215 | 441k | break; |
2216 | | |
2217 | 0 | case 'o': |
2218 | 0 | s = scan_int(s, &spec, 8, args); |
2219 | 0 | break; |
2220 | | |
2221 | 146k | case 'u': |
2222 | 146k | s = scan_int(s, &spec, 10, args); |
2223 | 146k | break; |
2224 | | |
2225 | 32.3k | case 'x': |
2226 | 32.3k | case 'X': |
2227 | 32.3k | s = scan_int(s, &spec, 16, args); |
2228 | 32.3k | break; |
2229 | | |
2230 | 0 | case 'e': |
2231 | 83 | case 'f': |
2232 | 83 | case 'g': |
2233 | 83 | case 'E': |
2234 | 83 | case 'G': |
2235 | 83 | s = scan_float(s, &spec, args); |
2236 | 83 | break; |
2237 | | |
2238 | 0 | case 's': |
2239 | 0 | s = scan_string(s, &spec, args); |
2240 | 0 | break; |
2241 | | |
2242 | 113k | case '[': |
2243 | 113k | s = scan_set(s, &spec, &p, args); |
2244 | 113k | break; |
2245 | | |
2246 | 0 | case 'c': |
2247 | 0 | s = scan_chars(s, &spec, args); |
2248 | 0 | break; |
2249 | | |
2250 | 401k | case 'n': |
2251 | 401k | if (spec.type != SCAN_DISCARD) { |
2252 | 401k | *va_arg(*args, int *) = s - start; |
2253 | 401k | } |
2254 | 401k | break; |
2255 | 1.27M | } |
2256 | | |
2257 | 1.27M | if (!s) { |
2258 | 109k | goto exit; |
2259 | 109k | } |
2260 | 1.27M | } |
2261 | 628k | if (n) { |
2262 | 132k | *n = s - start; |
2263 | 132k | } |
2264 | | |
2265 | 628k | ok = true; |
2266 | 1.72M | exit: |
2267 | 1.72M | return ok; |
2268 | 628k | } |
2269 | | |
2270 | | /* This is an implementation of the standard sscanf() function, with the |
2271 | | * following exceptions: |
2272 | | * |
2273 | | * - It returns true if the entire format was successfully scanned and |
2274 | | * converted, false if any conversion failed. |
2275 | | * |
2276 | | * - The standard doesn't define sscanf() behavior when an out-of-range value |
2277 | | * is scanned, e.g. if a "%"PRIi8 conversion scans "-1" or "0x1ff". Some |
2278 | | * implementations consider this an error and stop scanning. This |
2279 | | * implementation never considers an out-of-range value an error; instead, |
2280 | | * it stores the least-significant bits of the converted value in the |
2281 | | * destination, e.g. the value 255 for both examples earlier. |
2282 | | * |
2283 | | * - Only single-byte characters are supported, that is, the 'l' modifier |
2284 | | * on %s, %[, and %c is not supported. The GNU extension 'a' modifier is |
2285 | | * also not supported. |
2286 | | * |
2287 | | * - %p is not supported. |
2288 | | */ |
2289 | | bool |
2290 | | ovs_scan(const char *s, const char *format, ...) |
2291 | 1.46M | { |
2292 | 1.46M | va_list args; |
2293 | 1.46M | bool res; |
2294 | | |
2295 | 1.46M | va_start(args, format); |
2296 | 1.46M | res = ovs_scan__(s, NULL, format, &args); |
2297 | 1.46M | va_end(args); |
2298 | 1.46M | return res; |
2299 | 1.46M | } |
2300 | | |
2301 | | /* |
2302 | | * This function is similar to ovs_scan(), with an extra parameter `n` added to |
2303 | | * return the number of scanned characters. |
2304 | | */ |
2305 | | bool |
2306 | | ovs_scan_len(const char *s, int *n, const char *format, ...) |
2307 | 266k | { |
2308 | 266k | va_list args; |
2309 | 266k | bool success; |
2310 | 266k | int n1; |
2311 | | |
2312 | 266k | va_start(args, format); |
2313 | 266k | success = ovs_scan__(s + *n, &n1, format, &args); |
2314 | 266k | va_end(args); |
2315 | 266k | if (success) { |
2316 | 132k | *n = *n + n1; |
2317 | 132k | } |
2318 | 266k | return success; |
2319 | 266k | } |
2320 | | |
2321 | | void |
2322 | | xsleep(unsigned int seconds) |
2323 | 0 | { |
2324 | 0 | ovsrcu_quiesce_start(); |
2325 | 0 | sleep(seconds); |
2326 | 0 | ovsrcu_quiesce_end(); |
2327 | 0 | } |
2328 | | |
2329 | | static void |
2330 | | xnanosleep__(uint64_t nanoseconds) |
2331 | 0 | { |
2332 | 0 | int retval; |
2333 | 0 | struct timespec ts_sleep; |
2334 | 0 | nsec_to_timespec(nanoseconds, &ts_sleep); |
2335 | |
|
2336 | 0 | int error = 0; |
2337 | 0 | do { |
2338 | 0 | retval = nanosleep(&ts_sleep, NULL); |
2339 | 0 | error = retval < 0 ? errno : 0; |
2340 | 0 | } while (error == EINTR); |
2341 | 0 | } |
2342 | | |
2343 | | /* High resolution sleep with thread quiesce. */ |
2344 | | void |
2345 | | xnanosleep(uint64_t nanoseconds) |
2346 | 0 | { |
2347 | 0 | ovsrcu_quiesce_start(); |
2348 | 0 | xnanosleep__(nanoseconds); |
2349 | 0 | ovsrcu_quiesce_end(); |
2350 | 0 | } |
2351 | | |
2352 | | /* High resolution sleep without thread quiesce. */ |
2353 | | void |
2354 | | xnanosleep_no_quiesce(uint64_t nanoseconds) |
2355 | 0 | { |
2356 | 0 | xnanosleep__(nanoseconds); |
2357 | 0 | } |
2358 | | |
2359 | | #if __linux__ |
2360 | | void |
2361 | | set_timer_resolution(unsigned long nanoseconds) |
2362 | 0 | { |
2363 | 0 | prctl(PR_SET_TIMERSLACK, nanoseconds); |
2364 | 0 | } |
2365 | | #else |
2366 | | void |
2367 | | set_timer_resolution(unsigned long nanoseconds OVS_UNUSED) |
2368 | | { |
2369 | | } |
2370 | | #endif |
2371 | | |
2372 | | /* Determine whether standard output is a tty or not. This is useful to decide |
2373 | | * whether to use color output or not when --color option for utilities is set |
2374 | | * to `auto`. |
2375 | | */ |
2376 | | bool |
2377 | | is_stdout_a_tty(void) |
2378 | 0 | { |
2379 | 0 | char const *t = getenv("TERM"); |
2380 | 0 | return (isatty(STDOUT_FILENO) && t && strcmp(t, "dumb") != 0); |
2381 | 0 | } |
2382 | | |
2383 | | #ifdef __linux__ |
2384 | | bool |
2385 | | ovs_kernel_is_version_or_newer(int target_major, int target_minor) |
2386 | 0 | { |
2387 | 0 | static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; |
2388 | 0 | static int current_major, current_minor = -1; |
2389 | |
|
2390 | 0 | if (ovsthread_once_start(&once)) { |
2391 | 0 | struct utsname utsname; |
2392 | |
|
2393 | 0 | if (uname(&utsname) == -1) { |
2394 | 0 | VLOG_WARN("uname failed (%s)", ovs_strerror(errno)); |
2395 | 0 | } else if (!ovs_scan(utsname.release, "%d.%d", |
2396 | 0 | ¤t_major, ¤t_minor)) { |
2397 | 0 | VLOG_WARN("uname reported bad OS release (%s)", utsname.release); |
2398 | 0 | } |
2399 | 0 | ovsthread_once_done(&once); |
2400 | 0 | } |
2401 | 0 | if (current_major == -1 || current_minor == -1) { |
2402 | 0 | return false; |
2403 | 0 | } |
2404 | 0 | return current_major > target_major || ( |
2405 | 0 | current_major == target_major && current_minor >= target_minor); |
2406 | 0 | } |
2407 | | #endif |