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
249static int do_strtosz(const char *nptr, const char **end,
250 const char default_suffix, int64_t unit,
251 uint64_t *result)
252{
253 int retval;
254 const char *endptr;
255 unsigned char c;
256 int mul_required = 0;
257 double val, mul, integral, fraction;
258
259 retval = qemu_strtod_finite(nptr, &endptr, &val);
260 if (retval) {
261 goto out;
262 }
263 fraction = modf(val, &integral);
264 if (fraction != 0) {
265 mul_required = 1;
266 }
267 c = *endptr;
268 mul = suffix_mul(c, unit);
269 if (mul >= 0) {
270 endptr++;
271 } else {
272 mul = suffix_mul(default_suffix, unit);
273 assert(mul >= 0);
274 }
275 if (mul == 1 && mul_required) {
276 retval = -EINVAL;
277 goto out;
278 }
279
280
281
282
283
284
285 if ((val * mul > nextafter(0x1p64, 0)) || val < 0) {
286 retval = -ERANGE;
287 goto out;
288 }
289 *result = val * mul;
290 retval = 0;
291
292out:
293 if (end) {
294 *end = endptr;
295 } else if (*endptr) {
296 retval = -EINVAL;
297 }
298
299 return retval;
300}
301
302int qemu_strtosz(const char *nptr, const char **end, uint64_t *result)
303{
304 return do_strtosz(nptr, end, 'B', 1024, result);
305}
306
307int qemu_strtosz_MiB(const char *nptr, const char **end, uint64_t *result)
308{
309 return do_strtosz(nptr, end, 'M', 1024, result);
310}
311
312int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result)
313{
314 return do_strtosz(nptr, end, 'B', 1000, result);
315}
316
317
318
319
320static int check_strtox_error(const char *nptr, char *ep,
321 const char **endptr, int libc_errno)
322{
323 assert(ep >= nptr);
324 if (endptr) {
325 *endptr = ep;
326 }
327
328
329 if (libc_errno == 0 && ep == nptr) {
330 return -EINVAL;
331 }
332
333
334 if (!endptr && *ep) {
335 return -EINVAL;
336 }
337
338 return -libc_errno;
339}
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365int qemu_strtoi(const char *nptr, const char **endptr, int base,
366 int *result)
367{
368 char *ep;
369 long long lresult;
370
371 assert((unsigned) base <= 36 && base != 1);
372 if (!nptr) {
373 if (endptr) {
374 *endptr = nptr;
375 }
376 return -EINVAL;
377 }
378
379 errno = 0;
380 lresult = strtoll(nptr, &ep, base);
381 if (lresult < INT_MIN) {
382 *result = INT_MIN;
383 errno = ERANGE;
384 } else if (lresult > INT_MAX) {
385 *result = INT_MAX;
386 errno = ERANGE;
387 } else {
388 *result = lresult;
389 }
390 return check_strtox_error(nptr, ep, endptr, errno);
391}
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418int qemu_strtoui(const char *nptr, const char **endptr, int base,
419 unsigned int *result)
420{
421 char *ep;
422 long long lresult;
423
424 assert((unsigned) base <= 36 && base != 1);
425 if (!nptr) {
426 if (endptr) {
427 *endptr = nptr;
428 }
429 return -EINVAL;
430 }
431
432 errno = 0;
433 lresult = strtoull(nptr, &ep, base);
434
435
436 if (errno == ERANGE) {
437 *result = -1;
438 } else {
439 if (lresult > UINT_MAX) {
440 *result = UINT_MAX;
441 errno = ERANGE;
442 } else if (lresult < INT_MIN) {
443 *result = UINT_MAX;
444 errno = ERANGE;
445 } else {
446 *result = lresult;
447 }
448 }
449 return check_strtox_error(nptr, ep, endptr, errno);
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
475
476int qemu_strtol(const char *nptr, const char **endptr, int base,
477 long *result)
478{
479 char *ep;
480
481 assert((unsigned) base <= 36 && base != 1);
482 if (!nptr) {
483 if (endptr) {
484 *endptr = nptr;
485 }
486 return -EINVAL;
487 }
488
489 errno = 0;
490 *result = strtol(nptr, &ep, base);
491 return check_strtox_error(nptr, ep, endptr, errno);
492}
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519int qemu_strtoul(const char *nptr, const char **endptr, int base,
520 unsigned long *result)
521{
522 char *ep;
523
524 assert((unsigned) base <= 36 && base != 1);
525 if (!nptr) {
526 if (endptr) {
527 *endptr = nptr;
528 }
529 return -EINVAL;
530 }
531
532 errno = 0;
533 *result = strtoul(nptr, &ep, base);
534
535 if (errno == ERANGE) {
536 *result = -1;
537 }
538 return check_strtox_error(nptr, ep, endptr, errno);
539}
540
541
542
543
544
545
546
547int qemu_strtoi64(const char *nptr, const char **endptr, int base,
548 int64_t *result)
549{
550 char *ep;
551
552 assert((unsigned) base <= 36 && base != 1);
553 if (!nptr) {
554 if (endptr) {
555 *endptr = nptr;
556 }
557 return -EINVAL;
558 }
559
560
561 QEMU_BUILD_BUG_ON(sizeof(int64_t) != sizeof(long long));
562 errno = 0;
563 *result = strtoll(nptr, &ep, base);
564 return check_strtox_error(nptr, ep, endptr, errno);
565}
566
567
568
569
570
571
572int qemu_strtou64(const char *nptr, const char **endptr, int base,
573 uint64_t *result)
574{
575 char *ep;
576
577 assert((unsigned) base <= 36 && base != 1);
578 if (!nptr) {
579 if (endptr) {
580 *endptr = nptr;
581 }
582 return -EINVAL;
583 }
584
585
586 QEMU_BUILD_BUG_ON(sizeof(uint64_t) != sizeof(unsigned long long));
587 errno = 0;
588 *result = strtoull(nptr, &ep, base);
589
590 if (errno == ERANGE) {
591 *result = -1;
592 }
593 return check_strtox_error(nptr, ep, endptr, errno);
594}
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620int qemu_strtod(const char *nptr, const char **endptr, double *result)
621{
622 char *ep;
623
624 if (!nptr) {
625 if (endptr) {
626 *endptr = nptr;
627 }
628 return -EINVAL;
629 }
630
631 errno = 0;
632 *result = strtod(nptr, &ep);
633 return check_strtox_error(nptr, ep, endptr, errno);
634}
635
636
637
638
639
640
641
642int qemu_strtod_finite(const char *nptr, const char **endptr, double *result)
643{
644 double tmp;
645 int ret;
646
647 ret = qemu_strtod(nptr, endptr, &tmp);
648 if (!ret && !isfinite(tmp)) {
649 if (endptr) {
650 *endptr = nptr;
651 }
652 ret = -EINVAL;
653 }
654
655 if (ret != -EINVAL) {
656 *result = tmp;
657 }
658 return ret;
659}
660
661
662
663
664
665#ifndef HAVE_STRCHRNUL
666const char *qemu_strchrnul(const char *s, int c)
667{
668 const char *e = strchr(s, c);
669 if (!e) {
670 e = s + strlen(s);
671 }
672 return e;
673}
674#endif
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704int parse_uint(const char *s, unsigned long long *value, char **endptr,
705 int base)
706{
707 int r = 0;
708 char *endp = (char *)s;
709 unsigned long long val = 0;
710
711 assert((unsigned) base <= 36 && base != 1);
712 if (!s) {
713 r = -EINVAL;
714 goto out;
715 }
716
717 errno = 0;
718 val = strtoull(s, &endp, base);
719 if (errno) {
720 r = -errno;
721 goto out;
722 }
723
724 if (endp == s) {
725 r = -EINVAL;
726 goto out;
727 }
728
729
730 while (qemu_isspace(*s)) {
731 s++;
732 }
733 if (*s == '-') {
734 val = 0;
735 r = -ERANGE;
736 goto out;
737 }
738
739out:
740 *value = val;
741 *endptr = endp;
742 return r;
743}
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759int parse_uint_full(const char *s, unsigned long long *value, int base)
760{
761 char *endp;
762 int r;
763
764 r = parse_uint(s, value, &endp, base);
765 if (r < 0) {
766 return r;
767 }
768 if (*endp) {
769 *value = 0;
770 return -EINVAL;
771 }
772
773 return 0;
774}
775
776int qemu_parse_fd(const char *param)
777{
778 long fd;
779 char *endptr;
780
781 errno = 0;
782 fd = strtol(param, &endptr, 10);
783 if (param == endptr ||
784 errno != 0 ||
785 *endptr != '\0' ||
786 fd < 0 ||
787 fd > INT_MAX ) {
788 return -1;
789 }
790 return fd;
791}
792
793
794
795
796
797int uleb128_encode_small(uint8_t *out, uint32_t n)
798{
799 g_assert(n <= 0x3fff);
800 if (n < 0x80) {
801 *out = n;
802 return 1;
803 } else {
804 *out++ = (n & 0x7f) | 0x80;
805 *out = n >> 7;
806 return 2;
807 }
808}
809
810int uleb128_decode_small(const uint8_t *in, uint32_t *n)
811{
812 if (!(*in & 0x80)) {
813 *n = *in;
814 return 1;
815 } else {
816 *n = *in++ & 0x7f;
817
818 if (*in & 0x80) {
819 return -1;
820 }
821 *n |= *in << 7;
822 return 2;
823 }
824}
825
826
827
828
829int parse_debug_env(const char *name, int max, int initial)
830{
831 char *debug_env = getenv(name);
832 char *inv = NULL;
833 long debug;
834
835 if (!debug_env) {
836 return initial;
837 }
838 errno = 0;
839 debug = strtol(debug_env, &inv, 10);
840 if (inv == debug_env) {
841 return initial;
842 }
843 if (debug < 0 || debug > max || errno != 0) {
844 warn_report("%s not in [0, %d]", name, max);
845 return initial;
846 }
847 return debug;
848}
849
850
851
852
853const char *qemu_ether_ntoa(const MACAddr *mac)
854{
855 static char ret[18];
856
857 snprintf(ret, sizeof(ret), "%02x:%02x:%02x:%02x:%02x:%02x",
858 mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5]);
859
860 return ret;
861}
862
863
864
865
866
867
868
869char *size_to_str(uint64_t val)
870{
871 static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
872 uint64_t div;
873 int i;
874
875
876
877
878
879
880
881 frexp(val / (1000.0 / 1024.0), &i);
882 i = (i - 1) / 10;
883 div = 1ULL << (i * 10);
884
885 return g_strdup_printf("%0.3g %sB", (double)val / div, suffixes[i]);
886}
887
888char *freq_to_str(uint64_t freq_hz)
889{
890 static const char *const suffixes[] = { "", "K", "M", "G", "T", "P", "E" };
891 double freq = freq_hz;
892 size_t idx = 0;
893
894 while (freq >= 1000.0) {
895 freq /= 1000.0;
896 idx++;
897 }
898 assert(idx < ARRAY_SIZE(suffixes));
899
900 return g_strdup_printf("%0.3g %sHz", freq, suffixes[idx]);
901}
902
903int qemu_pstrcmp0(const char **str1, const char **str2)
904{
905 return g_strcmp0(*str1, *str2);
906}
907
908static inline bool starts_with_prefix(const char *dir)
909{
910 size_t prefix_len = strlen(CONFIG_PREFIX);
911 return !memcmp(dir, CONFIG_PREFIX, prefix_len) &&
912 (!dir[prefix_len] || G_IS_DIR_SEPARATOR(dir[prefix_len]));
913}
914
915
916static inline const char *next_component(const char *dir, int *p_len)
917{
918 int len;
919 while (*dir && G_IS_DIR_SEPARATOR(*dir)) {
920 dir++;
921 }
922 len = 0;
923 while (dir[len] && !G_IS_DIR_SEPARATOR(dir[len])) {
924 len++;
925 }
926 *p_len = len;
927 return dir;
928}
929
930char *get_relocated_path(const char *dir)
931{
932 size_t prefix_len = strlen(CONFIG_PREFIX);
933 const char *bindir = CONFIG_BINDIR;
934 const char *exec_dir = qemu_get_exec_dir();
935 GString *result;
936 int len_dir, len_bindir;
937
938
939 assert(exec_dir[0]);
940 if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
941 return g_strdup(dir);
942 }
943
944 result = g_string_new(exec_dir);
945
946
947 len_dir = len_bindir = prefix_len;
948 do {
949 dir += len_dir;
950 bindir += len_bindir;
951 dir = next_component(dir, &len_dir);
952 bindir = next_component(bindir, &len_bindir);
953 } while (len_dir && len_dir == len_bindir && !memcmp(dir, bindir, len_dir));
954
955
956 while (len_bindir) {
957 bindir += len_bindir;
958 g_string_append(result, "/..");
959 bindir = next_component(bindir, &len_bindir);
960 }
961
962 if (*dir) {
963 assert(G_IS_DIR_SEPARATOR(dir[-1]));
964 g_string_append(result, dir - 1);
965 }
966 return result->str;
967}
968