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
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#ifndef _WIN32
165
166int fcntl_setfl(int fd, int flag)
167{
168 int flags;
169
170 flags = fcntl(fd, F_GETFL);
171 if (flags == -1)
172 return -errno;
173
174 if (fcntl(fd, F_SETFL, flags | flag) == -1)
175 return -errno;
176
177 return 0;
178}
179#endif
180
181static int64_t suffix_mul(char suffix, int64_t unit)
182{
183 switch (qemu_toupper(suffix)) {
184 case QEMU_STRTOSZ_DEFSUFFIX_B:
185 return 1;
186 case QEMU_STRTOSZ_DEFSUFFIX_KB:
187 return unit;
188 case QEMU_STRTOSZ_DEFSUFFIX_MB:
189 return unit * unit;
190 case QEMU_STRTOSZ_DEFSUFFIX_GB:
191 return unit * unit * unit;
192 case QEMU_STRTOSZ_DEFSUFFIX_TB:
193 return unit * unit * unit * unit;
194 case QEMU_STRTOSZ_DEFSUFFIX_PB:
195 return unit * unit * unit * unit * unit;
196 case QEMU_STRTOSZ_DEFSUFFIX_EB:
197 return unit * unit * unit * unit * unit * unit;
198 }
199 return -1;
200}
201
202
203
204
205
206
207
208int64_t qemu_strtosz_suffix_unit(const char *nptr, char **end,
209 const char default_suffix, int64_t unit)
210{
211 int64_t retval = -EINVAL;
212 char *endptr;
213 unsigned char c;
214 int mul_required = 0;
215 double val, mul, integral, fraction;
216
217 errno = 0;
218 val = strtod(nptr, &endptr);
219 if (isnan(val) || endptr == nptr || errno != 0) {
220 goto fail;
221 }
222 fraction = modf(val, &integral);
223 if (fraction != 0) {
224 mul_required = 1;
225 }
226 c = *endptr;
227 mul = suffix_mul(c, unit);
228 if (mul >= 0) {
229 endptr++;
230 } else {
231 mul = suffix_mul(default_suffix, unit);
232 assert(mul >= 0);
233 }
234 if (mul == 1 && mul_required) {
235 goto fail;
236 }
237 if ((val * mul >= INT64_MAX) || val < 0) {
238 retval = -ERANGE;
239 goto fail;
240 }
241 retval = val * mul;
242
243fail:
244 if (end) {
245 *end = endptr;
246 }
247
248 return retval;
249}
250
251int64_t qemu_strtosz_suffix(const char *nptr, char **end,
252 const char default_suffix)
253{
254 return qemu_strtosz_suffix_unit(nptr, end, default_suffix, 1024);
255}
256
257int64_t qemu_strtosz(const char *nptr, char **end)
258{
259 return qemu_strtosz_suffix(nptr, end, QEMU_STRTOSZ_DEFSUFFIX_MB);
260}
261
262
263
264
265static int check_strtox_error(const char *p, char *endptr, const char **next,
266 int err)
267{
268
269
270
271 if (err == 0 && endptr == p) {
272 err = EINVAL;
273 }
274 if (!next && *endptr) {
275 return -EINVAL;
276 }
277 if (next) {
278 *next = endptr;
279 }
280 return -err;
281}
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309int qemu_strtol(const char *nptr, const char **endptr, int base,
310 long *result)
311{
312 char *p;
313 int err = 0;
314 if (!nptr) {
315 if (endptr) {
316 *endptr = nptr;
317 }
318 err = -EINVAL;
319 } else {
320 errno = 0;
321 *result = strtol(nptr, &p, base);
322 err = check_strtox_error(nptr, p, endptr, errno);
323 }
324 return err;
325}
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340int qemu_strtoul(const char *nptr, const char **endptr, int base,
341 unsigned long *result)
342{
343 char *p;
344 int err = 0;
345 if (!nptr) {
346 if (endptr) {
347 *endptr = nptr;
348 }
349 err = -EINVAL;
350 } else {
351 errno = 0;
352 *result = strtoul(nptr, &p, base);
353
354 if (errno == ERANGE) {
355 *result = -1;
356 }
357 err = check_strtox_error(nptr, p, endptr, errno);
358 }
359 return err;
360}
361
362
363
364
365
366
367int qemu_strtoll(const char *nptr, const char **endptr, int base,
368 int64_t *result)
369{
370 char *p;
371 int err = 0;
372 if (!nptr) {
373 if (endptr) {
374 *endptr = nptr;
375 }
376 err = -EINVAL;
377 } else {
378 errno = 0;
379 *result = strtoll(nptr, &p, base);
380 err = check_strtox_error(nptr, p, endptr, errno);
381 }
382 return err;
383}
384
385
386
387
388
389
390int qemu_strtoull(const char *nptr, const char **endptr, int base,
391 uint64_t *result)
392{
393 char *p;
394 int err = 0;
395 if (!nptr) {
396 if (endptr) {
397 *endptr = nptr;
398 }
399 err = -EINVAL;
400 } else {
401 errno = 0;
402 *result = strtoull(nptr, &p, base);
403
404 if (errno == ERANGE) {
405 *result = -1;
406 }
407 err = check_strtox_error(nptr, p, endptr, errno);
408 }
409 return err;
410}
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440int parse_uint(const char *s, unsigned long long *value, char **endptr,
441 int base)
442{
443 int r = 0;
444 char *endp = (char *)s;
445 unsigned long long val = 0;
446
447 if (!s) {
448 r = -EINVAL;
449 goto out;
450 }
451
452 errno = 0;
453 val = strtoull(s, &endp, base);
454 if (errno) {
455 r = -errno;
456 goto out;
457 }
458
459 if (endp == s) {
460 r = -EINVAL;
461 goto out;
462 }
463
464
465 while (isspace((unsigned char)*s)) {
466 s++;
467 }
468 if (*s == '-') {
469 val = 0;
470 r = -ERANGE;
471 goto out;
472 }
473
474out:
475 *value = val;
476 *endptr = endp;
477 return r;
478}
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494int parse_uint_full(const char *s, unsigned long long *value, int base)
495{
496 char *endp;
497 int r;
498
499 r = parse_uint(s, value, &endp, base);
500 if (r < 0) {
501 return r;
502 }
503 if (*endp) {
504 *value = 0;
505 return -EINVAL;
506 }
507
508 return 0;
509}
510
511int qemu_parse_fd(const char *param)
512{
513 long fd;
514 char *endptr;
515
516 errno = 0;
517 fd = strtol(param, &endptr, 10);
518 if (param == endptr ||
519 errno != 0 ||
520 *endptr != '\0' ||
521 fd < 0 ||
522 fd > INT_MAX ) {
523 return -1;
524 }
525 return fd;
526}
527
528
529
530
531
532int uleb128_encode_small(uint8_t *out, uint32_t n)
533{
534 g_assert(n <= 0x3fff);
535 if (n < 0x80) {
536 *out++ = n;
537 return 1;
538 } else {
539 *out++ = (n & 0x7f) | 0x80;
540 *out++ = n >> 7;
541 return 2;
542 }
543}
544
545int uleb128_decode_small(const uint8_t *in, uint32_t *n)
546{
547 if (!(*in & 0x80)) {
548 *n = *in++;
549 return 1;
550 } else {
551 *n = *in++ & 0x7f;
552
553 if (*in & 0x80) {
554 return -1;
555 }
556 *n |= *in++ << 7;
557 return 2;
558 }
559}
560
561
562
563
564int parse_debug_env(const char *name, int max, int initial)
565{
566 char *debug_env = getenv(name);
567 char *inv = NULL;
568 long debug;
569
570 if (!debug_env) {
571 return initial;
572 }
573 errno = 0;
574 debug = strtol(debug_env, &inv, 10);
575 if (inv == debug_env) {
576 return initial;
577 }
578 if (debug < 0 || debug > max || errno != 0) {
579 fprintf(stderr, "warning: %s not in [0, %d]", name, max);
580 return initial;
581 }
582 return debug;
583}
584
585
586
587
588const char *qemu_ether_ntoa(const MACAddr *mac)
589{
590 static char ret[18];
591
592 snprintf(ret, sizeof(ret), "%02x:%02x:%02x:%02x:%02x:%02x",
593 mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5]);
594
595 return ret;
596}
597