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, const char **end,
210 const char default_suffix, int64_t unit,
211 uint64_t *result)
212{
213 int retval;
214 const char *endptr;
215 unsigned char c;
216 int mul_required = 0;
217 double val, mul, integral, fraction;
218
219 retval = qemu_strtod_finite(nptr, &endptr, &val);
220 if (retval) {
221 goto out;
222 }
223 fraction = modf(val, &integral);
224 if (fraction != 0) {
225 mul_required = 1;
226 }
227 c = *endptr;
228 mul = suffix_mul(c, unit);
229 if (mul >= 0) {
230 endptr++;
231 } else {
232 mul = suffix_mul(default_suffix, unit);
233 assert(mul >= 0);
234 }
235 if (mul == 1 && mul_required) {
236 retval = -EINVAL;
237 goto out;
238 }
239
240
241
242
243 if ((val * mul >= 0xfffffffffffffc00) || val < 0) {
244 retval = -ERANGE;
245 goto out;
246 }
247 *result = val * mul;
248 retval = 0;
249
250out:
251 if (end) {
252 *end = endptr;
253 } else if (*endptr) {
254 retval = -EINVAL;
255 }
256
257 return retval;
258}
259
260int qemu_strtosz(const char *nptr, const char **end, uint64_t *result)
261{
262 return do_strtosz(nptr, end, 'B', 1024, result);
263}
264
265int qemu_strtosz_MiB(const char *nptr, const char **end, uint64_t *result)
266{
267 return do_strtosz(nptr, end, 'M', 1024, result);
268}
269
270int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result)
271{
272 return do_strtosz(nptr, end, 'B', 1000, result);
273}
274
275
276
277
278static int check_strtox_error(const char *nptr, char *ep,
279 const char **endptr, int libc_errno)
280{
281 assert(ep >= nptr);
282 if (endptr) {
283 *endptr = ep;
284 }
285
286
287 if (libc_errno == 0 && ep == nptr) {
288 return -EINVAL;
289 }
290
291
292 if (!endptr && *ep) {
293 return -EINVAL;
294 }
295
296 return -libc_errno;
297}
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
323int qemu_strtoi(const char *nptr, const char **endptr, int base,
324 int *result)
325{
326 char *ep;
327 long long lresult;
328
329 assert((unsigned) base <= 36 && base != 1);
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 assert((unsigned) base <= 36 && base != 1);
383 if (!nptr) {
384 if (endptr) {
385 *endptr = nptr;
386 }
387 return -EINVAL;
388 }
389
390 errno = 0;
391 lresult = strtoull(nptr, &ep, base);
392
393
394 if (errno == ERANGE) {
395 *result = -1;
396 } else {
397 if (lresult > UINT_MAX) {
398 *result = UINT_MAX;
399 errno = ERANGE;
400 } else if (lresult < INT_MIN) {
401 *result = UINT_MAX;
402 errno = ERANGE;
403 } else {
404 *result = lresult;
405 }
406 }
407 return check_strtox_error(nptr, ep, endptr, errno);
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
433
434int qemu_strtol(const char *nptr, const char **endptr, int base,
435 long *result)
436{
437 char *ep;
438
439 assert((unsigned) base <= 36 && base != 1);
440 if (!nptr) {
441 if (endptr) {
442 *endptr = nptr;
443 }
444 return -EINVAL;
445 }
446
447 errno = 0;
448 *result = strtol(nptr, &ep, base);
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
476
477int qemu_strtoul(const char *nptr, const char **endptr, int base,
478 unsigned long *result)
479{
480 char *ep;
481
482 assert((unsigned) base <= 36 && base != 1);
483 if (!nptr) {
484 if (endptr) {
485 *endptr = nptr;
486 }
487 return -EINVAL;
488 }
489
490 errno = 0;
491 *result = strtoul(nptr, &ep, base);
492
493 if (errno == ERANGE) {
494 *result = -1;
495 }
496 return check_strtox_error(nptr, ep, endptr, errno);
497}
498
499
500
501
502
503
504
505int qemu_strtoi64(const char *nptr, const char **endptr, int base,
506 int64_t *result)
507{
508 char *ep;
509
510 assert((unsigned) base <= 36 && base != 1);
511 if (!nptr) {
512 if (endptr) {
513 *endptr = nptr;
514 }
515 return -EINVAL;
516 }
517
518 errno = 0;
519
520 *result = strtoll(nptr, &ep, base);
521 return check_strtox_error(nptr, ep, endptr, errno);
522}
523
524
525
526
527
528
529int qemu_strtou64(const char *nptr, const char **endptr, int base,
530 uint64_t *result)
531{
532 char *ep;
533
534 assert((unsigned) base <= 36 && base != 1);
535 if (!nptr) {
536 if (endptr) {
537 *endptr = nptr;
538 }
539 return -EINVAL;
540 }
541
542 errno = 0;
543
544 *result = strtoull(nptr, &ep, base);
545
546 if (errno == ERANGE) {
547 *result = -1;
548 }
549 return check_strtox_error(nptr, ep, endptr, errno);
550}
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576int qemu_strtod(const char *nptr, const char **endptr, double *result)
577{
578 char *ep;
579
580 if (!nptr) {
581 if (endptr) {
582 *endptr = nptr;
583 }
584 return -EINVAL;
585 }
586
587 errno = 0;
588 *result = strtod(nptr, &ep);
589 return check_strtox_error(nptr, ep, endptr, errno);
590}
591
592
593
594
595
596
597
598int qemu_strtod_finite(const char *nptr, const char **endptr, double *result)
599{
600 double tmp;
601 int ret;
602
603 ret = qemu_strtod(nptr, endptr, &tmp);
604 if (!ret && !isfinite(tmp)) {
605 if (endptr) {
606 *endptr = nptr;
607 }
608 ret = -EINVAL;
609 }
610
611 if (ret != -EINVAL) {
612 *result = tmp;
613 }
614 return ret;
615}
616
617
618
619
620
621#ifndef HAVE_STRCHRNUL
622const char *qemu_strchrnul(const char *s, int c)
623{
624 const char *e = strchr(s, c);
625 if (!e) {
626 e = s + strlen(s);
627 }
628 return e;
629}
630#endif
631
632
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
660int parse_uint(const char *s, unsigned long long *value, char **endptr,
661 int base)
662{
663 int r = 0;
664 char *endp = (char *)s;
665 unsigned long long val = 0;
666
667 assert((unsigned) base <= 36 && base != 1);
668 if (!s) {
669 r = -EINVAL;
670 goto out;
671 }
672
673 errno = 0;
674 val = strtoull(s, &endp, base);
675 if (errno) {
676 r = -errno;
677 goto out;
678 }
679
680 if (endp == s) {
681 r = -EINVAL;
682 goto out;
683 }
684
685
686 while (isspace((unsigned char)*s)) {
687 s++;
688 }
689 if (*s == '-') {
690 val = 0;
691 r = -ERANGE;
692 goto out;
693 }
694
695out:
696 *value = val;
697 *endptr = endp;
698 return r;
699}
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715int parse_uint_full(const char *s, unsigned long long *value, int base)
716{
717 char *endp;
718 int r;
719
720 r = parse_uint(s, value, &endp, base);
721 if (r < 0) {
722 return r;
723 }
724 if (*endp) {
725 *value = 0;
726 return -EINVAL;
727 }
728
729 return 0;
730}
731
732int qemu_parse_fd(const char *param)
733{
734 long fd;
735 char *endptr;
736
737 errno = 0;
738 fd = strtol(param, &endptr, 10);
739 if (param == endptr ||
740 errno != 0 ||
741 *endptr != '\0' ||
742 fd < 0 ||
743 fd > INT_MAX ) {
744 return -1;
745 }
746 return fd;
747}
748
749
750
751
752
753int uleb128_encode_small(uint8_t *out, uint32_t n)
754{
755 g_assert(n <= 0x3fff);
756 if (n < 0x80) {
757 *out++ = n;
758 return 1;
759 } else {
760 *out++ = (n & 0x7f) | 0x80;
761 *out++ = n >> 7;
762 return 2;
763 }
764}
765
766int uleb128_decode_small(const uint8_t *in, uint32_t *n)
767{
768 if (!(*in & 0x80)) {
769 *n = *in++;
770 return 1;
771 } else {
772 *n = *in++ & 0x7f;
773
774 if (*in & 0x80) {
775 return -1;
776 }
777 *n |= *in++ << 7;
778 return 2;
779 }
780}
781
782
783
784
785int parse_debug_env(const char *name, int max, int initial)
786{
787 char *debug_env = getenv(name);
788 char *inv = NULL;
789 long debug;
790
791 if (!debug_env) {
792 return initial;
793 }
794 errno = 0;
795 debug = strtol(debug_env, &inv, 10);
796 if (inv == debug_env) {
797 return initial;
798 }
799 if (debug < 0 || debug > max || errno != 0) {
800 warn_report("%s not in [0, %d]", name, max);
801 return initial;
802 }
803 return debug;
804}
805
806
807
808
809const char *qemu_ether_ntoa(const MACAddr *mac)
810{
811 static char ret[18];
812
813 snprintf(ret, sizeof(ret), "%02x:%02x:%02x:%02x:%02x:%02x",
814 mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5]);
815
816 return ret;
817}
818
819
820
821
822
823
824
825char *size_to_str(uint64_t val)
826{
827 static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
828 unsigned long div;
829 int i;
830
831
832
833
834
835
836
837 frexp(val / (1000.0 / 1024.0), &i);
838 i = (i - 1) / 10;
839 div = 1ULL << (i * 10);
840
841 return g_strdup_printf("%0.3g %sB", (double)val / div, suffixes[i]);
842}
843
844int qemu_pstrcmp0(const char **str1, const char **str2)
845{
846 return g_strcmp0(*str1, *str2);
847}
848