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-common.h"
25#include "qemu/host-utils.h"
26#include <math.h>
27
28#include "qemu/sockets.h"
29#include "qemu/iov.h"
30
31void strpadcpy(char *buf, int buf_size, const char *str, char pad)
32{
33 int len = qemu_strnlen(str, buf_size);
34 memcpy(buf, str, len);
35 memset(buf + len, pad, buf_size - len);
36}
37
38void pstrcpy(char *buf, int buf_size, const char *str)
39{
40 int c;
41 char *q = buf;
42
43 if (buf_size <= 0)
44 return;
45
46 for(;;) {
47 c = *str++;
48 if (c == 0 || q >= buf + buf_size - 1)
49 break;
50 *q++ = c;
51 }
52 *q = '\0';
53}
54
55
56char *pstrcat(char *buf, int buf_size, const char *s)
57{
58 int len;
59 len = strlen(buf);
60 if (len < buf_size)
61 pstrcpy(buf + len, buf_size - len, s);
62 return buf;
63}
64
65int strstart(const char *str, const char *val, const char **ptr)
66{
67 const char *p, *q;
68 p = str;
69 q = val;
70 while (*q != '\0') {
71 if (*p != *q)
72 return 0;
73 p++;
74 q++;
75 }
76 if (ptr)
77 *ptr = p;
78 return 1;
79}
80
81int stristart(const char *str, const char *val, const char **ptr)
82{
83 const char *p, *q;
84 p = str;
85 q = val;
86 while (*q != '\0') {
87 if (qemu_toupper(*p) != qemu_toupper(*q))
88 return 0;
89 p++;
90 q++;
91 }
92 if (ptr)
93 *ptr = p;
94 return 1;
95}
96
97
98int qemu_strnlen(const char *s, int max_len)
99{
100 int i;
101
102 for(i = 0; i < max_len; i++) {
103 if (s[i] == '\0') {
104 break;
105 }
106 }
107 return i;
108}
109
110char *qemu_strsep(char **input, const char *delim)
111{
112 char *result = *input;
113 if (result != NULL) {
114 char *p;
115
116 for (p = result; *p != '\0'; p++) {
117 if (strchr(delim, *p)) {
118 break;
119 }
120 }
121 if (*p == '\0') {
122 *input = NULL;
123 } else {
124 *p = '\0';
125 *input = p + 1;
126 }
127 }
128 return result;
129}
130
131time_t mktimegm(struct tm *tm)
132{
133 time_t t;
134 int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
135 if (m < 3) {
136 m += 12;
137 y--;
138 }
139 t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
140 y / 400 - 719469);
141 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
142 return t;
143}
144
145int qemu_fls(int i)
146{
147 return 32 - clz32(i);
148}
149
150
151
152
153
154
155
156
157int qemu_fdatasync(int fd)
158{
159#ifdef CONFIG_FDATASYNC
160 return fdatasync(fd);
161#else
162 return fsync(fd);
163#endif
164}
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186size_t buffer_find_nonzero_offset(const void *buf, size_t len)
187{
188 const VECTYPE *p = buf;
189 const VECTYPE zero = (VECTYPE){0};
190 size_t i;
191
192 assert(can_use_buffer_find_nonzero_offset(buf, len));
193
194 if (!len) {
195 return 0;
196 }
197
198 for (i = 0; i < BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR; i++) {
199 if (!ALL_EQ(p[i], zero)) {
200 return i * sizeof(VECTYPE);
201 }
202 }
203
204 for (i = BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR;
205 i < len / sizeof(VECTYPE);
206 i += BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR) {
207 VECTYPE tmp0 = p[i + 0] | p[i + 1];
208 VECTYPE tmp1 = p[i + 2] | p[i + 3];
209 VECTYPE tmp2 = p[i + 4] | p[i + 5];
210 VECTYPE tmp3 = p[i + 6] | p[i + 7];
211 VECTYPE tmp01 = tmp0 | tmp1;
212 VECTYPE tmp23 = tmp2 | tmp3;
213 if (!ALL_EQ(tmp01 | tmp23, zero)) {
214 break;
215 }
216 }
217
218 return i * sizeof(VECTYPE);
219}
220
221
222
223
224
225
226
227bool buffer_is_zero(const void *buf, size_t len)
228{
229
230
231
232
233
234
235 size_t i;
236 long d0, d1, d2, d3;
237 const long * const data = buf;
238
239
240 if (can_use_buffer_find_nonzero_offset(buf, len)) {
241 return buffer_find_nonzero_offset(buf, len) == len;
242 }
243
244 assert(len % (4 * sizeof(long)) == 0);
245 len /= sizeof(long);
246
247 for (i = 0; i < len; i += 4) {
248 d0 = data[i + 0];
249 d1 = data[i + 1];
250 d2 = data[i + 2];
251 d3 = data[i + 3];
252
253 if (d0 || d1 || d2 || d3) {
254 return false;
255 }
256 }
257
258 return true;
259}
260
261#ifndef _WIN32
262
263int fcntl_setfl(int fd, int flag)
264{
265 int flags;
266
267 flags = fcntl(fd, F_GETFL);
268 if (flags == -1)
269 return -errno;
270
271 if (fcntl(fd, F_SETFL, flags | flag) == -1)
272 return -errno;
273
274 return 0;
275}
276#endif
277
278static int64_t suffix_mul(char suffix, int64_t unit)
279{
280 switch (qemu_toupper(suffix)) {
281 case STRTOSZ_DEFSUFFIX_B:
282 return 1;
283 case STRTOSZ_DEFSUFFIX_KB:
284 return unit;
285 case STRTOSZ_DEFSUFFIX_MB:
286 return unit * unit;
287 case STRTOSZ_DEFSUFFIX_GB:
288 return unit * unit * unit;
289 case STRTOSZ_DEFSUFFIX_TB:
290 return unit * unit * unit * unit;
291 case STRTOSZ_DEFSUFFIX_PB:
292 return unit * unit * unit * unit * unit;
293 case STRTOSZ_DEFSUFFIX_EB:
294 return unit * unit * unit * unit * unit * unit;
295 }
296 return -1;
297}
298
299
300
301
302
303
304
305int64_t strtosz_suffix_unit(const char *nptr, char **end,
306 const char default_suffix, int64_t unit)
307{
308 int64_t retval = -EINVAL;
309 char *endptr;
310 unsigned char c;
311 int mul_required = 0;
312 double val, mul, integral, fraction;
313
314 errno = 0;
315 val = strtod(nptr, &endptr);
316 if (isnan(val) || endptr == nptr || errno != 0) {
317 goto fail;
318 }
319 fraction = modf(val, &integral);
320 if (fraction != 0) {
321 mul_required = 1;
322 }
323 c = *endptr;
324 mul = suffix_mul(c, unit);
325 if (mul >= 0) {
326 endptr++;
327 } else {
328 mul = suffix_mul(default_suffix, unit);
329 assert(mul >= 0);
330 }
331 if (mul == 1 && mul_required) {
332 goto fail;
333 }
334 if ((val * mul >= INT64_MAX) || val < 0) {
335 retval = -ERANGE;
336 goto fail;
337 }
338 retval = val * mul;
339
340fail:
341 if (end) {
342 *end = endptr;
343 }
344
345 return retval;
346}
347
348int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
349{
350 return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
351}
352
353int64_t strtosz(const char *nptr, char **end)
354{
355 return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB);
356}
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386int parse_uint(const char *s, unsigned long long *value, char **endptr,
387 int base)
388{
389 int r = 0;
390 char *endp = (char *)s;
391 unsigned long long val = 0;
392
393 if (!s) {
394 r = -EINVAL;
395 goto out;
396 }
397
398 errno = 0;
399 val = strtoull(s, &endp, base);
400 if (errno) {
401 r = -errno;
402 goto out;
403 }
404
405 if (endp == s) {
406 r = -EINVAL;
407 goto out;
408 }
409
410
411 while (isspace((unsigned char)*s)) {
412 s++;
413 }
414 if (*s == '-') {
415 val = 0;
416 r = -ERANGE;
417 goto out;
418 }
419
420out:
421 *value = val;
422 *endptr = endp;
423 return r;
424}
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440int parse_uint_full(const char *s, unsigned long long *value, int base)
441{
442 char *endp;
443 int r;
444
445 r = parse_uint(s, value, &endp, base);
446 if (r < 0) {
447 return r;
448 }
449 if (*endp) {
450 *value = 0;
451 return -EINVAL;
452 }
453
454 return 0;
455}
456
457int qemu_parse_fd(const char *param)
458{
459 int fd;
460 char *endptr = NULL;
461
462 fd = strtol(param, &endptr, 10);
463 if (*endptr || (fd == 0 && param == endptr)) {
464 return -1;
465 }
466 return fd;
467}
468
469
470int64_t pow2floor(int64_t value)
471{
472 if (!is_power_of_2(value)) {
473 value = 0x8000000000000000ULL >> clz64(value);
474 }
475 return value;
476}
477
478
479
480
481
482int uleb128_encode_small(uint8_t *out, uint32_t n)
483{
484 g_assert(n <= 0x3fff);
485 if (n < 0x80) {
486 *out++ = n;
487 return 1;
488 } else {
489 *out++ = (n & 0x7f) | 0x80;
490 *out++ = n >> 7;
491 return 2;
492 }
493}
494
495int uleb128_decode_small(const uint8_t *in, uint32_t *n)
496{
497 if (!(*in & 0x80)) {
498 *n = *in++;
499 return 1;
500 } else {
501 *n = *in++ & 0x7f;
502
503 if (*in & 0x80) {
504 return -1;
505 }
506 *n |= *in++ << 7;
507 return 2;
508 }
509}
510
511
512
513
514int parse_debug_env(const char *name, int max, int initial)
515{
516 char *debug_env = getenv(name);
517 char *inv = NULL;
518 int debug;
519
520 if (!debug_env) {
521 return initial;
522 }
523 debug = strtol(debug_env, &inv, 10);
524 if (inv == debug_env) {
525 return initial;
526 }
527 if (debug < 0 || debug > max) {
528 fprintf(stderr, "warning: %s not in [0, %d]", name, max);
529 return initial;
530 }
531 return debug;
532}
533