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