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