convert udp chardev to QemuOpts.
[qemu] / cutils.c
index 658746b..7a22346 100644 (file)
--- a/cutils.c
+++ b/cutils.c
@@ -83,6 +83,19 @@ int stristart(const char *str, const char *val, const char **ptr)
     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 t;
@@ -102,6 +115,22 @@ int qemu_fls(int 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 _POSIX_SYNCHRONIZED_IO
+    return fdatasync(fd);
+#else
+    return fsync(fd);
+#endif
+}
+
 /* io vectors */
 
 void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
@@ -112,8 +141,22 @@ void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
     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)
 {
+    assert(qiov->nalloc != -1);
+
     if (qiov->niov == qiov->nalloc) {
         qiov->nalloc = 2 * qiov->nalloc + 1;
         qiov->iov = qemu_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec));
@@ -124,13 +167,42 @@ void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
     ++qiov->niov;
 }
 
+/*
+ * Copies iovecs from src to the end dst 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_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size)
+{
+    int i;
+    size_t done;
+
+    assert(dst->nalloc != -1);
+
+    done = 0;
+    for (i = 0; (i < src->niov) && (done != size); i++) {
+        if (done + src->iov[i].iov_len > size) {
+            qemu_iovec_add(dst, src->iov[i].iov_base, size - done);
+            break;
+        } else {
+            qemu_iovec_add(dst, src->iov[i].iov_base, src->iov[i].iov_len);
+        }
+        done += src->iov[i].iov_len;
+    }
+}
+
 void qemu_iovec_destroy(QEMUIOVector *qiov)
 {
+    assert(qiov->nalloc != -1);
+
     qemu_free(qiov->iov);
 }
 
 void qemu_iovec_reset(QEMUIOVector *qiov)
 {
+    assert(qiov->nalloc != -1);
+
     qiov->niov = 0;
     qiov->size = 0;
 }