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, char **end,
210 const char default_suffix, int64_t unit,
211 uint64_t *result)
212{
213 int retval;
214 char *endptr;
215 unsigned char c;
216 int mul_required = 0;
217 double val, mul, integral, fraction;
218
219 errno = 0;
220 val = strtod(nptr, &endptr);
221 if (isnan(val) || endptr == nptr || errno != 0) {
222 retval = -EINVAL;
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, char **end, uint64_t *result)
263{
264 return do_strtosz(nptr, end, 'B', 1024, result);
265}
266
267int qemu_strtosz_MiB(const char *nptr, char **end, uint64_t *result)
268{
269 return do_strtosz(nptr, end, 'M', 1024, result);
270}
271
272int qemu_strtosz_metric(const char *nptr, 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 if (endptr) {
284 *endptr = ep;
285 }
286
287
288 if (libc_errno == 0 && ep == nptr) {
289 return -EINVAL;
290 }
291
292
293 if (!endptr && *ep) {
294 return -EINVAL;
295 }
296
297 return -libc_errno;
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
323
324int qemu_strtoi(const char *nptr, const char **endptr, int base,
325 int *result)
326{
327 char *ep;
328 long long lresult;
329
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 if (!nptr) {
383 if (endptr) {
384 *endptr = nptr;
385 }
386 return -EINVAL;
387 }
388
389 errno = 0;
390 lresult = strtoull(nptr, &ep, base);
391
392
393 if (errno == ERANGE) {
394 *result = -1;
395 } else {
396 if (lresult > UINT_MAX) {
397 *result = UINT_MAX;
398 errno = ERANGE;
399 } else if (lresult < INT_MIN) {
400 *result = UINT_MAX;
401 errno = ERANGE;
402 } else {
403 *result = lresult;
404 }
405 }
406 return check_strtox_error(nptr, ep, endptr, errno);
407}
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
433int qemu_strtol(const char *nptr, const char **endptr, int base,
434 long *result)
435{
436 char *ep;
437
438 if (!nptr) {
439 if (endptr) {
440 *endptr = nptr;
441 }
442 return -EINVAL;
443 }
444
445 errno = 0;
446 *result = strtol(nptr, &ep, base);
447 return check_strtox_error(nptr, ep, endptr, errno);
448}
449
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
475int qemu_strtoul(const char *nptr, const char **endptr, int base,
476 unsigned long *result)
477{
478 char *ep;
479
480 if (!nptr) {
481 if (endptr) {
482 *endptr = nptr;
483 }
484 return -EINVAL;
485 }
486
487 errno = 0;
488 *result = strtoul(nptr, &ep, base);
489
490 if (errno == ERANGE) {
491 *result = -1;
492 }
493 return check_strtox_error(nptr, ep, endptr, errno);
494}
495
496
497
498
499
500
501
502int qemu_strtoi64(const char *nptr, const char **endptr, int base,
503 int64_t *result)
504{
505 char *ep;
506
507 if (!nptr) {
508 if (endptr) {
509 *endptr = nptr;
510 }
511 return -EINVAL;
512 }
513
514 errno = 0;
515
516 *result = strtoll(nptr, &ep, base);
517 return check_strtox_error(nptr, ep, endptr, errno);
518}
519
520
521
522
523
524
525int qemu_strtou64(const char *nptr, const char **endptr, int base,
526 uint64_t *result)
527{
528 char *ep;
529
530 if (!nptr) {
531 if (endptr) {
532 *endptr = nptr;
533 }
534 return -EINVAL;
535 }
536
537 errno = 0;
538
539 *result = strtoull(nptr, &ep, base);
540
541 if (errno == ERANGE) {
542 *result = -1;
543 }
544 return check_strtox_error(nptr, ep, endptr, errno);
545}
546
547
548
549
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
575int parse_uint(const char *s, unsigned long long *value, char **endptr,
576 int base)
577{
578 int r = 0;
579 char *endp = (char *)s;
580 unsigned long long val = 0;
581
582 if (!s) {
583 r = -EINVAL;
584 goto out;
585 }
586
587 errno = 0;
588 val = strtoull(s, &endp, base);
589 if (errno) {
590 r = -errno;
591 goto out;
592 }
593
594 if (endp == s) {
595 r = -EINVAL;
596 goto out;
597 }
598
599
600 while (isspace((unsigned char)*s)) {
601 s++;
602 }
603 if (*s == '-') {
604 val = 0;
605 r = -ERANGE;
606 goto out;
607 }
608
609out:
610 *value = val;
611 *endptr = endp;
612 return r;
613}
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629int parse_uint_full(const char *s, unsigned long long *value, int base)
630{
631 char *endp;
632 int r;
633
634 r = parse_uint(s, value, &endp, base);
635 if (r < 0) {
636 return r;
637 }
638 if (*endp) {
639 *value = 0;
640 return -EINVAL;
641 }
642
643 return 0;
644}
645
646int qemu_parse_fd(const char *param)
647{
648 long fd;
649 char *endptr;
650
651 errno = 0;
652 fd = strtol(param, &endptr, 10);
653 if (param == endptr ||
654 errno != 0 ||
655 *endptr != '\0' ||
656 fd < 0 ||
657 fd > INT_MAX ) {
658 return -1;
659 }
660 return fd;
661}
662
663
664
665
666
667int uleb128_encode_small(uint8_t *out, uint32_t n)
668{
669 g_assert(n <= 0x3fff);
670 if (n < 0x80) {
671 *out++ = n;
672 return 1;
673 } else {
674 *out++ = (n & 0x7f) | 0x80;
675 *out++ = n >> 7;
676 return 2;
677 }
678}
679
680int uleb128_decode_small(const uint8_t *in, uint32_t *n)
681{
682 if (!(*in & 0x80)) {
683 *n = *in++;
684 return 1;
685 } else {
686 *n = *in++ & 0x7f;
687
688 if (*in & 0x80) {
689 return -1;
690 }
691 *n |= *in++ << 7;
692 return 2;
693 }
694}
695
696
697
698
699int parse_debug_env(const char *name, int max, int initial)
700{
701 char *debug_env = getenv(name);
702 char *inv = NULL;
703 long debug;
704
705 if (!debug_env) {
706 return initial;
707 }
708 errno = 0;
709 debug = strtol(debug_env, &inv, 10);
710 if (inv == debug_env) {
711 return initial;
712 }
713 if (debug < 0 || debug > max || errno != 0) {
714 warn_report("%s not in [0, %d]", name, max);
715 return initial;
716 }
717 return debug;
718}
719
720
721
722
723const char *qemu_ether_ntoa(const MACAddr *mac)
724{
725 static char ret[18];
726
727 snprintf(ret, sizeof(ret), "%02x:%02x:%02x:%02x:%02x:%02x",
728 mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5]);
729
730 return ret;
731}
732
733
734
735
736
737
738
739char *size_to_str(uint64_t val)
740{
741 static const char *suffixes[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
742 unsigned long div;
743 int i;
744
745
746
747
748
749
750
751 frexp(val / (1000.0 / 1024.0), &i);
752 i = (i - 1) / 10;
753 div = 1ULL << (i * 10);
754
755 return g_strdup_printf("%0.3g %sB", (double)val / div, suffixes[i]);
756}
757