]>
git.proxmox.com Git - mirror_ovs.git/blob - lib/util.c
2 * Copyright (c) 2008, 2009, 2010 Nicira Networks.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 const char *program_name
;
31 ovs_fatal(0, "virtual memory exhausted");
35 xcalloc(size_t count
, size_t size
)
37 void *p
= count
&& size
? calloc(count
, size
) : malloc(1);
38 COVERAGE_INC(util_xalloc
);
48 return xcalloc(1, size
);
54 void *p
= malloc(size
? size
: 1);
55 COVERAGE_INC(util_xalloc
);
63 xrealloc(void *p
, size_t size
)
65 p
= realloc(p
, size
? size
: 1);
66 COVERAGE_INC(util_xalloc
);
74 xmemdup(const void *p_
, size_t size
)
76 void *p
= xmalloc(size
);
82 xmemdup0(const char *p_
, size_t length
)
84 char *p
= xmalloc(length
+ 1);
85 memcpy(p
, p_
, length
);
91 xstrdup(const char *s
)
93 return xmemdup0(s
, strlen(s
));
97 xvasprintf(const char *format
, va_list args
)
103 va_copy(args2
, args
);
104 needed
= vsnprintf(NULL
, 0, format
, args
);
106 s
= xmalloc(needed
+ 1);
108 vsnprintf(s
, needed
+ 1, format
, args2
);
115 x2nrealloc(void *p
, size_t *n
, size_t s
)
117 *n
= *n
== 0 ? 1 : 2 * *n
;
118 return xrealloc(p
, *n
* s
);
122 xasprintf(const char *format
, ...)
127 va_start(args
, format
);
128 s
= xvasprintf(format
, args
);
135 ovs_strlcpy(char *dst
, const char *src
, size_t size
)
138 size_t n
= strlen(src
);
139 size_t n_copy
= MIN(n
, size
- 1);
140 memcpy(dst
, src
, n_copy
);
146 ovs_fatal(int err_no
, const char *format
, ...)
150 fprintf(stderr
, "%s: ", program_name
);
151 va_start(args
, format
);
152 vfprintf(stderr
, format
, args
);
155 fprintf(stderr
, " (%s)", strerror(err_no
));
162 ovs_error(int err_no
, const char *format
, ...)
164 int save_errno
= errno
;
167 fprintf(stderr
, "%s: ", program_name
);
168 va_start(args
, format
);
169 vfprintf(stderr
, format
, args
);
172 fprintf(stderr
, " (%s)",
173 err_no
== EOF
? "end of file" : strerror(err_no
));
180 /* Sets program_name based on 'argv0'. Should be called at the beginning of
181 * main(), as "set_program_name(argv[0]);". */
182 void set_program_name(const char *argv0
)
184 const char *slash
= strrchr(argv0
, '/');
185 program_name
= slash
? slash
+ 1 : argv0
;
188 /* Print the version information for the program. */
190 ovs_print_version(char *date
, char *time
,
191 uint8_t min_ofp
, uint8_t max_ofp
)
193 printf("%s (Open vSwitch) "VERSION BUILDNR
"\n", program_name
);
194 printf("Compiled %s %s\n", date
, time
);
195 if (min_ofp
|| max_ofp
) {
196 printf("OpenFlow versions %#x:%#x\n", min_ofp
, max_ofp
);
200 /* Writes the 'size' bytes in 'buf' to 'stream' as hex bytes arranged 16 per
201 * line. Numeric offsets are also included, starting at 'ofs' for the first
202 * byte in 'buf'. If 'ascii' is true then the corresponding ASCII characters
203 * are also rendered alongside. */
205 ovs_hex_dump(FILE *stream
, const void *buf_
, size_t size
,
206 uintptr_t ofs
, bool ascii
)
208 const uint8_t *buf
= buf_
;
209 const size_t per_line
= 16; /* Maximum bytes per line. */
213 size_t start
, end
, n
;
216 /* Number of bytes on this line. */
217 start
= ofs
% per_line
;
219 if (end
- start
> size
)
224 fprintf(stream
, "%08jx ", (uintmax_t) ROUND_DOWN(ofs
, per_line
));
225 for (i
= 0; i
< start
; i
++)
226 fprintf(stream
, " ");
228 fprintf(stream
, "%02hhx%c",
229 buf
[i
- start
], i
== per_line
/ 2 - 1? '-' : ' ');
232 for (; i
< per_line
; i
++)
233 fprintf(stream
, " ");
234 fprintf(stream
, "|");
235 for (i
= 0; i
< start
; i
++)
236 fprintf(stream
, " ");
237 for (; i
< end
; i
++) {
238 int c
= buf
[i
- start
];
239 putc(c
>= 32 && c
< 127 ? c
: '.', stream
);
241 for (; i
< per_line
; i
++)
242 fprintf(stream
, " ");
243 fprintf(stream
, "|");
245 fprintf(stream
, "\n");
254 str_to_int(const char *s
, int base
, int *i
)
257 bool ok
= str_to_llong(s
, base
, &ll
);
263 str_to_long(const char *s
, int base
, long *li
)
266 bool ok
= str_to_llong(s
, base
, &ll
);
272 str_to_llong(const char *s
, int base
, long long *x
)
274 int save_errno
= errno
;
277 *x
= strtoll(s
, &tail
, base
);
278 if (errno
== EINVAL
|| errno
== ERANGE
|| tail
== s
|| *tail
!= '\0') {
289 str_to_uint(const char *s
, int base
, unsigned int *u
)
291 return str_to_int(s
, base
, (int *) u
);
295 str_to_ulong(const char *s
, int base
, unsigned long *ul
)
297 return str_to_long(s
, base
, (long *) ul
);
301 str_to_ullong(const char *s
, int base
, unsigned long long *ull
)
303 return str_to_llong(s
, base
, (long long *) ull
);
306 /* Converts floating-point string 's' into a double. If successful, stores
307 * the double in '*d' and returns true; on failure, stores 0 in '*d' and
310 * Underflow (e.g. "1e-9999") is not considered an error, but overflow
311 * (e.g. "1e9999)" is. */
313 str_to_double(const char *s
, double *d
)
315 int save_errno
= errno
;
318 *d
= strtod(s
, &tail
);
319 if (errno
== EINVAL
|| (errno
== ERANGE
&& *d
!= 0)
320 || tail
== s
|| *tail
!= '\0') {
330 /* Returns the value of 'c' as a hexadecimal digit. */
335 case '0': case '1': case '2': case '3': case '4':
336 case '5': case '6': case '7': case '8': case '9':
361 /* Returns the directory name portion of 'file_name' as a malloc()'d string,
362 * similar to the POSIX dirname() function but thread-safe. */
364 dir_name(const char *file_name
)
366 size_t len
= strlen(file_name
);
367 while (len
> 0 && file_name
[len
- 1] == '/') {
370 while (len
> 0 && file_name
[len
- 1] != '/') {
373 while (len
> 0 && file_name
[len
- 1] == '/') {
377 return xstrdup((file_name
[0] == '/'
378 && file_name
[1] == '/'
379 && file_name
[2] != '/') ? "//"
380 : file_name
[0] == '/' ? "/"
383 return xmemdup0(file_name
, len
);
387 /* Pass a value to this function if it is marked with
388 * __attribute__((warn_unused_result)) and you genuinely want to ignore
389 * its return value. (Note that every scalar type can be implicitly
390 * converted to bool.) */
391 void ignore(bool x OVS_UNUSED
) { }