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/osdep.h"
25#include "qemu-common.h"
26#include "qemu/host-utils.h"
27#include <math.h>
28
29#include "qemu/sockets.h"
30#include "qemu/iov.h"
31#include "net/net.h"
32#include "qemu/cutils.h"
33#include "qemu/error-report.h"
34
35void strpadcpy(char *buf, int buf_size, const char *str, char pad)
36{
37 int len = qemu_strnlen(str, buf_size);
38 memcpy(buf, str, len);
39 memset(buf + len, pad, buf_size - len);
40}
41
42void pstrcpy(char *buf, int buf_size, const char *str)
43{
44 int c;
45 char *q = buf;
46
47 if (buf_size <= 0)
48 return;
49
50 for(;;) {
51 c = *str++;
52 if (c == 0 || q >= buf + buf_size - 1)
53 break;
54 *q++ = c;
55 }
56 *q = '\0';
57}
58
59
60char *pstrcat(char *buf, int buf_size, const char *s)
61{
62 int len;
63 len = strlen(buf);
64 if (len < buf_size)
65 pstrcpy(buf + len, buf_size - len, s);
66 return buf;
67}
68
69int strstart(const char *str, const char *val, const char **ptr)
70{
71 const char *p, *q;
72 p = str;
73 q = val;
74 while (*q != '\0') {
75 if (*p != *q)
76 return 0;
77 p++;
78 q++;
79 }
80 if (ptr)
81 *ptr = p;
82 return 1;
83}
84
85int stristart(const char *str, const char *val, const char **ptr)
86{
87 const char *p, *q;
88 p = str;
89 q = val;
90 while (*q != '\0') {
91 if (qemu_toupper(*p) != qemu_toupper(*q))
92 return 0;
93 p++;
94 q++;
95 }
96 if (ptr)
97 *ptr = p;
98 return 1;
99}
100
101
102int qemu_strnlen(const char *s, int max_len)
103{
104 int i;
105
106 for(i = 0; i < max_len; i++) {
107 if (s[i] == '\0') {
108 break;
109 }
110 }
111 return i;
112}
113
114char *qemu_strsep(char **input, const char *delim)
115{
116 char *result = *input;
117 if (result != NULL) {
118 char *p;
119
120 for (p = result; *p != '\0'; p++) {
121 if (strchr(delim, *p)) {
122 break;
123 }
124 }
125 if (*p == '\0') {
126 *input = NULL;
127 } else {
128 *p = '\0';
129 *input = p + 1;
130 }
131 }
132 return result;
133}
134
135time_t mktimegm(struct tm *tm)
136{
137 time_t t;
138 int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
139 if (m < 3) {
140 m += 12;
141 y--;
142 }
143 t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
144 y / 400 - 719469);
145 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
146 return t;
147}
148
149
150
151
152
153
154
155
156int qemu_fdatasync(int fd)
157{
158#ifdef CONFIG_FDATASYNC
159 return fdatasync(fd);
160#else
161 return fsync(fd);
162#endif
163}
164
165#ifndef _WIN32
166
167int fcntl_setfl(int fd, int flag)
168{
169 int flags;
170
171 flags = fcntl(fd, F_GETFL);
172 if (flags == -1)
173 return -errno;
174
175 if (fcntl(fd, F_SETFL, flags | flag) == -1)
176 return -errno;
177
178 return 0;
179}
180#endif
181
182static int64_t suffix_mul(char suffix, int64_t unit)
183{
184 switch (qemu_toupper(suffix)) {
185 case 'B':
186 return 1;
187 case 'K':
188 return unit;
189 case 'M':
190 return unit * unit;
191 case 'G':
192 return unit * unit * unit;
193 case 'T':
194 return unit * unit * unit * unit;
195 case 'P':
196 return unit * unit * unit * unit * unit;
197 case 'E':
198 return unit * unit * unit * unit * unit * unit;
199 }
200 return -1;
201}
202
203
204
205
206
207
208
209static int do_strtosz(const char *nptr, char **end,
210 const char default_suffix, int64_t unit,
211 uint64_t *result)
212{
213 int retval;
214 char *endptr;
215 unsigned char c;
216 int mul_required = 0;
217 double val, mul, integral, fraction;
218
219 errno = 0;
220 val = strtod(nptr, &endptr);
221 if (isnan(val) || endptr == nptr || errno != 0) {
222 retval = -EINVAL;
223 goto out;
224 }
225 fraction = modf(val, &integral);
226 if (fraction != 0) {
227 mul_required = 1;
228 }
229 c = *endptr;
230 mul = suffix_mul(c, unit);
231 if (mul >= 0) {
232 endptr++;
233 } else {
234 mul = suffix_mul(default_suffix, unit);
235 assert(mul >= 0);
236 }
237 if (mul == 1 && mul_required) {
238 retval = -EINVAL;
239 goto out;
240 }
241
242
243
244
245 if ((val * mul >= 0xfffffffffffffc00) || val < 0) {
246 retval = -ERANGE;
247 goto out;
248 }
249 *result = val * mul;
250 retval = 0;
251
252out:
253 if (end) {
254 *end = endptr;
255 } else if (*endptr) {
256 retval = -EINVAL;
257 }
258
259 return retval;
260}
261
262int qemu_strtosz(const char *nptr, char **end, uint64_t *result)
263{
264 return do_strtosz(nptr, end, 'B', 1024, result);
265}
266
267int qemu_strtosz_MiB(const char *nptr, char **end, uint64_t *result)
268{
269 return do_strtosz(nptr, end, 'M', 1024, result);
270}
271
272int qemu_strtosz_metric(const char *nptr, char **end, uint64_t *result)
273{
274 return do_strtosz(nptr, end, 'B', 1000, result);
275}
276
277
278
279
280static int check_strtox_error(const char *nptr, char *ep,
281 const char **endptr, int libc_errno)
282{
283 if (endptr) {
284 *endptr = ep;
285 }
286
287
288 if (libc_errno == 0 && ep == nptr) {
289 return -EINVAL;
290 }
291
292
293 if (!endptr && *ep) {
294 return -EINVAL;
295 }
296
297 return -libc_errno;
298}
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324int qemu_strtoi(const char *nptr, const char **endptr, int base,
325 int *result)
326{
327 char *ep;
328 long long lresult;
329
330 if (!nptr) {
331 if (endptr) {
332 *endptr = nptr;
333 }
334 return -EINVAL;
335 }
336
337 errno = 0;
338 lresult = strtoll(nptr, &ep, base);
339 if (lresult < INT_MIN) {
340 *result = INT_MIN;
341 errno = ERANGE;
342 } else if (lresult > INT_MAX) {
343 *result = INT_MAX;
344 errno = ERANGE;
345 } else {
346 *result = lresult;
347 }
348 return check_strtox_error(nptr, ep, endptr, errno);
349}
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376int qemu_strtoui(const char *nptr, const char **endptr, int base,
377 unsigned int *result)
378{
379 char *ep;
380 long long lresult;
381
382 if (!nptr) {
383 if (endptr) {
384 *endptr = nptr;
385 }
386 return -EINVAL;
387 }
388
389 errno = 0;
390 lresult = strtoull(nptr, &ep, base);
391
392
393 if (errno == ERANGE) {
394 *result = -1;
395 } else {
396 if (lresult > UINT_MAX) {
397 *result = UINT_MAX;
398 errno = ERANGE;
399 } else if (lresult < INT_MIN) {
400 *result = UINT_MAX;
401 errno = ERANGE;
402 } else {
403 *result = lresult;
404 }
405 }
406 return check_strtox_error(nptr, ep, endptr, errno);
407}
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433int qemu_strtol(const char *nptr, const char **endptr, int base,
434 long *result)
435{
436 char *ep;
437
438 if (!nptr) {
439 if (endptr) {
440 *endptr = nptr;
441 }
442 return -EINVAL;
443 }
444
445 errno = 0;
446 *result = strtol(nptr, &ep, base);
447 return check_strtox_error(nptr, ep, endptr, errno);
448}
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475int qemu_strtoul(const char *nptr, const char **endptr, int base,
476 unsigned long *result)
477{
478 char *ep;
479
480 if (!nptr) {
481 if (endptr) {
482 *endptr = nptr;
483 }
484 return -EINVAL;
485 }
486
487 errno = 0;
488 *result = strtoul(nptr, &ep, base);
489
490 if (errno == ERANGE) {
491 *result = -1;
492 }
493 return check_strtox_error(nptr, ep, endptr, errno);
494}
495
496
497
498
499
500
501
502int qemu_strtoi64(const char *nptr, const char **endptr, int base,
503 int64_t *result)
504{
505 char *ep;
506
507 if (!nptr) {
508 if (endptr) {
509 *endptr = nptr;
510 }
511 return -EINVAL;
512 }
513
514 errno = 0;
515
516 *result = strtoll(nptr, &ep, base);
517 return check_strtox_error(nptr, ep, endptr, errno);
518}
519
520
521
522
523
524
525int qemu_strtou64(const char *nptr, const char **endptr, int base,
526 uint64_t *result)
527{
528 char *ep;
529
530 if (!nptr) {
531 if (endptr) {
532 *endptr = nptr;
533 }
534 return -EINVAL;
535 }
536
537 errno = 0;
538
539 *result = strtoull(nptr, &ep, base);
540
541 if (errno == ERANGE) {
542 *result = -1;
543 }
544 return check_strtox_error(nptr, ep, endptr, errno);
545}
546
547
548
549
550
551#ifndef HAVE_STRCHRNUL
552const char *qemu_strchrnul(const char *s, int c)
553{
554 const char *e = strchr(s, c);
555 if (!e) {
556 e = s + strlen(s);
557 }
558 return e;
559}
560#endif
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590int parse_uint(const char *s, unsigned long long *value, char **endptr,
591 int base)
592{
593 int r = 0;
594 char *endp = (char *)s;
595 unsigned long long val = 0;
596
597 if (!s) {
598 r = -EINVAL;
599 goto out;
600 }
601
602 errno = 0;
603 val = strtoull(s, &endp, base);
604 if (errno) {
605 r = -errno;
606 goto out;
607 }
608
609 if (endp == s) {
610 r = -EINVAL;
611 goto out;
612 }
613
614
615 while (isspace((unsigned char)*s)) {
616 s++;
617 }
618 if (*s == '-') {
619 val = 0;
620 r = -ERANGE;
621 goto out;
622 }
623
624out:
625 *value = val;
626 *endptr = endp;
627 return r;
628}
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644int parse_uint_full(const char *s, unsigned long long *value, int base)
645{
646 char *endp;
647 int r;
648
649 r = parse_uint(s, value, &endp, base);
650 if (r < 0) {
651 return r;
652 }
653 if (*endp) {
654 *value = 0;
655 return -EINVAL;
656 }
657
658 return 0;
659}
660
661int qemu_parse_fd(const char *param)
662{
663 long fd;
664 char *endptr;
665
666 errno = 0;
667 fd = strtol(param, &endptr, 10);
668 if (param == endptr ||
669 errno != 0 ||
670 *endptr != '\0' ||
671 fd < 0 ||
672 fd > INT_MAX ) {
673 return -1;
674 }
675 return fd;
676}
677
678
679
680
681
682int uleb128_encode_small(uint8_t *out, uint32_t n)
683{
684 g_assert(n <= 0x3fff);
685 if (n < 0x80) {
686 *out++ = n;
687 return 1;
688 } else {
689 *out++ = (n & 0x7f) | 0x80;
690 *out++ = n >> 7;
691 return 2;
692 }
693}
694
695int uleb128_decode_small(const uint8_t *in, uint32_t *n)
696{
697 if (!(*in & 0x80)) {
698 *n = *in++;
699 return 1;
700 } else {
701 *n = *in++ & 0x7f;
702
703 if (*in & 0x80) {
704 return -1;
705 }
706 *n |= *in++ << 7;
707 return 2;
708 }
709}
710
711
712
713
714int parse_debug_env(const char *name, int max, int initial)
715{
716 char *debug_env = getenv(name);
717 char *inv = NULL;
718 long debug;
719
720 if (!debug_env) {
721 return initial;
722 }
723 errno = 0;
724 debug = strtol(debug_env, &inv, 10);
725 if (inv == debug_env) {
726 return initial;
727 }
728 if (debug < 0 || debug > max || errno != 0) {
729 warn_report("%s not in [0, %d]", name, max);
730 return initial;
731 }
732 return debug;
733}
734
735
736
737
738const char *qemu_ether_ntoa(const MACAddr *mac)
739{
740 static char ret[18];
741
742 snprintf(ret, sizeof(ret), "%02x:%02x:%02x:%02x:%02x:%02x",
743 mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5]);
744
745 return ret;
746}
747
748
749
750
751
752
753
754char *size_to_str(uint64_t val)
755{
756 static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
757 unsigned long div;
758 int i;
759
760
761
762
763
764
765
766 frexp(val / (1000.0 / 1024.0), &i);
767 i = (i - 1) / 10;
768 div = 1ULL << (i * 10);
769
770 return g_strdup_printf("%0.3g %sB", (double)val / div, suffixes[i]);
771}
772