]> Git Repo - qemu.git/blobdiff - util/qemu-option.c
qemu-thread: fix qemu_event without futexes
[qemu.git] / util / qemu-option.c
index 8ac8111ea892f9f0541bebb449be5f4789767909..a708241643626282088bc6b7072e209d3aa24025 100644 (file)
@@ -310,8 +310,13 @@ static void qemu_opt_del_all(QemuOpts *opts, const char *name)
 
 const char *qemu_opt_get(QemuOpts *opts, const char *name)
 {
-    QemuOpt *opt = qemu_opt_find(opts, name);
+    QemuOpt *opt;
+
+    if (opts == NULL) {
+        return NULL;
+    }
 
+    opt = qemu_opt_find(opts, name);
     if (!opt) {
         const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
         if (desc && desc->def_value_str) {
@@ -364,9 +369,14 @@ bool qemu_opt_has_help_opt(QemuOpts *opts)
 static bool qemu_opt_get_bool_helper(QemuOpts *opts, const char *name,
                                      bool defval, bool del)
 {
-    QemuOpt *opt = qemu_opt_find(opts, name);
+    QemuOpt *opt;
     bool ret = defval;
 
+    if (opts == NULL) {
+        return ret;
+    }
+
+    opt = qemu_opt_find(opts, name);
     if (opt == NULL) {
         const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
         if (desc && desc->def_value_str) {
@@ -395,9 +405,14 @@ bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval)
 static uint64_t qemu_opt_get_number_helper(QemuOpts *opts, const char *name,
                                            uint64_t defval, bool del)
 {
-    QemuOpt *opt = qemu_opt_find(opts, name);
+    QemuOpt *opt;
     uint64_t ret = defval;
 
+    if (opts == NULL) {
+        return ret;
+    }
+
+    opt = qemu_opt_find(opts, name);
     if (opt == NULL) {
         const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
         if (desc && desc->def_value_str) {
@@ -427,9 +442,14 @@ uint64_t qemu_opt_get_number_del(QemuOpts *opts, const char *name,
 static uint64_t qemu_opt_get_size_helper(QemuOpts *opts, const char *name,
                                          uint64_t defval, bool del)
 {
-    QemuOpt *opt = qemu_opt_find(opts, name);
+    QemuOpt *opt;
     uint64_t ret = defval;
 
+    if (opts == NULL) {
+        return ret;
+    }
+
+    opt = qemu_opt_find(opts, name);
     if (opt == NULL) {
         const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);
         if (desc && desc->def_value_str) {
@@ -621,21 +641,6 @@ QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id)
     return NULL;
 }
 
-static int id_wellformed(const char *id)
-{
-    int i;
-
-    if (!qemu_isalpha(id[0])) {
-        return 0;
-    }
-    for (i = 1; id[i]; i++) {
-        if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {
-            return 0;
-        }
-    }
-    return 1;
-}
-
 QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
                            int fail_if_exists, Error **errp)
 {
@@ -732,14 +737,14 @@ void qemu_opts_del(QemuOpts *opts)
     g_free(opts);
 }
 
-void qemu_opts_print(QemuOpts *opts)
+void qemu_opts_print(QemuOpts *opts, const char *sep)
 {
     QemuOpt *opt;
     QemuOptDesc *desc = opts->list->desc;
 
     if (desc[0].name == NULL) {
         QTAILQ_FOREACH(opt, &opts->head, next) {
-            printf("%s=\"%s\" ", opt->name, opt->str);
+            printf("%s%s=\"%s\"", sep, opt->name, opt->str);
         }
         return;
     }
@@ -752,12 +757,12 @@ void qemu_opts_print(QemuOpts *opts)
             continue;
         }
         if (desc->type == QEMU_OPT_STRING) {
-            printf("%s='%s' ", desc->name, value);
+            printf("%s%s='%s'", sep, desc->name, value);
         } else if ((desc->type == QEMU_OPT_SIZE ||
                     desc->type == QEMU_OPT_NUMBER) && opt) {
-            printf("%s=%" PRId64 " ", desc->name, opt->value.uint);
+            printf("%s%s=%" PRId64, sep, desc->name, opt->value.uint);
         } else {
-            printf("%s=%s ", desc->name, value);
+            printf("%s%s=%s", sep, desc->name, value);
         }
     }
 }
@@ -1077,26 +1082,13 @@ static size_t count_opts_list(QemuOptsList *list)
 
 void qemu_opts_free(QemuOptsList *list)
 {
-    /* List members point to new malloced space and need to be freed.
-     * FIXME:
-     * Introduced for QEMUOptionParamter->QemuOpts conversion.
-     * Will remove after all drivers switch to QemuOpts.
-     */
-    if (list && list->allocated) {
-        QemuOptDesc *desc = list->desc;
-        while (desc && desc->name) {
-            g_free((char *)desc->name);
-            g_free((char *)desc->help);
-            g_free((char *)desc->def_value_str);
-            desc++;
-        }
-    }
-
     g_free(list);
 }
 
 /* Realloc dst option list and append options from an option list (list)
  * to it. dst could be NULL or a malloced list.
+ * The lifetime of dst must be shorter than the input list because the
+ * QemuOptDesc->name, ->help, and ->def_value_str strings are shared.
  */
 QemuOptsList *qemu_opts_append(QemuOptsList *dst,
                                QemuOptsList *list)
@@ -1104,6 +1096,7 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst,
     size_t num_opts, num_dst_opts;
     QemuOptDesc *desc;
     bool need_init = false;
+    bool need_head_update;
 
     if (!list) {
         return dst;
@@ -1114,6 +1107,12 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst,
      */
     if (!dst) {
         need_init = true;
+        need_head_update = true;
+    } else {
+        /* Moreover, even if dst is not NULL, the realloc may move it to a
+         * different address in which case we may get a stale tail pointer
+         * in dst->head. */
+        need_head_update = QTAILQ_EMPTY(&dst->head);
     }
 
     num_opts = count_opts_list(dst);
@@ -1124,25 +1123,19 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst,
     if (need_init) {
         dst->name = NULL;
         dst->implied_opt_name = NULL;
-        QTAILQ_INIT(&dst->head);
-        dst->allocated = true;
         dst->merge_lists = false;
     }
+    if (need_head_update) {
+        QTAILQ_INIT(&dst->head);
+    }
     dst->desc[num_dst_opts].name = NULL;
 
-    /* (const char *) members of result dst are malloced, need free. */
-    assert(dst->allocated);
     /* append list->desc to dst->desc */
     if (list) {
         desc = list->desc;
         while (desc && desc->name) {
             if (find_desc_by_name(dst->desc, desc->name) == NULL) {
-                dst->desc[num_dst_opts].name = g_strdup(desc->name);
-                dst->desc[num_dst_opts].type = desc->type;
-                dst->desc[num_dst_opts].help = g_strdup(desc->help);
-                dst->desc[num_dst_opts].def_value_str =
-                                         g_strdup(desc->def_value_str);
-                num_dst_opts++;
+                dst->desc[num_dst_opts++] = *desc;
                 dst->desc[num_dst_opts].name = NULL;
             }
             desc++;
This page took 0.025092 seconds and 4 git commands to generate.