qemu/util/cutils.c
<<
>>
Prefs
   1/*
   2 * Simple C functions to supplement the C library
   3 *
   4 * Copyright (c) 2006 Fabrice Bellard
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  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/* strcat and truncate. */
  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/* XXX: use host strnlen if available ? */
  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 * Make sure data goes on disk, but if possible do not bother to
 152 * write out the inode just for timestamp updates.
 153 *
 154 * Unfortunately even in 2009 many operating systems do not support
 155 * fdatasync and have to fall back to fsync.
 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 * Searches for an area with non-zero content in a buffer
 168 *
 169 * Attention! The len must be a multiple of
 170 * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE)
 171 * and addr must be a multiple of sizeof(VECTYPE) due to
 172 * restriction of optimizations in this function.
 173 *
 174 * can_use_buffer_find_nonzero_offset() can be used to check
 175 * these requirements.
 176 *
 177 * The return value is the offset of the non-zero area rounded
 178 * down to a multiple of sizeof(VECTYPE) for the first
 179 * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR chunks and down to
 180 * BUFFER_FIND_NONZERO_OFFSET_UNROLL_FACTOR * sizeof(VECTYPE)
 181 * afterwards.
 182 *
 183 * If the buffer is all zero the return value is equal to len.
 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 * Checks if a buffer is all zeroes
 223 *
 224 * Attention! The len must be a multiple of 4 * sizeof(long) due to
 225 * restriction of optimizations in this function.
 226 */
 227bool buffer_is_zero(const void *buf, size_t len)
 228{
 229    /*
 230     * Use long as the biggest available internal data type that fits into the
 231     * CPU register and unroll the loop to smooth out the effect of memory
 232     * latency.
 233     */
 234
 235    size_t i;
 236    long d0, d1, d2, d3;
 237    const long * const data = buf;
 238
 239    /* use vector optimized zero check if possible */
 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/* Sets a specific flag */
 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 * Convert string to bytes, allowing either B/b for bytes, K/k for KB,
 301 * M/m for MB, G/g for GB or T/t for TB. End pointer will be returned
 302 * in *end, if not NULL. Return -ERANGE on overflow, Return -EINVAL on
 303 * other error.
 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 * parse_uint:
 360 *
 361 * @s: String to parse
 362 * @value: Destination for parsed integer value
 363 * @endptr: Destination for pointer to first character not consumed
 364 * @base: integer base, between 2 and 36 inclusive, or 0
 365 *
 366 * Parse unsigned integer
 367 *
 368 * Parsed syntax is like strtoull()'s: arbitrary whitespace, a single optional
 369 * '+' or '-', an optional "0x" if @base is 0 or 16, one or more digits.
 370 *
 371 * If @s is null, or @base is invalid, or @s doesn't start with an
 372 * integer in the syntax above, set *@value to 0, *@endptr to @s, and
 373 * return -EINVAL.
 374 *
 375 * Set *@endptr to point right beyond the parsed integer (even if the integer
 376 * overflows or is negative, all digits will be parsed and *@endptr will
 377 * point right beyond them).
 378 *
 379 * If the integer is negative, set *@value to 0, and return -ERANGE.
 380 *
 381 * If the integer overflows unsigned long long, set *@value to
 382 * ULLONG_MAX, and return -ERANGE.
 383 *
 384 * Else, set *@value to the parsed integer, and return 0.
 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    /* make sure we reject negative numbers: */
 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 * parse_uint_full:
 428 *
 429 * @s: String to parse
 430 * @value: Destination for parsed integer value
 431 * @base: integer base, between 2 and 36 inclusive, or 0
 432 *
 433 * Parse unsigned integer from entire string
 434 *
 435 * Have the same behavior of parse_uint(), but with an additional check
 436 * for additional data after the parsed number. If extra characters are present
 437 * after the parsed number, the function will return -EINVAL, and *@v will
 438 * be set to 0.
 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/* round down to the nearest power of 2*/
 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 * Implementation of  ULEB128 (http://en.wikipedia.org/wiki/LEB128)
 480 * Input is limited to 14-bit numbers
 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        /* we exceed 14 bit number */
 503        if (*in & 0x80) {
 504            return -1;
 505        }
 506        *n |= *in++ << 7;
 507        return 2;
 508    }
 509}
 510
 511/*
 512 * helper to parse debug environment variables
 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