1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "qemu-common.h"
25#include "qemu/host-utils.h"
26#include <math.h>
27#include <limits.h>
28#include <errno.h>
29
30#include "qemu/sockets.h"
31#include "qemu/iov.h"
32#include "net/net.h"
33
34void strpadcpy(char *buf, int buf_size, const char *str, char pad)
35{
36 int len = qemu_strnlen(str, buf_size);
37 memcpy(buf, str, len);
38 memset(buf + len, pad, buf_size - len);
39}
40
41void pstrcpy(char *buf, int buf_size, const char *str)
42{
43 int c;
44 char *q = buf;
45
46 if (buf_size <= 0)
47 return;
48
49 for(;;) {
50 c = *str++;
51 if (c == 0 || q >= buf + buf_size - 1)
52 break;
53 *q++ = c;
54 }
55 *q = '\0';
56}
57
58
59char *pstrcat(char *buf, int buf_size, const char *s)
60{
61 int len;
62 len = strlen(buf);
63 if (len < buf_size)
64 pstrcpy(buf + len, buf_size - len, s);
65 return buf;
66}
67
68int strstart(const char *str, const char *val, const char **ptr)
69{
70 const char *p, *q;
71 p = str;
72 q = val;
73 while (*q != '\0') {
74 if (*p != *q)
75 return 0;
76 p++;
77 q++;
78 }
79 if (ptr)
80 *ptr = p;
81 return 1;
82}
83
84int stristart(const char *str, const char *val, const char **ptr)
85{
86 const char *p, *q;
87 p = str;
88 q = val;
89 while (*q != '\0') {
90 if (qemu_toupper(*p) != qemu_toupper(*q))
91 return 0;
92 p++;
93 q++;
94 }
95 if (ptr)
96 *ptr = p;
97 return 1;
98}
99
100
101int qemu_strnlen(const char *s, int max_len)
102{
103 int i;
104
105 for(i = 0; i < max_len; i++) {
106 if (s[i] == '\0') {
107 break;
108 }
109 }
110 return i;
111}
112
113char *qemu_strsep(char **input, const char *delim)
114{
115 char *result = *input;
116 if (result != NULL) {
117 char *p;
118
119 for (p = result; *p != '\0'; p++) {
120 if (strchr(delim, *p)) {
121 break;
122 }
123 }
124 if (*p == '\0') {
125 *input = NULL;
126 } else {
127 *p = '\0';
128 *input = p + 1;
129 }
130 }
131 return result;
132}
133
134time_t mktimegm(struct tm *tm)
135{
136 time_t t;
137 int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
138 if (m < 3) {
139 m += 12;
140 y--;
141 }
142 t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
143 y / 400 - 719469);
144 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
145 return t;
146}
147
148int qemu_fls(int i)
149{
150 return 32 - clz32(i);
151}
152
153
154
155
156
157
158
159
160int qemu_fdatasync(int fd)
161{
162#ifdef CONFIG_FDATASYNC
163 return fdatasync(fd);
164#else
165 return fsync(fd);
166#endif
167}
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189size_t buffer_find_nonzero_offset(const void *buf, size_t len)
190{
191 const VECTYPE *p = buf;
192 const VECTYPE zero = (VECTYPE){0};
193 size_t i;
194
195 assert(can_use_buffer_find_nonzero_offset(buf, len));
196
197 if (!len) {
198 return 0;
199 }
200
201 for (i = 0; i < BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) {
202 if (!ALL_EQ(p[i], zero)) {
203 return i * sizeof(VECTYPE);
204 }
205 }
206
207 for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR;
208 i < len / sizeof(VECTYPE);
209 i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) {
210 VECTYPE tmp0 = p[i + 0] | p[i + 1];
211 VECTYPE tmp1 = p[i + 2] | p[i + 3];
212 VECTYPE tmp2 = p[i + 4] | p[i + 5];
213 VECTYPE tmp3 = p[i + 6] | p[i + 7];
214 VECTYPE tmp01 = tmp0 | tmp1;
215 VECTYPE tmp23 = tmp2 | tmp3;
216 if (!ALL_EQ(tmp01 | tmp23, zero)) {
217 break;
218 }
219 }
220
221 return i * sizeof(VECTYPE);
222}
223
224
225
226
227
228
229
230bool buffer_is_zero(const void *buf, size_t len)
231{
232
233
234
235
236
237
238 size_t i;
239 long d0, d1, d2, d3;
240 const long * const data = buf;
241
242
243 if (can_use_buffer_find_nonzero_offset(buf, len)) {
244 return buffer_find_nonzero_offset(buf, len) == len;
245 }
246
247 assert(len % (4 * sizeof(long)) == 0);
248 len /= sizeof(long);
249
250 for (i = 0; i < len; i += 4) {
251 d0 = data[i + 0];
252 d1 = data[i + 1];
253 d2 = data[i + 2];
254 d3 = data[i + 3];
255
256 if (d0 || d1 || d2 || d3) {
257 return false;
258 }
259 }
260
261 return true;
262}
263
264#ifndef _WIN32
265
266int fcntl_setfl(int fd, int flag)
267{
268 int flags;
269
270 flags = fcntl(fd, F_GETFL);
271 if (flags == -1)
272 return -errno;
273
274 if (fcntl(fd, F_SETFL, flags | flag) == -1)
275 return -errno;
276
277 return 0;
278}
279#endif
280
281static int64_t suffix_mul(char suffix, int64_t unit)
282{
283 switch (qemu_toupper(suffix)) {
284 case STRTOSZ_DEFSUFFIX_B:
285 return 1;
286 case STRTOSZ_DEFSUFFIX_KB:
287 return unit;
288 case STRTOSZ_DEFSUFFIX_MB:
289 return unit * unit;
290 case STRTOSZ_DEFSUFFIX_GB:
291 return unit * unit * unit;
292 case STRTOSZ_DEFSUFFIX_TB:
293 return unit * unit * unit * unit;
294 case STRTOSZ_DEFSUFFIX_PB:
295 return unit * unit * unit * unit * unit;
296 case STRTOSZ_DEFSUFFIX_EB:
297 return unit * unit * unit * unit * unit * unit;
298 }
299 return -1;
300}
301
302
303
304
305
306
307
308int64_t strtosz_suffix_unit(const char *nptr, char **end,
309 const char default_suffix, int64_t unit)
310{
311 int64_t retval = -EINVAL;
312 char *endptr;
313 unsigned char c;
314 int mul_required = 0;
315 double val, mul, integral, fraction;
316
317 errno = 0;
318 val = strtod(nptr, &endptr);
319 if (isnan(val) || endptr == nptr || errno != 0) {
320 goto fail;
321 }
322 fraction = modf(val, &integral);
323 if (fraction != 0) {
324 mul_required = 1;
325 }
326 c = *endptr;
327 mul = suffix_mul(c, unit);
328 if (mul >= 0) {
329 endptr++;
330 } else {
331 mul = suffix_mul(default_suffix, unit);
332 assert(mul >= 0);
333 }
334 if (mul == 1 && mul_required) {
335 goto fail;
336 }
337 if ((val * mul >= INT64_MAX) || val < 0) {
338 retval = -ERANGE;
339 goto fail;
340 }
341 retval = val * mul;
342
343fail:
344 if (end) {
345 *end = endptr;
346 }
347
348 return retval;
349}
350
351int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
352{
353 return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
354}
355
356int64_t strtosz(const char *nptr, char **end)
357{
358 return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB);
359}
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389int parse_uint(const char *s, unsigned long long *value, char **endptr,
390 int base)
391{
392 int r = 0;
393 char *endp = (char *)s;
394 unsigned long long val = 0;
395
396 if (!s) {
397 r = -EINVAL;
398 goto out;
399 }
400
401 errno = 0;
402 val = strtoull(s, &endp, base);
403 if (errno) {
404 r = -errno;
405 goto out;
406 }
407
408 if (endp == s) {
409 r = -EINVAL;
410 goto out;
411 }
412
413
414 while (isspace((unsigned char)*s)) {
415 s++;
416 }
417 if (*s == '-') {
418 val = 0;
419 r = -ERANGE;
420 goto out;
421 }
422
423out:
424 *value = val;
425 *endptr = endp;
426 return r;
427}
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443int parse_uint_full(const char *s, unsigned long long *value, int base)
444{
445 char *endp;
446 int r;
447
448 r = parse_uint(s, value, &endp, base);
449 if (r < 0) {
450 return r;
451 }
452 if (*endp) {
453 *value = 0;
454 return -EINVAL;
455 }
456
457 return 0;
458}
459
460int qemu_parse_fd(const char *param)
461{
462 long fd;
463 char *endptr;
464
465 errno = 0;
466 fd = strtol(param, &endptr, 10);
467 if (param == endptr ||
468 errno != 0 ||
469 *endptr != '\0' ||
470 fd < 0 ||
471 fd > INT_MAX ) {
472 return -1;
473 }
474 return fd;
475}
476
477
478int64_t pow2floor(int64_t value)
479{
480 if (!is_power_of_2(value)) {
481 value = 0x8000000000000000ULL >> clz64(value);
482 }
483 return value;
484}
485
486
487
488
489
490int uleb128_encode_small(uint8_t *out, uint32_t n)
491{
492 g_assert(n <= 0x3fff);
493 if (n < 0x80) {
494 *out++ = n;
495 return 1;
496 } else {
497 *out++ = (n & 0x7f) | 0x80;
498 *out++ = n >> 7;
499 return 2;
500 }
501}
502
503int uleb128_decode_small(const uint8_t *in, uint32_t *n)
504{
505 if (!(*in & 0x80)) {
506 *n = *in++;
507 return 1;
508 } else {
509 *n = *in++ & 0x7f;
510
511 if (*in & 0x80) {
512 return -1;
513 }
514 *n |= *in++ << 7;
515 return 2;
516 }
517}
518
519
520
521
522int parse_debug_env(const char *name, int max, int initial)
523{
524 char *debug_env = getenv(name);
525 char *inv = NULL;
526 int debug;
527
528 if (!debug_env) {
529 return initial;
530 }
531 debug = strtol(debug_env, &inv, 10);
532 if (inv == debug_env) {
533 return initial;
534 }
535 if (debug < 0 || debug > max) {
536 fprintf(stderr, "warning: %s not in [0, %d]", name, max);
537 return initial;
538 }
539 return debug;
540}
541
542
543
544
545const char *qemu_ether_ntoa(const MACAddr *mac)
546{
547 static char ret[18];
548
549 snprintf(ret, sizeof(ret), "%02x:%02x:%02x:%02x:%02x:%02x",
550 mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5]);
551
552 return ret;
553}
554