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
110time_t mktimegm(struct tm *tm)
111{
112 time_t t;
113 int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
114 if (m < 3) {
115 m += 12;
116 y--;
117 }
118 t = 86400ULL * (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 +
119 y / 400 - 719469);
120 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
121 return t;
122}
123
124int qemu_fls(int i)
125{
126 return 32 - clz32(i);
127}
128
129
130
131
132
133
134
135
136int qemu_fdatasync(int fd)
137{
138#ifdef CONFIG_FDATASYNC
139 return fdatasync(fd);
140#else
141 return fsync(fd);
142#endif
143}
144
145
146
147
148
149
150
151bool buffer_is_zero(const void *buf, size_t len)
152{
153
154
155
156
157
158
159 size_t i;
160 long d0, d1, d2, d3;
161 const long * const data = buf;
162
163 assert(len % (4 * sizeof(long)) == 0);
164 len /= sizeof(long);
165
166 for (i = 0; i < len; i += 4) {
167 d0 = data[i + 0];
168 d1 = data[i + 1];
169 d2 = data[i + 2];
170 d3 = data[i + 3];
171
172 if (d0 || d1 || d2 || d3) {
173 return false;
174 }
175 }
176
177 return true;
178}
179
180#ifndef _WIN32
181
182int fcntl_setfl(int fd, int flag)
183{
184 int flags;
185
186 flags = fcntl(fd, F_GETFL);
187 if (flags == -1)
188 return -errno;
189
190 if (fcntl(fd, F_SETFL, flags | flag) == -1)
191 return -errno;
192
193 return 0;
194}
195#endif
196
197static int64_t suffix_mul(char suffix, int64_t unit)
198{
199 switch (qemu_toupper(suffix)) {
200 case STRTOSZ_DEFSUFFIX_B:
201 return 1;
202 case STRTOSZ_DEFSUFFIX_KB:
203 return unit;
204 case STRTOSZ_DEFSUFFIX_MB:
205 return unit * unit;
206 case STRTOSZ_DEFSUFFIX_GB:
207 return unit * unit * unit;
208 case STRTOSZ_DEFSUFFIX_TB:
209 return unit * unit * unit * unit;
210 }
211 return -1;
212}
213
214
215
216
217
218
219
220int64_t strtosz_suffix_unit(const char *nptr, char **end,
221 const char default_suffix, int64_t unit)
222{
223 int64_t retval = -EINVAL;
224 char *endptr;
225 unsigned char c;
226 int mul_required = 0;
227 double val, mul, integral, fraction;
228
229 errno = 0;
230 val = strtod(nptr, &endptr);
231 if (isnan(val) || endptr == nptr || errno != 0) {
232 goto fail;
233 }
234 fraction = modf(val, &integral);
235 if (fraction != 0) {
236 mul_required = 1;
237 }
238 c = *endptr;
239 mul = suffix_mul(c, unit);
240 if (mul >= 0) {
241 endptr++;
242 } else {
243 mul = suffix_mul(default_suffix, unit);
244 assert(mul >= 0);
245 }
246 if (mul == 1 && mul_required) {
247 goto fail;
248 }
249 if ((val * mul >= INT64_MAX) || val < 0) {
250 retval = -ERANGE;
251 goto fail;
252 }
253 retval = val * mul;
254
255fail:
256 if (end) {
257 *end = endptr;
258 }
259
260 return retval;
261}
262
263int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
264{
265 return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
266}
267
268int64_t strtosz(const char *nptr, char **end)
269{
270 return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB);
271}
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301int parse_uint(const char *s, unsigned long long *value, char **endptr,
302 int base)
303{
304 int r = 0;
305 char *endp = (char *)s;
306 unsigned long long val = 0;
307
308 if (!s) {
309 r = -EINVAL;
310 goto out;
311 }
312
313 errno = 0;
314 val = strtoull(s, &endp, base);
315 if (errno) {
316 r = -errno;
317 goto out;
318 }
319
320 if (endp == s) {
321 r = -EINVAL;
322 goto out;
323 }
324
325
326 while (isspace((unsigned char)*s)) {
327 s++;
328 }
329 if (*s == '-') {
330 val = 0;
331 r = -ERANGE;
332 goto out;
333 }
334
335out:
336 *value = val;
337 *endptr = endp;
338 return r;
339}
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355int parse_uint_full(const char *s, unsigned long long *value, int base)
356{
357 char *endp;
358 int r;
359
360 r = parse_uint(s, value, &endp, base);
361 if (r < 0) {
362 return r;
363 }
364 if (*endp) {
365 *value = 0;
366 return -EINVAL;
367 }
368
369 return 0;
370}
371
372int qemu_parse_fd(const char *param)
373{
374 int fd;
375 char *endptr = NULL;
376
377 fd = strtol(param, &endptr, 10);
378 if (*endptr || (fd == 0 && param == endptr)) {
379 return -1;
380 }
381 return fd;
382}
383
384
385int64_t pow2floor(int64_t value)
386{
387 if (!is_power_of_2(value)) {
388 value = 0x8000000000000000ULL >> clz64(value);
389 }
390 return value;
391}
392
393
394
395
396
397int uleb128_encode_small(uint8_t *out, uint32_t n)
398{
399 g_assert(n <= 0x3fff);
400 if (n < 0x80) {
401 *out++ = n;
402 return 1;
403 } else {
404 *out++ = (n & 0x7f) | 0x80;
405 *out++ = n >> 7;
406 return 2;
407 }
408}
409
410int uleb128_decode_small(const uint8_t *in, uint32_t *n)
411{
412 if (!(*in & 0x80)) {
413 *n = *in++;
414 return 1;
415 } else {
416 *n = *in++ & 0x7f;
417
418 if (*in & 0x80) {
419 return -1;
420 }
421 *n |= *in++ << 7;
422 return 2;
423 }
424}
425