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
168
169
170
171
172
173
174
175
176
177
178int qemu_msync(void *addr, size_t length, int fd)
179{
180#ifdef CONFIG_POSIX
181 size_t align_mask = ~(qemu_real_host_page_size - 1);
182
183
184
185
186
187
188
189 length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
190 length = (length + ~align_mask) & align_mask;
191
192 addr = (void *)((uintptr_t)addr & align_mask);
193
194 return msync(addr, length, MS_SYNC);
195#else
196
197
198
199
200
201 return qemu_fdatasync(fd);
202#endif
203}
204
205#ifndef _WIN32
206
207int fcntl_setfl(int fd, int flag)
208{
209 int flags;
210
211 flags = fcntl(fd, F_GETFL);
212 if (flags == -1)
213 return -errno;
214
215 if (fcntl(fd, F_SETFL, flags | flag) == -1)
216 return -errno;
217
218 return 0;
219}
220#endif
221
222static int64_t suffix_mul(char suffix, int64_t unit)
223{
224 switch (qemu_toupper(suffix)) {
225 case 'B':
226 return 1;
227 case 'K':
228 return unit;
229 case 'M':
230 return unit * unit;
231 case 'G':
232 return unit * unit * unit;
233 case 'T':
234 return unit * unit * unit * unit;
235 case 'P':
236 return unit * unit * unit * unit * unit;
237 case 'E':
238 return unit * unit * unit * unit * unit * unit;
239 }
240 return -1;
241}
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271static int do_strtosz(const char *nptr, const char **end,
272 const char default_suffix, int64_t unit,
273 uint64_t *result)
274{
275 int retval;
276 const char *endptr, *f;
277 unsigned char c;
278 bool hex = false;
279 uint64_t val, valf = 0;
280 int64_t mul;
281
282
283 retval = qemu_strtou64(nptr, &endptr, 10, &val);
284 if (retval) {
285 goto out;
286 }
287 if (memchr(nptr, '-', endptr - nptr) != NULL) {
288 endptr = nptr;
289 retval = -EINVAL;
290 goto out;
291 }
292 if (val == 0 && (*endptr == 'x' || *endptr == 'X')) {
293
294 retval = qemu_strtou64(nptr, &endptr, 16, &val);
295 if (retval) {
296 goto out;
297 }
298 if (*endptr == '.') {
299 endptr = nptr;
300 retval = -EINVAL;
301 goto out;
302 }
303 hex = true;
304 } else if (*endptr == '.') {
305
306
307
308
309
310 double fraction;
311
312 f = endptr;
313 retval = qemu_strtod_finite(f, &endptr, &fraction);
314 if (retval) {
315 endptr++;
316 } else if (memchr(f, 'e', endptr - f) || memchr(f, 'E', endptr - f)) {
317 endptr = nptr;
318 retval = -EINVAL;
319 goto out;
320 } else {
321
322 valf = (uint64_t)(fraction * 0x1p64);
323 }
324 }
325 c = *endptr;
326 mul = suffix_mul(c, unit);
327 if (mul > 0) {
328 if (hex) {
329 warn_report("Using a multiplier suffix on hex numbers "
330 "is deprecated: %s", nptr);
331 }
332 endptr++;
333 } else {
334 mul = suffix_mul(default_suffix, unit);
335 assert(mul > 0);
336 }
337 if (mul == 1) {
338
339 if (valf != 0) {
340 endptr = nptr;
341 retval = -EINVAL;
342 goto out;
343 }
344 } else {
345 uint64_t valh, tmp;
346
347
348 mulu64(&val, &valh, val, mul);
349 mulu64(&valf, &tmp, valf, mul);
350 val += tmp;
351 valh += val < tmp;
352
353
354 tmp = valf >> 63;
355 val += tmp;
356 valh += val < tmp;
357
358
359 if (valh != 0) {
360 retval = -ERANGE;
361 goto out;
362 }
363 }
364
365 retval = 0;
366
367out:
368 if (end) {
369 *end = endptr;
370 } else if (*endptr) {
371 retval = -EINVAL;
372 }
373 if (retval == 0) {
374 *result = val;
375 }
376
377 return retval;
378}
379
380int qemu_strtosz(const char *nptr, const char **end, uint64_t *result)
381{
382 return do_strtosz(nptr, end, 'B', 1024, result);
383}
384
385int qemu_strtosz_MiB(const char *nptr, const char **end, uint64_t *result)
386{
387 return do_strtosz(nptr, end, 'M', 1024, result);
388}
389
390int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result)
391{
392 return do_strtosz(nptr, end, 'B', 1000, result);
393}
394
395
396
397
398static int check_strtox_error(const char *nptr, char *ep,
399 const char **endptr, bool check_zero,
400 int libc_errno)
401{
402 assert(ep >= nptr);
403
404
405 if (check_zero && ep == nptr && libc_errno == 0) {
406 char *tmp;
407
408 errno = 0;
409 if (strtol(nptr, &tmp, 10) == 0 && errno == 0 &&
410 (*tmp == 'x' || *tmp == 'X')) {
411 ep = tmp;
412 }
413 }
414
415 if (endptr) {
416 *endptr = ep;
417 }
418
419
420 if (libc_errno == 0 && ep == nptr) {
421 return -EINVAL;
422 }
423
424
425 if (!endptr && *ep) {
426 return -EINVAL;
427 }
428
429 return -libc_errno;
430}
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456int qemu_strtoi(const char *nptr, const char **endptr, int base,
457 int *result)
458{
459 char *ep;
460 long long lresult;
461
462 assert((unsigned) base <= 36 && base != 1);
463 if (!nptr) {
464 if (endptr) {
465 *endptr = nptr;
466 }
467 return -EINVAL;
468 }
469
470 errno = 0;
471 lresult = strtoll(nptr, &ep, base);
472 if (lresult < INT_MIN) {
473 *result = INT_MIN;
474 errno = ERANGE;
475 } else if (lresult > INT_MAX) {
476 *result = INT_MAX;
477 errno = ERANGE;
478 } else {
479 *result = lresult;
480 }
481 return check_strtox_error(nptr, ep, endptr, lresult == 0, errno);
482}
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509int qemu_strtoui(const char *nptr, const char **endptr, int base,
510 unsigned int *result)
511{
512 char *ep;
513 long long lresult;
514
515 assert((unsigned) base <= 36 && base != 1);
516 if (!nptr) {
517 if (endptr) {
518 *endptr = nptr;
519 }
520 return -EINVAL;
521 }
522
523 errno = 0;
524 lresult = strtoull(nptr, &ep, base);
525
526
527 if (errno == ERANGE) {
528 *result = -1;
529 } else {
530 if (lresult > UINT_MAX) {
531 *result = UINT_MAX;
532 errno = ERANGE;
533 } else if (lresult < INT_MIN) {
534 *result = UINT_MAX;
535 errno = ERANGE;
536 } else {
537 *result = lresult;
538 }
539 }
540 return check_strtox_error(nptr, ep, endptr, lresult == 0, errno);
541}
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567int qemu_strtol(const char *nptr, const char **endptr, int base,
568 long *result)
569{
570 char *ep;
571
572 assert((unsigned) base <= 36 && base != 1);
573 if (!nptr) {
574 if (endptr) {
575 *endptr = nptr;
576 }
577 return -EINVAL;
578 }
579
580 errno = 0;
581 *result = strtol(nptr, &ep, base);
582 return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
583}
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610int qemu_strtoul(const char *nptr, const char **endptr, int base,
611 unsigned long *result)
612{
613 char *ep;
614
615 assert((unsigned) base <= 36 && base != 1);
616 if (!nptr) {
617 if (endptr) {
618 *endptr = nptr;
619 }
620 return -EINVAL;
621 }
622
623 errno = 0;
624 *result = strtoul(nptr, &ep, base);
625
626 if (errno == ERANGE) {
627 *result = -1;
628 }
629 return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
630}
631
632
633
634
635
636
637
638int qemu_strtoi64(const char *nptr, const char **endptr, int base,
639 int64_t *result)
640{
641 char *ep;
642
643 assert((unsigned) base <= 36 && base != 1);
644 if (!nptr) {
645 if (endptr) {
646 *endptr = nptr;
647 }
648 return -EINVAL;
649 }
650
651
652 QEMU_BUILD_BUG_ON(sizeof(int64_t) != sizeof(long long));
653 errno = 0;
654 *result = strtoll(nptr, &ep, base);
655 return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
656}
657
658
659
660
661
662
663int qemu_strtou64(const char *nptr, const char **endptr, int base,
664 uint64_t *result)
665{
666 char *ep;
667
668 assert((unsigned) base <= 36 && base != 1);
669 if (!nptr) {
670 if (endptr) {
671 *endptr = nptr;
672 }
673 return -EINVAL;
674 }
675
676
677 QEMU_BUILD_BUG_ON(sizeof(uint64_t) != sizeof(unsigned long long));
678 errno = 0;
679 *result = strtoull(nptr, &ep, base);
680
681 if (errno == ERANGE) {
682 *result = -1;
683 }
684 return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
685}
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711int qemu_strtod(const char *nptr, const char **endptr, double *result)
712{
713 char *ep;
714
715 if (!nptr) {
716 if (endptr) {
717 *endptr = nptr;
718 }
719 return -EINVAL;
720 }
721
722 errno = 0;
723 *result = strtod(nptr, &ep);
724 return check_strtox_error(nptr, ep, endptr, false, errno);
725}
726
727
728
729
730
731
732
733int qemu_strtod_finite(const char *nptr, const char **endptr, double *result)
734{
735 double tmp;
736 int ret;
737
738 ret = qemu_strtod(nptr, endptr, &tmp);
739 if (!ret && !isfinite(tmp)) {
740 if (endptr) {
741 *endptr = nptr;
742 }
743 ret = -EINVAL;
744 }
745
746 if (ret != -EINVAL) {
747 *result = tmp;
748 }
749 return ret;
750}
751
752
753
754
755
756#ifndef HAVE_STRCHRNUL
757const char *qemu_strchrnul(const char *s, int c)
758{
759 const char *e = strchr(s, c);
760 if (!e) {
761 e = s + strlen(s);
762 }
763 return e;
764}
765#endif
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795int parse_uint(const char *s, unsigned long long *value, char **endptr,
796 int base)
797{
798 int r = 0;
799 char *endp = (char *)s;
800 unsigned long long val = 0;
801
802 assert((unsigned) base <= 36 && base != 1);
803 if (!s) {
804 r = -EINVAL;
805 goto out;
806 }
807
808 errno = 0;
809 val = strtoull(s, &endp, base);
810 if (errno) {
811 r = -errno;
812 goto out;
813 }
814
815 if (endp == s) {
816 r = -EINVAL;
817 goto out;
818 }
819
820
821 while (qemu_isspace(*s)) {
822 s++;
823 }
824 if (*s == '-') {
825 val = 0;
826 r = -ERANGE;
827 goto out;
828 }
829
830out:
831 *value = val;
832 *endptr = endp;
833 return r;
834}
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850int parse_uint_full(const char *s, unsigned long long *value, int base)
851{
852 char *endp;
853 int r;
854
855 r = parse_uint(s, value, &endp, base);
856 if (r < 0) {
857 return r;
858 }
859 if (*endp) {
860 *value = 0;
861 return -EINVAL;
862 }
863
864 return 0;
865}
866
867int qemu_parse_fd(const char *param)
868{
869 long fd;
870 char *endptr;
871
872 errno = 0;
873 fd = strtol(param, &endptr, 10);
874 if (param == endptr ||
875 errno != 0 ||
876 *endptr != '\0' ||
877 fd < 0 ||
878 fd > INT_MAX ) {
879 return -1;
880 }
881 return fd;
882}
883
884
885
886
887
888int uleb128_encode_small(uint8_t *out, uint32_t n)
889{
890 g_assert(n <= 0x3fff);
891 if (n < 0x80) {
892 *out = n;
893 return 1;
894 } else {
895 *out++ = (n & 0x7f) | 0x80;
896 *out = n >> 7;
897 return 2;
898 }
899}
900
901int uleb128_decode_small(const uint8_t *in, uint32_t *n)
902{
903 if (!(*in & 0x80)) {
904 *n = *in;
905 return 1;
906 } else {
907 *n = *in++ & 0x7f;
908
909 if (*in & 0x80) {
910 return -1;
911 }
912 *n |= *in << 7;
913 return 2;
914 }
915}
916
917
918
919
920int parse_debug_env(const char *name, int max, int initial)
921{
922 char *debug_env = getenv(name);
923 char *inv = NULL;
924 long debug;
925
926 if (!debug_env) {
927 return initial;
928 }
929 errno = 0;
930 debug = strtol(debug_env, &inv, 10);
931 if (inv == debug_env) {
932 return initial;
933 }
934 if (debug < 0 || debug > max || errno != 0) {
935 warn_report("%s not in [0, %d]", name, max);
936 return initial;
937 }
938 return debug;
939}
940
941
942
943
944const char *qemu_ether_ntoa(const MACAddr *mac)
945{
946 static char ret[18];
947
948 snprintf(ret, sizeof(ret), "%02x:%02x:%02x:%02x:%02x:%02x",
949 mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5]);
950
951 return ret;
952}
953
954
955
956
957
958
959
960char *size_to_str(uint64_t val)
961{
962 static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
963 uint64_t div;
964 int i;
965
966
967
968
969
970
971
972 frexp(val / (1000.0 / 1024.0), &i);
973 i = (i - 1) / 10;
974 div = 1ULL << (i * 10);
975
976 return g_strdup_printf("%0.3g %sB", (double)val / div, suffixes[i]);
977}
978
979char *freq_to_str(uint64_t freq_hz)
980{
981 static const char *const suffixes[] = { "", "K", "M", "G", "T", "P", "E" };
982 double freq = freq_hz;
983 size_t idx = 0;
984
985 while (freq >= 1000.0) {
986 freq /= 1000.0;
987 idx++;
988 }
989 assert(idx < ARRAY_SIZE(suffixes));
990
991 return g_strdup_printf("%0.3g %sHz", freq, suffixes[idx]);
992}
993
994int qemu_pstrcmp0(const char **str1, const char **str2)
995{
996 return g_strcmp0(*str1, *str2);
997}
998
999static inline bool starts_with_prefix(const char *dir)
1000{
1001 size_t prefix_len = strlen(CONFIG_PREFIX);
1002 return !memcmp(dir, CONFIG_PREFIX, prefix_len) &&
1003 (!dir[prefix_len] || G_IS_DIR_SEPARATOR(dir[prefix_len]));
1004}
1005
1006
1007static inline const char *next_component(const char *dir, int *p_len)
1008{
1009 int len;
1010 while ((*dir && G_IS_DIR_SEPARATOR(*dir)) ||
1011 (*dir == '.' && (G_IS_DIR_SEPARATOR(dir[1]) || dir[1] == '\0'))) {
1012 dir++;
1013 }
1014 len = 0;
1015 while (dir[len] && !G_IS_DIR_SEPARATOR(dir[len])) {
1016 len++;
1017 }
1018 *p_len = len;
1019 return dir;
1020}
1021
1022char *get_relocated_path(const char *dir)
1023{
1024 size_t prefix_len = strlen(CONFIG_PREFIX);
1025 const char *bindir = CONFIG_BINDIR;
1026 const char *exec_dir = qemu_get_exec_dir();
1027 GString *result;
1028 int len_dir, len_bindir;
1029
1030
1031 assert(exec_dir[0]);
1032 if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
1033 return g_strdup(dir);
1034 }
1035
1036 result = g_string_new(exec_dir);
1037
1038
1039 len_dir = len_bindir = prefix_len;
1040 do {
1041 dir += len_dir;
1042 bindir += len_bindir;
1043 dir = next_component(dir, &len_dir);
1044 bindir = next_component(bindir, &len_bindir);
1045 } while (len_dir && len_dir == len_bindir && !memcmp(dir, bindir, len_dir));
1046
1047
1048 while (len_bindir) {
1049 bindir += len_bindir;
1050 g_string_append(result, "/..");
1051 bindir = next_component(bindir, &len_bindir);
1052 }
1053
1054 if (*dir) {
1055 assert(G_IS_DIR_SEPARATOR(dir[-1]));
1056 g_string_append(result, dir - 1);
1057 }
1058 return g_string_free(result, false);
1059}
1060