Diff for /qemu/cutils.c between versions 1.1.1.3 and 1.1.1.7

version 1.1.1.3, 2018/04/24 16:50:24 version 1.1.1.7, 2018/04/24 18:33:30
Line 23 Line 23
  */   */
 #include "qemu-common.h"  #include "qemu-common.h"
 #include "host-utils.h"  #include "host-utils.h"
   #include <math.h>
   
 void pstrcpy(char *buf, int buf_size, const char *str)  void pstrcpy(char *buf, int buf_size, const char *str)
 {  {
Line 83  int stristart(const char *str, const cha Line 84  int stristart(const char *str, const cha
     return 1;      return 1;
 }  }
   
   /* XXX: use host strnlen if available ? */
   int qemu_strnlen(const char *s, int max_len)
   {
       int i;
   
       for(i = 0; i < max_len; i++) {
           if (s[i] == '\0') {
               break;
           }
       }
       return i;
   }
   
 time_t mktimegm(struct tm *tm)  time_t mktimegm(struct tm *tm)
 {  {
     time_t t;      time_t t;
Line 102  int qemu_fls(int i) Line 116  int qemu_fls(int i)
     return 32 - clz32(i);      return 32 - clz32(i);
 }  }
   
   /*
    * Make sure data goes on disk, but if possible do not bother to
    * write out the inode just for timestamp updates.
    *
    * Unfortunately even in 2009 many operating systems do not support
    * fdatasync and have to fall back to fsync.
    */
   int qemu_fdatasync(int fd)
   {
   #ifdef CONFIG_FDATASYNC
       return fdatasync(fd);
   #else
       return fsync(fd);
   #endif
   }
   
 /* io vectors */  /* io vectors */
   
 void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)  void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
Line 112  void qemu_iovec_init(QEMUIOVector *qiov, Line 142  void qemu_iovec_init(QEMUIOVector *qiov,
     qiov->size = 0;      qiov->size = 0;
 }  }
   
   void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov)
   {
       int i;
   
       qiov->iov = iov;
       qiov->niov = niov;
       qiov->nalloc = -1;
       qiov->size = 0;
       for (i = 0; i < niov; i++)
           qiov->size += iov[i].iov_len;
   }
   
 void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)  void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
 {  {
       assert(qiov->nalloc != -1);
   
     if (qiov->niov == qiov->nalloc) {      if (qiov->niov == qiov->nalloc) {
         qiov->nalloc = 2 * qiov->nalloc + 1;          qiov->nalloc = 2 * qiov->nalloc + 1;
         qiov->iov = qemu_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec));          qiov->iov = qemu_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec));
Line 124  void qemu_iovec_add(QEMUIOVector *qiov,  Line 168  void qemu_iovec_add(QEMUIOVector *qiov, 
     ++qiov->niov;      ++qiov->niov;
 }  }
   
   /*
    * Copies iovecs from src to the end of dst. It starts copying after skipping
    * the given number of bytes in src and copies until src is completely copied
    * or the total size of the copied iovec reaches size.The size of the last
    * copied iovec is changed in order to fit the specified total size if it isn't
    * a perfect fit already.
    */
   void qemu_iovec_copy(QEMUIOVector *dst, QEMUIOVector *src, uint64_t skip,
       size_t size)
   {
       int i;
       size_t done;
       void *iov_base;
       uint64_t iov_len;
   
       assert(dst->nalloc != -1);
   
       done = 0;
       for (i = 0; (i < src->niov) && (done != size); i++) {
           if (skip >= src->iov[i].iov_len) {
               /* Skip the whole iov */
               skip -= src->iov[i].iov_len;
               continue;
           } else {
               /* Skip only part (or nothing) of the iov */
               iov_base = (uint8_t*) src->iov[i].iov_base + skip;
               iov_len = src->iov[i].iov_len - skip;
               skip = 0;
           }
   
           if (done + iov_len > size) {
               qemu_iovec_add(dst, iov_base, size - done);
               break;
           } else {
               qemu_iovec_add(dst, iov_base, iov_len);
           }
           done += iov_len;
       }
   }
   
   void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size)
   {
       qemu_iovec_copy(dst, src, 0, size);
   }
   
 void qemu_iovec_destroy(QEMUIOVector *qiov)  void qemu_iovec_destroy(QEMUIOVector *qiov)
 {  {
       assert(qiov->nalloc != -1);
   
     qemu_free(qiov->iov);      qemu_free(qiov->iov);
 }  }
   
 void qemu_iovec_reset(QEMUIOVector *qiov)  void qemu_iovec_reset(QEMUIOVector *qiov)
 {  {
       assert(qiov->nalloc != -1);
   
     qiov->niov = 0;      qiov->niov = 0;
     qiov->size = 0;      qiov->size = 0;
 }  }
Line 161  void qemu_iovec_from_buffer(QEMUIOVector Line 254  void qemu_iovec_from_buffer(QEMUIOVector
         count -= copy;          count -= copy;
     }      }
 }  }
   
   void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count)
   {
       size_t n;
       int i;
   
       for (i = 0; i < qiov->niov && count; ++i) {
           n = MIN(count, qiov->iov[i].iov_len);
           memset(qiov->iov[i].iov_base, c, n);
           count -= n;
       }
   }
   
   void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count,
                               size_t skip)
   {
       int i;
       size_t done;
       void *iov_base;
       uint64_t iov_len;
   
       done = 0;
       for (i = 0; (i < qiov->niov) && (done != count); i++) {
           if (skip >= qiov->iov[i].iov_len) {
               /* Skip the whole iov */
               skip -= qiov->iov[i].iov_len;
               continue;
           } else {
               /* Skip only part (or nothing) of the iov */
               iov_base = (uint8_t*) qiov->iov[i].iov_base + skip;
               iov_len = qiov->iov[i].iov_len - skip;
               skip = 0;
           }
   
           if (done + iov_len > count) {
               memset(iov_base, c, count - done);
               break;
           } else {
               memset(iov_base, c, iov_len);
           }
           done += iov_len;
       }
   }
   
   #ifndef _WIN32
   /* Sets a specific flag */
   int fcntl_setfl(int fd, int flag)
   {
       int flags;
   
       flags = fcntl(fd, F_GETFL);
       if (flags == -1)
           return -errno;
   
       if (fcntl(fd, F_SETFL, flags | flag) == -1)
           return -errno;
   
       return 0;
   }
   #endif
   
   /*
    * Convert string to bytes, allowing either B/b for bytes, K/k for KB,
    * M/m for MB, G/g for GB or T/t for TB. Default without any postfix
    * is MB. End pointer will be returned in *end, if not NULL. A valid
    * value must be terminated by whitespace, ',' or '\0'. Return -1 on
    * error.
    */
   int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
   {
       int64_t retval = -1;
       char *endptr;
       unsigned char c, d;
       int mul_required = 0;
       double val, mul, integral, fraction;
   
       errno = 0;
       val = strtod(nptr, &endptr);
       if (isnan(val) || endptr == nptr || errno != 0) {
           goto fail;
       }
       fraction = modf(val, &integral);
       if (fraction != 0) {
           mul_required = 1;
       }
       /*
        * Any whitespace character is fine for terminating the number,
        * in addition we accept ',' to handle strings where the size is
        * part of a multi token argument.
        */
       c = *endptr;
       d = c;
       if (qemu_isspace(c) || c == '\0' || c == ',') {
           c = 0;
           if (default_suffix) {
               d = default_suffix;
           } else {
               d = c;
           }
       }
       switch (qemu_toupper(d)) {
       case STRTOSZ_DEFSUFFIX_B:
           mul = 1;
           if (mul_required) {
               goto fail;
           }
           break;
       case STRTOSZ_DEFSUFFIX_KB:
           mul = 1 << 10;
           break;
       case 0:
           if (mul_required) {
               goto fail;
           }
       case STRTOSZ_DEFSUFFIX_MB:
           mul = 1ULL << 20;
           break;
       case STRTOSZ_DEFSUFFIX_GB:
           mul = 1ULL << 30;
           break;
       case STRTOSZ_DEFSUFFIX_TB:
           mul = 1ULL << 40;
           break;
       default:
           goto fail;
       }
       /*
        * If not terminated by whitespace, ',', or \0, increment endptr
        * to point to next character, then check that we are terminated
        * by an appropriate separating character, ie. whitespace, ',', or
        * \0. If not, we are seeing trailing garbage, thus fail.
        */
       if (c != 0) {
           endptr++;
           if (!qemu_isspace(*endptr) && *endptr != ',' && *endptr != 0) {
               goto fail;
           }
       }
       if ((val * mul >= INT64_MAX) || val < 0) {
           goto fail;
       }
       retval = val * mul;
   
   fail:
       if (end) {
           *end = endptr;
       }
   
       return retval;
   }
   
   int64_t strtosz(const char *nptr, char **end)
   {
       return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB);
   }

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.7


unix.superglobalmegacorp.com