From e9d635ea1809a6e114c33413c359abbb88a35737 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 13 Jan 2021 16:10:09 -0600 Subject: [PATCH 1/5] net: Clarify early exit condition On first glance, the loop in qmp_query_rx_filter() has early return paths that could leak any allocation of filter_list from a previous iteration. But on closer inspection, it is obvious that all of the early exits are guarded by has_name, and that the bulk of the loop body can be executed at most once if the user is filtering by name, thus, any early exit coincides with an empty list. Add asserts to make this obvious. Signed-off-by: Eric Blake Reviewed-by: Markus Armbruster Message-Id: <20210113221013.390592-2-eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Markus Armbruster --- net/net.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/net.c b/net/net.c index c1cd9c75f6..2afac24b79 100644 --- a/net/net.c +++ b/net/net.c @@ -1227,6 +1227,7 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name, if (nc->info->type != NET_CLIENT_DRIVER_NIC) { if (has_name) { error_setg(errp, "net client(%s) isn't a NIC", name); + assert(!filter_list); return NULL; } continue; @@ -1252,6 +1253,7 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name, } else if (has_name) { error_setg(errp, "net client(%s) doesn't support" " rx-filter querying", name); + assert(!filter_list); return NULL; } From 240ee8bd31f7ff7407197588ae800ff554758b4d Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 13 Jan 2021 16:10:10 -0600 Subject: [PATCH 2/5] qapi: A couple more QAPI_LIST_PREPEND() stragglers Commit 54aa3de72e switched multiple sites to use QAPI_LIST_PREPEND instead of open-coding, but missed a couple of spots. Signed-off-by: Eric Blake Message-Id: <20210113221013.390592-3-eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Markus Armbruster --- hw/core/machine-qmp-cmds.c | 32 +++++++++++--------------------- monitor/qmp-cmds-control.c | 9 ++++----- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index affffe0c4a..156223a344 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -293,41 +293,31 @@ void qmp_set_numa_node(NumaOptions *cmd, Error **errp) static int query_memdev(Object *obj, void *opaque) { MemdevList **list = opaque; - MemdevList *m = NULL; + Memdev *m; QObject *host_nodes; Visitor *v; if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) { m = g_malloc0(sizeof(*m)); - m->value = g_malloc0(sizeof(*m->value)); + m->id = g_strdup(object_get_canonical_path_component(obj)); + m->has_id = !!m->id; - m->value->id = g_strdup(object_get_canonical_path_component(obj)); - m->value->has_id = !!m->value->id; - - m->value->size = object_property_get_uint(obj, "size", - &error_abort); - m->value->merge = object_property_get_bool(obj, "merge", - &error_abort); - m->value->dump = object_property_get_bool(obj, "dump", - &error_abort); - m->value->prealloc = object_property_get_bool(obj, - "prealloc", - &error_abort); - m->value->policy = object_property_get_enum(obj, - "policy", - "HostMemPolicy", - &error_abort); + m->size = object_property_get_uint(obj, "size", &error_abort); + m->merge = object_property_get_bool(obj, "merge", &error_abort); + m->dump = object_property_get_bool(obj, "dump", &error_abort); + m->prealloc = object_property_get_bool(obj, "prealloc", &error_abort); + m->policy = object_property_get_enum(obj, "policy", "HostMemPolicy", + &error_abort); host_nodes = object_property_get_qobject(obj, "host-nodes", &error_abort); v = qobject_input_visitor_new(host_nodes); - visit_type_uint16List(v, NULL, &m->value->host_nodes, &error_abort); + visit_type_uint16List(v, NULL, &m->host_nodes, &error_abort); visit_free(v); qobject_unref(host_nodes); - m->next = *list; - *list = m; + QAPI_LIST_PREPEND(*list, m); } return 0; diff --git a/monitor/qmp-cmds-control.c b/monitor/qmp-cmds-control.c index 17514f4959..509ae870bd 100644 --- a/monitor/qmp-cmds-control.c +++ b/monitor/qmp-cmds-control.c @@ -104,17 +104,16 @@ VersionInfo *qmp_query_version(Error **errp) static void query_commands_cb(const QmpCommand *cmd, void *opaque) { - CommandInfoList *info, **list = opaque; + CommandInfo *info; + CommandInfoList **list = opaque; if (!cmd->enabled) { return; } info = g_malloc0(sizeof(*info)); - info->value = g_malloc0(sizeof(*info->value)); - info->value->name = g_strdup(cmd->name); - info->next = *list; - *list = info; + info->name = g_strdup(cmd->name); + QAPI_LIST_PREPEND(*list, info); } CommandInfoList *qmp_query_commands(Error **errp) From dc13f40c6ba291e31d09053815c230ed88c8921f Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 13 Jan 2021 16:10:11 -0600 Subject: [PATCH 3/5] qapi: Introduce QAPI_LIST_APPEND Similar to the existing QAPI_LIST_PREPEND, but designed for use where we want to preserve insertion order. Callers will be added in upcoming patches. Note the difference in signature: PREPEND takes List*, APPEND takes List**. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy Message-Id: <20210113221013.390592-4-eblake@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- include/qapi/util.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/qapi/util.h b/include/qapi/util.h index 6178e98e97..d7bfb30e25 100644 --- a/include/qapi/util.h +++ b/include/qapi/util.h @@ -37,4 +37,17 @@ int parse_qapi_name(const char *name, bool complete); (list) = _tmp; \ } while (0) +/* + * For any pointer to a GenericList @tail (usually the 'next' member of a + * list element), insert @element at the back and update the tail. + * + * Note that this macro evaluates @element exactly once, so it is safe + * to have side-effects with that argument. + */ +#define QAPI_LIST_APPEND(tail, element) do { \ + *(tail) = g_malloc0(sizeof(**(tail))); \ + (*(tail))->value = (element); \ + (tail) = &(*(tail))->next; \ +} while (0) + #endif From c3033fd372fdaf5b89190136a74b3d78880b85d6 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 13 Jan 2021 16:10:12 -0600 Subject: [PATCH 4/5] qapi: Use QAPI_LIST_APPEND in trivial cases The easiest spots to use QAPI_LIST_APPEND are where we already have an obvious pointer to the tail of a list. While at it, consistently use the variable name 'tail' for that purpose. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Markus Armbruster Message-Id: <20210113221013.390592-5-eblake@redhat.com> Signed-off-by: Markus Armbruster --- backends/hostmem.c | 10 ++-- block/dirty-bitmap.c | 8 ++- block/export/export.c | 7 +-- block/qapi.c | 23 ++------ block/qcow2-bitmap.c | 15 ++---- block/vmdk.c | 9 ++-- blockdev.c | 13 ++--- crypto/block-luks.c | 9 ++-- hw/acpi/cpu.c | 7 +-- hw/acpi/memory_hotplug.c | 8 ++- iothread.c | 12 ++--- job-qmp.c | 13 ++--- monitor/hmp-cmds.c | 10 ++-- qemu-img.c | 8 +-- qga/commands-posix.c | 31 ++++------- qga/commands-win32.c | 11 ++-- scsi/pr-manager.c | 10 +--- target/i386/cpu.c | 24 +++------ tests/test-qobject-output-visitor.c | 84 +++++++++-------------------- tests/test-string-output-visitor.c | 6 +-- 20 files changed, 96 insertions(+), 222 deletions(-) diff --git a/backends/hostmem.c b/backends/hostmem.c index 9f9ac95edd..be0c3b079f 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -80,7 +80,7 @@ host_memory_backend_get_host_nodes(Object *obj, Visitor *v, const char *name, { HostMemoryBackend *backend = MEMORY_BACKEND(obj); uint16List *host_nodes = NULL; - uint16List **node = &host_nodes; + uint16List **tail = &host_nodes; unsigned long value; value = find_first_bit(backend->host_nodes, MAX_NODES); @@ -88,9 +88,7 @@ host_memory_backend_get_host_nodes(Object *obj, Visitor *v, const char *name, goto ret; } - *node = g_malloc0(sizeof(**node)); - (*node)->value = value; - node = &(*node)->next; + QAPI_LIST_APPEND(tail, value); do { value = find_next_bit(backend->host_nodes, MAX_NODES, value + 1); @@ -98,9 +96,7 @@ host_memory_backend_get_host_nodes(Object *obj, Visitor *v, const char *name, break; } - *node = g_malloc0(sizeof(**node)); - (*node)->value = value; - node = &(*node)->next; + QAPI_LIST_APPEND(tail, value); } while (true); ret: diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index c01319b188..9b9cd71238 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -572,12 +572,12 @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) { BdrvDirtyBitmap *bm; BlockDirtyInfoList *list = NULL; - BlockDirtyInfoList **plist = &list; + BlockDirtyInfoList **tail = &list; bdrv_dirty_bitmaps_lock(bs); QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1); - BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1); + info->count = bdrv_get_dirty_count(bm); info->granularity = bdrv_dirty_bitmap_granularity(bm); info->has_name = !!bm->name; @@ -588,9 +588,7 @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) info->persistent = bm->persistent; info->has_inconsistent = bm->inconsistent; info->inconsistent = bm->inconsistent; - entry->value = info; - *plist = entry; - plist = &entry->next; + QAPI_LIST_APPEND(tail, info); } bdrv_dirty_bitmaps_unlock(bs); diff --git a/block/export/export.c b/block/export/export.c index b716c1522c..fec7d9f738 100644 --- a/block/export/export.c +++ b/block/export/export.c @@ -342,11 +342,10 @@ void qmp_block_export_del(const char *id, BlockExportInfoList *qmp_query_block_exports(Error **errp) { - BlockExportInfoList *head = NULL, **p_next = &head; + BlockExportInfoList *head = NULL, **tail = &head; BlockExport *exp; QLIST_FOREACH(exp, &block_exports, next) { - BlockExportInfoList *entry = g_new0(BlockExportInfoList, 1); BlockExportInfo *info = g_new(BlockExportInfo, 1); *info = (BlockExportInfo) { .id = g_strdup(exp->id), @@ -355,9 +354,7 @@ BlockExportInfoList *qmp_query_block_exports(Error **errp) .shutting_down = !exp->user_owned, }; - entry->value = info; - *p_next = entry; - p_next = &entry->next; + QAPI_LIST_APPEND(tail, info); } return head; diff --git a/block/qapi.c b/block/qapi.c index 0ca206f559..3a1186fdcc 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -418,17 +418,12 @@ static uint64List *uint64_list(uint64_t *list, int size) { int i; uint64List *out_list = NULL; - uint64List **pout_list = &out_list; + uint64List **tail = &out_list; for (i = 0; i < size; i++) { - uint64List *entry = g_new(uint64List, 1); - entry->value = list[i]; - *pout_list = entry; - pout_list = &entry->next; + QAPI_LIST_APPEND(tail, list[i]); } - *pout_list = NULL; - return out_list; } @@ -636,26 +631,21 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes, bool query_nodes, Error **errp) { - BlockStatsList *head = NULL, **p_next = &head; + BlockStatsList *head = NULL, **tail = &head; BlockBackend *blk; BlockDriverState *bs; /* Just to be safe if query_nodes is not always initialized */ if (has_query_nodes && query_nodes) { for (bs = bdrv_next_node(NULL); bs; bs = bdrv_next_node(bs)) { - BlockStatsList *info = g_malloc0(sizeof(*info)); AioContext *ctx = bdrv_get_aio_context(bs); aio_context_acquire(ctx); - info->value = bdrv_query_bds_stats(bs, false); + QAPI_LIST_APPEND(tail, bdrv_query_bds_stats(bs, false)); aio_context_release(ctx); - - *p_next = info; - p_next = &info->next; } } else { for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) { - BlockStatsList *info; AioContext *ctx = blk_get_aio_context(blk); BlockStats *s; char *qdev; @@ -680,10 +670,7 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes, bdrv_query_blk_stats(s->stats, blk); aio_context_release(ctx); - info = g_malloc0(sizeof(*info)); - info->value = s; - *p_next = info; - p_next = &info->next; + QAPI_LIST_APPEND(tail, s); } } diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index d7a31a8ddc..5eef82fa55 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -1061,7 +1061,7 @@ fail: static Qcow2BitmapInfoFlagsList *get_bitmap_info_flags(uint32_t flags) { Qcow2BitmapInfoFlagsList *list = NULL; - Qcow2BitmapInfoFlagsList **plist = &list; + Qcow2BitmapInfoFlagsList **tail = &list; int i; static const struct { @@ -1076,11 +1076,7 @@ static Qcow2BitmapInfoFlagsList *get_bitmap_info_flags(uint32_t flags) for (i = 0; i < map_size; ++i) { if (flags & map[i].bme) { - Qcow2BitmapInfoFlagsList *entry = - g_new0(Qcow2BitmapInfoFlagsList, 1); - entry->value = map[i].info; - *plist = entry; - plist = &entry->next; + QAPI_LIST_APPEND(tail, map[i].info); flags &= ~map[i].bme; } } @@ -1105,7 +1101,7 @@ Qcow2BitmapInfoList *qcow2_get_bitmap_info_list(BlockDriverState *bs, Qcow2BitmapList *bm_list; Qcow2Bitmap *bm; Qcow2BitmapInfoList *list = NULL; - Qcow2BitmapInfoList **plist = &list; + Qcow2BitmapInfoList **tail = &list; if (s->nb_bitmaps == 0) { return NULL; @@ -1119,13 +1115,10 @@ Qcow2BitmapInfoList *qcow2_get_bitmap_info_list(BlockDriverState *bs, QSIMPLEQ_FOREACH(bm, bm_list, entry) { Qcow2BitmapInfo *info = g_new0(Qcow2BitmapInfo, 1); - Qcow2BitmapInfoList *obj = g_new0(Qcow2BitmapInfoList, 1); info->granularity = 1U << bm->granularity_bits; info->name = g_strdup(bm->name); info->flags = get_bitmap_info_flags(bm->flags & ~BME_RESERVED_FLAGS); - obj->value = info; - *plist = obj; - plist = &obj->next; + QAPI_LIST_APPEND(tail, info); } bitmap_list_free(bm_list); diff --git a/block/vmdk.c b/block/vmdk.c index a00dc00eb4..4499f136bd 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -2928,7 +2928,7 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs, int i; BDRVVmdkState *s = bs->opaque; ImageInfoSpecific *spec_info = g_new0(ImageInfoSpecific, 1); - ImageInfoList **next; + ImageInfoList **tail; *spec_info = (ImageInfoSpecific){ .type = IMAGE_INFO_SPECIFIC_KIND_VMDK, @@ -2943,12 +2943,9 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs, .parent_cid = s->parent_cid, }; - next = &spec_info->u.vmdk.data->extents; + tail = &spec_info->u.vmdk.data->extents; for (i = 0; i < s->num_extents; i++) { - *next = g_new0(ImageInfoList, 1); - (*next)->value = vmdk_get_extent_info(&s->extents[i]); - (*next)->next = NULL; - next = &(*next)->next; + QAPI_LIST_APPEND(tail, vmdk_get_extent_info(&s->extents[i])); } return spec_info; diff --git a/blockdev.c b/blockdev.c index 93417f6302..b250b9b959 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3725,28 +3725,25 @@ void qmp_x_blockdev_change(const char *parent, bool has_child, BlockJobInfoList *qmp_query_block_jobs(Error **errp) { - BlockJobInfoList *head = NULL, **p_next = &head; + BlockJobInfoList *head = NULL, **tail = &head; BlockJob *job; for (job = block_job_next(NULL); job; job = block_job_next(job)) { - BlockJobInfoList *elem; + BlockJobInfo *value; AioContext *aio_context; if (block_job_is_internal(job)) { continue; } - elem = g_new0(BlockJobInfoList, 1); aio_context = blk_get_aio_context(job->blk); aio_context_acquire(aio_context); - elem->value = block_job_query(job, errp); + value = block_job_query(job, errp); aio_context_release(aio_context); - if (!elem->value) { - g_free(elem); + if (!value) { qapi_free_BlockJobInfoList(head); return NULL; } - *p_next = elem; - p_next = &elem->next; + QAPI_LIST_APPEND(tail, value); } return head; diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 564caa1094..fe8f04ffb2 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -1885,7 +1885,7 @@ static int qcrypto_block_luks_get_info(QCryptoBlock *block, { QCryptoBlockLUKS *luks = block->opaque; QCryptoBlockInfoLUKSSlot *slot; - QCryptoBlockInfoLUKSSlotList *slots = NULL, **prev = &info->u.luks.slots; + QCryptoBlockInfoLUKSSlotList **tail = &info->u.luks.slots; size_t i; info->u.luks.cipher_alg = luks->cipher_alg; @@ -1902,10 +1902,7 @@ static int qcrypto_block_luks_get_info(QCryptoBlock *block, sizeof(luks->header.uuid)); for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { - slots = g_new0(QCryptoBlockInfoLUKSSlotList, 1); - *prev = slots; - - slots->value = slot = g_new0(QCryptoBlockInfoLUKSSlot, 1); + slot = g_new0(QCryptoBlockInfoLUKSSlot, 1); slot->active = luks->header.key_slots[i].active == QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED; slot->key_offset = luks->header.key_slots[i].key_offset_sector @@ -1917,7 +1914,7 @@ static int qcrypto_block_luks_get_info(QCryptoBlock *block, slot->stripes = luks->header.key_slots[i].stripes; } - prev = &slots->next; + QAPI_LIST_APPEND(tail, slot); } return 0; diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c index 6350caa765..e2317be546 100644 --- a/hw/acpi/cpu.c +++ b/hw/acpi/cpu.c @@ -44,14 +44,11 @@ static ACPIOSTInfo *acpi_cpu_device_status(int idx, AcpiCpuStatus *cdev) void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list) { + ACPIOSTInfoList ***tail = list; int i; for (i = 0; i < cpu_st->dev_count; i++) { - ACPIOSTInfoList *elem = g_new0(ACPIOSTInfoList, 1); - elem->value = acpi_cpu_device_status(i, &cpu_st->devs[i]); - elem->next = NULL; - **list = elem; - *list = &elem->next; + QAPI_LIST_APPEND(*tail, acpi_cpu_device_status(i, &cpu_st->devs[i])); } } diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index f2552b2a46..0bdcf15528 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -53,14 +53,12 @@ static ACPIOSTInfo *acpi_memory_device_status(int slot, MemStatus *mdev) void acpi_memory_ospm_status(MemHotplugState *mem_st, ACPIOSTInfoList ***list) { + ACPIOSTInfoList ***tail = list; int i; for (i = 0; i < mem_st->dev_count; i++) { - ACPIOSTInfoList *elem = g_new0(ACPIOSTInfoList, 1); - elem->value = acpi_memory_device_status(i, &mem_st->devs[i]); - elem->next = NULL; - **list = elem; - *list = &elem->next; + QAPI_LIST_APPEND(*tail, + acpi_memory_device_status(i, &mem_st->devs[i])); } } diff --git a/iothread.c b/iothread.c index 69eff9efbc..b9f2751382 100644 --- a/iothread.c +++ b/iothread.c @@ -1,7 +1,7 @@ /* * Event loop thread * - * Copyright Red Hat Inc., 2013 + * Copyright Red Hat Inc., 2013, 2020 * * Authors: * Stefan Hajnoczi @@ -310,8 +310,7 @@ AioContext *iothread_get_aio_context(IOThread *iothread) static int query_one_iothread(Object *object, void *opaque) { - IOThreadInfoList ***prev = opaque; - IOThreadInfoList *elem; + IOThreadInfoList ***tail = opaque; IOThreadInfo *info; IOThread *iothread; @@ -327,12 +326,7 @@ static int query_one_iothread(Object *object, void *opaque) info->poll_grow = iothread->poll_grow; info->poll_shrink = iothread->poll_shrink; - elem = g_new0(IOThreadInfoList, 1); - elem->value = info; - elem->next = NULL; - - **prev = elem; - *prev = &elem->next; + QAPI_LIST_APPEND(*tail, info); return 0; } diff --git a/job-qmp.c b/job-qmp.c index 645601b2cc..34c4da094f 100644 --- a/job-qmp.c +++ b/job-qmp.c @@ -164,28 +164,25 @@ static JobInfo *job_query_single(Job *job, Error **errp) JobInfoList *qmp_query_jobs(Error **errp) { - JobInfoList *head = NULL, **p_next = &head; + JobInfoList *head = NULL, **tail = &head; Job *job; for (job = job_next(NULL); job; job = job_next(job)) { - JobInfoList *elem; + JobInfo *value; AioContext *aio_context; if (job_is_internal(job)) { continue; } - elem = g_new0(JobInfoList, 1); aio_context = job->aio_context; aio_context_acquire(aio_context); - elem->value = job_query_single(job, errp); + value = job_query_single(job, errp); aio_context_release(aio_context); - if (!elem->value) { - g_free(elem); + if (!value) { qapi_free_JobInfoList(head); return NULL; } - *p_next = elem; - p_next = &elem->next; + QAPI_LIST_APPEND(tail, value); } return head; diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 499647a578..529f18099e 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -76,20 +76,20 @@ void hmp_handle_error(Monitor *mon, Error *err) static strList *strList_from_comma_list(const char *in) { strList *res = NULL; - strList **hook = &res; + strList **tail = &res; while (in && in[0]) { char *comma = strchr(in, ','); - *hook = g_new0(strList, 1); + char *value; if (comma) { - (*hook)->value = g_strndup(in, comma - in); + value = g_strndup(in, comma - in); in = comma + 1; /* skip the , */ } else { - (*hook)->value = g_strdup(in); + value = g_strdup(in); in = NULL; } - hook = &(*hook)->next; + QAPI_LIST_APPEND(tail, value); } return res; diff --git a/qemu-img.c b/qemu-img.c index 8597d069af..e2952fe955 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -2856,7 +2856,7 @@ static ImageInfoList *collect_image_info_list(bool image_opts, bool chain, bool force_share) { ImageInfoList *head = NULL; - ImageInfoList **last = &head; + ImageInfoList **tail = &head; GHashTable *filenames; Error *err = NULL; @@ -2866,7 +2866,6 @@ static ImageInfoList *collect_image_info_list(bool image_opts, BlockBackend *blk; BlockDriverState *bs; ImageInfo *info; - ImageInfoList *elem; if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) { error_report("Backing file '%s' creates an infinite loop.", @@ -2890,10 +2889,7 @@ static ImageInfoList *collect_image_info_list(bool image_opts, goto err; } - elem = g_new0(ImageInfoList, 1); - elem->value = info; - *last = elem; - last = &elem->next; + QAPI_LIST_APPEND(tail, info); blk_unref(blk); diff --git a/qga/commands-posix.c b/qga/commands-posix.c index edf785b2da..f0a23b0402 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -2474,18 +2474,17 @@ static void transfer_vcpu(GuestLogicalProcessor *vcpu, bool sys2vcpu, GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) { int64_t current; - GuestLogicalProcessorList *head, **link; + GuestLogicalProcessorList *head, **tail; long sc_max; Error *local_err = NULL; current = 0; head = NULL; - link = &head; + tail = &head; sc_max = SYSCONF_EXACT(_SC_NPROCESSORS_CONF, &local_err); while (local_err == NULL && current < sc_max) { GuestLogicalProcessor *vcpu; - GuestLogicalProcessorList *entry; int64_t id = current++; char *path = g_strdup_printf("/sys/devices/system/cpu/cpu%" PRId64 "/", id); @@ -2495,10 +2494,7 @@ GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) vcpu->logical_id = id; vcpu->has_can_offline = true; /* lolspeak ftw */ transfer_vcpu(vcpu, true, path, &local_err); - entry = g_malloc0(sizeof *entry); - entry->value = vcpu; - *link = entry; - link = &entry->next; + QAPI_LIST_APPEND(tail, vcpu); } g_free(path); } @@ -2831,13 +2827,13 @@ out1: GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp) { - GuestMemoryBlockList *head, **link; + GuestMemoryBlockList *head, **tail; Error *local_err = NULL; struct dirent *de; DIR *dp; head = NULL; - link = &head; + tail = &head; dp = opendir("/sys/devices/system/memory/"); if (!dp) { @@ -2859,7 +2855,6 @@ GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp) */ while ((de = readdir(dp)) != NULL) { GuestMemoryBlock *mem_blk; - GuestMemoryBlockList *entry; if ((strncmp(de->d_name, "memory", 6) != 0) || !(de->d_type & DT_DIR)) { @@ -2875,11 +2870,7 @@ GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp) break; } - entry = g_malloc0(sizeof *entry); - entry->value = mem_blk; - - *link = entry; - link = &entry->next; + QAPI_LIST_APPEND(tail, mem_blk); } closedir(dp); @@ -2899,15 +2890,14 @@ GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp) GuestMemoryBlockResponseList * qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp) { - GuestMemoryBlockResponseList *head, **link; + GuestMemoryBlockResponseList *head, **tail; Error *local_err = NULL; head = NULL; - link = &head; + tail = &head; while (mem_blks != NULL) { GuestMemoryBlockResponse *result; - GuestMemoryBlockResponseList *entry; GuestMemoryBlock *current_mem_blk = mem_blks->value; result = g_malloc0(sizeof(*result)); @@ -2916,11 +2906,8 @@ qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp) if (local_err) { /* should never happen */ goto err; } - entry = g_malloc0(sizeof *entry); - entry->value = result; - *link = entry; - link = &entry->next; + QAPI_LIST_APPEND(tail, result); mem_blks = mem_blks->next; } diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 684639bd13..a6cc481bc3 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1833,7 +1833,7 @@ GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) { PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pslpi, ptr; DWORD length; - GuestLogicalProcessorList *head, **link; + GuestLogicalProcessorList *head, **tail; Error *local_err = NULL; int64_t current; @@ -1841,7 +1841,7 @@ GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) length = 0; current = 0; head = NULL; - link = &head; + tail = &head; if ((GetLogicalProcessorInformation(pslpi, &length) == FALSE) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) && @@ -1864,18 +1864,13 @@ GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) while (cpu_bits > 0) { if (!!(cpu_bits & 1)) { GuestLogicalProcessor *vcpu; - GuestLogicalProcessorList *entry; vcpu = g_malloc0(sizeof *vcpu); vcpu->logical_id = current++; vcpu->online = true; vcpu->has_can_offline = true; - entry = g_malloc0(sizeof *entry); - entry->value = vcpu; - - *link = entry; - link = &entry->next; + QAPI_LIST_APPEND(tail, vcpu); } cpu_bits >>= 1; } diff --git a/scsi/pr-manager.c b/scsi/pr-manager.c index 32b9287e68..2098d7e759 100644 --- a/scsi/pr-manager.c +++ b/scsi/pr-manager.c @@ -116,8 +116,7 @@ pr_manager_register_types(void) static int query_one_pr_manager(Object *object, void *opaque) { - PRManagerInfoList ***prev = opaque; - PRManagerInfoList *elem; + PRManagerInfoList ***tail = opaque; PRManagerInfo *info; PRManager *pr_mgr; @@ -126,15 +125,10 @@ static int query_one_pr_manager(Object *object, void *opaque) return 0; } - elem = g_new0(PRManagerInfoList, 1); info = g_new0(PRManagerInfo, 1); info->id = g_strdup(object_get_canonical_path_component(object)); info->connected = pr_manager_is_connected(pr_mgr); - elem->value = info; - elem->next = NULL; - - **prev = elem; - *prev = &elem->next; + QAPI_LIST_APPEND(*tail, info); return 0; } diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 72a79e6019..ae89024d36 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -4818,20 +4818,17 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose); /* Build a list with the name of all features on a feature word array */ static void x86_cpu_list_feature_names(FeatureWordArray features, - strList **feat_names) + strList **list) { + strList **tail = list; FeatureWord w; - strList **next = feat_names; for (w = 0; w < FEATURE_WORDS; w++) { uint64_t filtered = features[w]; int i; for (i = 0; i < 64; i++) { if (filtered & (1ULL << i)) { - strList *new = g_new0(strList, 1); - new->value = g_strdup(x86_cpu_feature_name(w, i)); - *next = new; - next = &new->next; + QAPI_LIST_APPEND(tail, g_strdup(x86_cpu_feature_name(w, i))); } } } @@ -4852,16 +4849,14 @@ static void x86_cpu_get_unavailable_features(Object *obj, Visitor *v, * running using the current machine and accelerator. */ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc, - strList **missing_feats) + strList **list) { + strList **tail = list; X86CPU *xc; Error *err = NULL; - strList **next = missing_feats; if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) { - strList *new = g_new0(strList, 1); - new->value = g_strdup("kvm"); - *missing_feats = new; + QAPI_LIST_APPEND(tail, g_strdup("kvm")); return; } @@ -4873,16 +4868,13 @@ static void x86_cpu_class_check_missing_features(X86CPUClass *xcc, * but in case it does, just report the model as not * runnable at all using the "type" property. */ - strList *new = g_new0(strList, 1); - new->value = g_strdup("type"); - *next = new; - next = &new->next; + QAPI_LIST_APPEND(tail, g_strdup("type")); error_free(err); } x86_cpu_filter_features(xc, false); - x86_cpu_list_feature_names(xc->filtered_features, next); + x86_cpu_list_feature_names(xc->filtered_features, tail); object_unref(OBJECT(xc)); } diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c index b20ab8b29b..9dc1e075e7 100644 --- a/tests/test-qobject-output-visitor.c +++ b/tests/test-qobject-output-visitor.c @@ -442,122 +442,86 @@ static void init_list_union(UserDefListUnion *cvalue) int i; switch (cvalue->type) { case USER_DEF_LIST_UNION_KIND_INTEGER: { - intList **list = &cvalue->u.integer.data; + intList **tail = &cvalue->u.integer.data; for (i = 0; i < 32; i++) { - *list = g_new0(intList, 1); - (*list)->value = i; - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, i); } break; } case USER_DEF_LIST_UNION_KIND_S8: { - int8List **list = &cvalue->u.s8.data; + int8List **tail = &cvalue->u.s8.data; for (i = 0; i < 32; i++) { - *list = g_new0(int8List, 1); - (*list)->value = i; - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, i); } break; } case USER_DEF_LIST_UNION_KIND_S16: { - int16List **list = &cvalue->u.s16.data; + int16List **tail = &cvalue->u.s16.data; for (i = 0; i < 32; i++) { - *list = g_new0(int16List, 1); - (*list)->value = i; - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, i); } break; } case USER_DEF_LIST_UNION_KIND_S32: { - int32List **list = &cvalue->u.s32.data; + int32List **tail = &cvalue->u.s32.data; for (i = 0; i < 32; i++) { - *list = g_new0(int32List, 1); - (*list)->value = i; - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, i); } break; } case USER_DEF_LIST_UNION_KIND_S64: { - int64List **list = &cvalue->u.s64.data; + int64List **tail = &cvalue->u.s64.data; for (i = 0; i < 32; i++) { - *list = g_new0(int64List, 1); - (*list)->value = i; - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, i); } break; } case USER_DEF_LIST_UNION_KIND_U8: { - uint8List **list = &cvalue->u.u8.data; + uint8List **tail = &cvalue->u.u8.data; for (i = 0; i < 32; i++) { - *list = g_new0(uint8List, 1); - (*list)->value = i; - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, i); } break; } case USER_DEF_LIST_UNION_KIND_U16: { - uint16List **list = &cvalue->u.u16.data; + uint16List **tail = &cvalue->u.u16.data; for (i = 0; i < 32; i++) { - *list = g_new0(uint16List, 1); - (*list)->value = i; - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, i); } break; } case USER_DEF_LIST_UNION_KIND_U32: { - uint32List **list = &cvalue->u.u32.data; + uint32List **tail = &cvalue->u.u32.data; for (i = 0; i < 32; i++) { - *list = g_new0(uint32List, 1); - (*list)->value = i; - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, i); } break; } case USER_DEF_LIST_UNION_KIND_U64: { - uint64List **list = &cvalue->u.u64.data; + uint64List **tail = &cvalue->u.u64.data; for (i = 0; i < 32; i++) { - *list = g_new0(uint64List, 1); - (*list)->value = i; - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, i); } break; } case USER_DEF_LIST_UNION_KIND_BOOLEAN: { - boolList **list = &cvalue->u.boolean.data; + boolList **tail = &cvalue->u.boolean.data; for (i = 0; i < 32; i++) { - *list = g_new0(boolList, 1); - (*list)->value = QEMU_IS_ALIGNED(i, 3); - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, QEMU_IS_ALIGNED(i, 3)); } break; } case USER_DEF_LIST_UNION_KIND_STRING: { - strList **list = &cvalue->u.string.data; + strList **tail = &cvalue->u.string.data; for (i = 0; i < 32; i++) { - *list = g_new0(strList, 1); - (*list)->value = g_strdup_printf("%d", i); - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, g_strdup_printf("%d", i)); } break; } case USER_DEF_LIST_UNION_KIND_NUMBER: { - numberList **list = &cvalue->u.number.data; + numberList **tail = &cvalue->u.number.data; for (i = 0; i < 32; i++) { - *list = g_new0(numberList, 1); - (*list)->value = (double)i / 3; - (*list)->next = NULL; - list = &(*list)->next; + QAPI_LIST_APPEND(tail, (double)i / 3); } break; } diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c index 0dae04b960..e2bedc5c7c 100644 --- a/tests/test-string-output-visitor.c +++ b/tests/test-string-output-visitor.c @@ -88,15 +88,13 @@ static void test_visitor_out_intList(TestOutputVisitorData *data, { int64_t value[] = {0, 1, 9, 10, 16, 15, 14, 3, 4, 5, 6, 11, 12, 13, 21, 22, INT64_MAX - 1, INT64_MAX}; - intList *list = NULL, **tmp = &list; + intList *list = NULL, **tail = &list; int i; Error *err = NULL; char *str; for (i = 0; i < ARRAY_SIZE(value); i++) { - *tmp = g_malloc0(sizeof(**tmp)); - (*tmp)->value = value[i]; - tmp = &(*tmp)->next; + QAPI_LIST_APPEND(tail, value[i]); } visit_type_intList(data->ov, NULL, &list, &err); From 95b3a8c8a82a34ca874ac0d4a9bbbdb38034acf3 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 13 Jan 2021 16:10:13 -0600 Subject: [PATCH 5/5] qapi: More complex uses of QAPI_LIST_APPEND These cases require a bit more thought to review; in each case, the code was appending to a list, but not with a FOOList **tail variable. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy Message-Id: <20210113221013.390592-6-eblake@redhat.com> Reviewed-by: Markus Armbruster [Flawed change to qmp_guest_network_get_interfaces() dropped] Signed-off-by: Markus Armbruster --- block/gluster.c | 13 ++---- block/qapi.c | 14 +----- dump/dump.c | 22 +++------ hw/core/machine-qmp-cmds.c | 93 ++++++++++++++++---------------------- hw/mem/memory-device.c | 12 +---- hw/pci/pci.c | 60 ++++++++---------------- migration/migration.c | 20 +++----- monitor/hmp-cmds.c | 25 ++++------ net/net.c | 13 +----- qga/commands-posix.c | 19 +++----- qga/commands-win32.c | 88 ++++++++++++------------------------ softmmu/tpm.c | 38 +++------------- ui/spice-core.c | 27 ++++------- 13 files changed, 141 insertions(+), 303 deletions(-) diff --git a/block/gluster.c b/block/gluster.c index 1f8699b938..e8ee14c8e9 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -514,7 +514,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf, { QemuOpts *opts; SocketAddress *gsconf = NULL; - SocketAddressList *curr = NULL; + SocketAddressList **tail; QDict *backing_options = NULL; Error *local_err = NULL; char *str = NULL; @@ -547,6 +547,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf, } gconf->path = g_strdup(ptr); qemu_opts_del(opts); + tail = &gconf->server; for (i = 0; i < num_servers; i++) { str = g_strdup_printf(GLUSTER_OPT_SERVER_PATTERN"%d.", i); @@ -655,15 +656,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf, qemu_opts_del(opts); } - if (gconf->server == NULL) { - gconf->server = g_new0(SocketAddressList, 1); - gconf->server->value = gsconf; - curr = gconf->server; - } else { - curr->next = g_new0(SocketAddressList, 1); - curr->next->value = gsconf; - curr = curr->next; - } + QAPI_LIST_APPEND(tail, gsconf); gsconf = NULL; qobject_unref(backing_options); diff --git a/block/qapi.c b/block/qapi.c index 3a1186fdcc..0a96099e36 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -198,7 +198,7 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs, { int i, sn_count; QEMUSnapshotInfo *sn_tab = NULL; - SnapshotInfoList *info_list, *cur_item = NULL, *head = NULL; + SnapshotInfoList *head = NULL, **tail = &head; SnapshotInfo *info; sn_count = bdrv_snapshot_list(bs, &sn_tab); @@ -233,17 +233,7 @@ int bdrv_query_snapshot_info_list(BlockDriverState *bs, info->icount = sn_tab[i].icount; info->has_icount = sn_tab[i].icount != -1ULL; - info_list = g_new0(SnapshotInfoList, 1); - info_list->value = info; - - /* XXX: waiting for the qapi to support qemu-queue.h types */ - if (!cur_item) { - head = cur_item = info_list; - } else { - cur_item->next = info_list; - cur_item = info_list; - } - + QAPI_LIST_APPEND(tail, info); } g_free(sn_tab); diff --git a/dump/dump.c b/dump/dump.c index dec32468d9..929138e91d 100644 --- a/dump/dump.c +++ b/dump/dump.c @@ -2030,39 +2030,29 @@ void qmp_dump_guest_memory(bool paging, const char *file, DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp) { - DumpGuestMemoryFormatList *item; DumpGuestMemoryCapability *cap = g_malloc0(sizeof(DumpGuestMemoryCapability)); + DumpGuestMemoryFormatList **tail = &cap->formats; /* elf is always available */ - item = g_malloc0(sizeof(DumpGuestMemoryFormatList)); - cap->formats = item; - item->value = DUMP_GUEST_MEMORY_FORMAT_ELF; + QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_ELF); /* kdump-zlib is always available */ - item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList)); - item = item->next; - item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB; + QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB); /* add new item if kdump-lzo is available */ #ifdef CONFIG_LZO - item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList)); - item = item->next; - item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO; + QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO); #endif /* add new item if kdump-snappy is available */ #ifdef CONFIG_SNAPPY - item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList)); - item = item->next; - item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY; + QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY); #endif /* Windows dump is available only if target is x86_64 */ #ifdef TARGET_X86_64 - item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList)); - item = item->next; - item->value = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP; + QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_WIN_DMP); #endif return cap; diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index 156223a344..44e979e503 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -28,11 +28,11 @@ CpuInfoList *qmp_query_cpus(Error **errp) { MachineState *ms = MACHINE(qdev_get_machine()); MachineClass *mc = MACHINE_GET_CLASS(ms); - CpuInfoList *head = NULL, *cur_item = NULL; + CpuInfoList *head = NULL, **tail = &head; CPUState *cpu; CPU_FOREACH(cpu) { - CpuInfoList *info; + CpuInfo *value; #if defined(TARGET_I386) X86CPU *x86_cpu = X86_CPU(cpu); CPUX86State *env = &x86_cpu->env; @@ -58,53 +58,46 @@ CpuInfoList *qmp_query_cpus(Error **errp) cpu_synchronize_state(cpu); - info = g_malloc0(sizeof(*info)); - info->value = g_malloc0(sizeof(*info->value)); - info->value->CPU = cpu->cpu_index; - info->value->current = (cpu == first_cpu); - info->value->halted = cpu->halted; - info->value->qom_path = object_get_canonical_path(OBJECT(cpu)); - info->value->thread_id = cpu->thread_id; + value = g_malloc0(sizeof(*value)); + value->CPU = cpu->cpu_index; + value->current = (cpu == first_cpu); + value->halted = cpu->halted; + value->qom_path = object_get_canonical_path(OBJECT(cpu)); + value->thread_id = cpu->thread_id; #if defined(TARGET_I386) - info->value->arch = CPU_INFO_ARCH_X86; - info->value->u.x86.pc = env->eip + env->segs[R_CS].base; + value->arch = CPU_INFO_ARCH_X86; + value->u.x86.pc = env->eip + env->segs[R_CS].base; #elif defined(TARGET_PPC) - info->value->arch = CPU_INFO_ARCH_PPC; - info->value->u.ppc.nip = env->nip; + value->arch = CPU_INFO_ARCH_PPC; + value->u.ppc.nip = env->nip; #elif defined(TARGET_SPARC) - info->value->arch = CPU_INFO_ARCH_SPARC; - info->value->u.q_sparc.pc = env->pc; - info->value->u.q_sparc.npc = env->npc; + value->arch = CPU_INFO_ARCH_SPARC; + value->u.q_sparc.pc = env->pc; + value->u.q_sparc.npc = env->npc; #elif defined(TARGET_MIPS) - info->value->arch = CPU_INFO_ARCH_MIPS; - info->value->u.q_mips.PC = env->active_tc.PC; + value->arch = CPU_INFO_ARCH_MIPS; + value->u.q_mips.PC = env->active_tc.PC; #elif defined(TARGET_TRICORE) - info->value->arch = CPU_INFO_ARCH_TRICORE; - info->value->u.tricore.PC = env->PC; + value->arch = CPU_INFO_ARCH_TRICORE; + value->u.tricore.PC = env->PC; #elif defined(TARGET_S390X) - info->value->arch = CPU_INFO_ARCH_S390; - info->value->u.s390.cpu_state = env->cpu_state; + value->arch = CPU_INFO_ARCH_S390; + value->u.s390.cpu_state = env->cpu_state; #elif defined(TARGET_RISCV) - info->value->arch = CPU_INFO_ARCH_RISCV; - info->value->u.riscv.pc = env->pc; + value->arch = CPU_INFO_ARCH_RISCV; + value->u.riscv.pc = env->pc; #else - info->value->arch = CPU_INFO_ARCH_OTHER; + value->arch = CPU_INFO_ARCH_OTHER; #endif - info->value->has_props = !!mc->cpu_index_to_instance_props; - if (info->value->has_props) { + value->has_props = !!mc->cpu_index_to_instance_props; + if (value->has_props) { CpuInstanceProperties *props; props = g_malloc0(sizeof(*props)); *props = mc->cpu_index_to_instance_props(ms, cpu->cpu_index); - info->value->props = props; + value->props = props; } - /* XXX: waiting for the qapi to support GSList */ - if (!cur_item) { - head = cur_item = info; - } else { - cur_item->next = info; - cur_item = info; - } + QAPI_LIST_APPEND(tail, value); } return head; @@ -170,39 +163,33 @@ CpuInfoFastList *qmp_query_cpus_fast(Error **errp) { MachineState *ms = MACHINE(qdev_get_machine()); MachineClass *mc = MACHINE_GET_CLASS(ms); - CpuInfoFastList *head = NULL, *cur_item = NULL; + CpuInfoFastList *head = NULL, **tail = &head; SysEmuTarget target = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME, -1, &error_abort); CPUState *cpu; CPU_FOREACH(cpu) { - CpuInfoFastList *info = g_malloc0(sizeof(*info)); - info->value = g_malloc0(sizeof(*info->value)); + CpuInfoFast *value = g_malloc0(sizeof(*value)); - info->value->cpu_index = cpu->cpu_index; - info->value->qom_path = object_get_canonical_path(OBJECT(cpu)); - info->value->thread_id = cpu->thread_id; + value->cpu_index = cpu->cpu_index; + value->qom_path = object_get_canonical_path(OBJECT(cpu)); + value->thread_id = cpu->thread_id; - info->value->has_props = !!mc->cpu_index_to_instance_props; - if (info->value->has_props) { + value->has_props = !!mc->cpu_index_to_instance_props; + if (value->has_props) { CpuInstanceProperties *props; props = g_malloc0(sizeof(*props)); *props = mc->cpu_index_to_instance_props(ms, cpu->cpu_index); - info->value->props = props; + value->props = props; } - info->value->arch = sysemu_target_to_cpuinfo_arch(target); - info->value->target = target; + value->arch = sysemu_target_to_cpuinfo_arch(target); + value->target = target; if (target == SYS_EMU_TARGET_S390X) { - cpustate_to_cpuinfo_s390(&info->value->u.s390x, cpu); + cpustate_to_cpuinfo_s390(&value->u.s390x, cpu); } - if (!cur_item) { - head = cur_item = info; - } else { - cur_item->next = info; - cur_item = info; - } + QAPI_LIST_APPEND(tail, value); } return head; diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c index cf0627fd01..d9f8301711 100644 --- a/hw/mem/memory-device.c +++ b/hw/mem/memory-device.c @@ -199,7 +199,7 @@ out: MemoryDeviceInfoList *qmp_memory_device_list(void) { GSList *devices = NULL, *item; - MemoryDeviceInfoList *list = NULL, *prev = NULL; + MemoryDeviceInfoList *list = NULL, **tail = &list; object_child_foreach(qdev_get_machine(), memory_device_build_list, &devices); @@ -207,19 +207,11 @@ MemoryDeviceInfoList *qmp_memory_device_list(void) for (item = devices; item; item = g_slist_next(item)) { const MemoryDeviceState *md = MEMORY_DEVICE(item->data); const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(item->data); - MemoryDeviceInfoList *elem = g_new0(MemoryDeviceInfoList, 1); MemoryDeviceInfo *info = g_new0(MemoryDeviceInfo, 1); mdc->fill_device_info(md, info); - elem->value = info; - elem->next = NULL; - if (prev) { - prev->next = elem; - } else { - list = elem; - } - prev = elem; + QAPI_LIST_APPEND(tail, info); } g_slist_free(devices); diff --git a/hw/pci/pci.c b/hw/pci/pci.c index a6b0c5602e..512e9042ff 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1683,41 +1683,34 @@ static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num); static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev) { - PciMemoryRegionList *head = NULL, *cur_item = NULL; + PciMemoryRegionList *head = NULL, **tail = &head; int i; for (i = 0; i < PCI_NUM_REGIONS; i++) { const PCIIORegion *r = &dev->io_regions[i]; - PciMemoryRegionList *region; + PciMemoryRegion *region; if (!r->size) { continue; } region = g_malloc0(sizeof(*region)); - region->value = g_malloc0(sizeof(*region->value)); if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { - region->value->type = g_strdup("io"); + region->type = g_strdup("io"); } else { - region->value->type = g_strdup("memory"); - region->value->has_prefetch = true; - region->value->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH); - region->value->has_mem_type_64 = true; - region->value->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64); + region->type = g_strdup("memory"); + region->has_prefetch = true; + region->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH); + region->has_mem_type_64 = true; + region->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64); } - region->value->bar = i; - region->value->address = r->addr; - region->value->size = r->size; + region->bar = i; + region->address = r->addr; + region->size = r->size; - /* XXX: waiting for the qapi to support GSList */ - if (!cur_item) { - head = cur_item = region; - } else { - cur_item->next = region; - cur_item = region; - } + QAPI_LIST_APPEND(tail, region); } return head; @@ -1814,23 +1807,14 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus, static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num) { - PciDeviceInfoList *info, *head = NULL, *cur_item = NULL; + PciDeviceInfoList *head = NULL, **tail = &head; PCIDevice *dev; int devfn; for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { dev = bus->devices[devfn]; if (dev) { - info = g_malloc0(sizeof(*info)); - info->value = qmp_query_pci_device(dev, bus, bus_num); - - /* XXX: waiting for the qapi to support GSList */ - if (!cur_item) { - head = cur_item = info; - } else { - cur_item->next = info; - cur_item = info; - } + QAPI_LIST_APPEND(tail, qmp_query_pci_device(dev, bus, bus_num)); } } @@ -1853,21 +1837,13 @@ static PciInfo *qmp_query_pci_bus(PCIBus *bus, int bus_num) PciInfoList *qmp_query_pci(Error **errp) { - PciInfoList *info, *head = NULL, *cur_item = NULL; + PciInfoList *head = NULL, **tail = &head; PCIHostState *host_bridge; QLIST_FOREACH(host_bridge, &pci_host_bridges, next) { - info = g_malloc0(sizeof(*info)); - info->value = qmp_query_pci_bus(host_bridge->bus, - pci_bus_num(host_bridge->bus)); - - /* XXX: waiting for the qapi to support GSList */ - if (!cur_item) { - head = cur_item = info; - } else { - cur_item->next = info; - cur_item = info; - } + QAPI_LIST_APPEND(tail, + qmp_query_pci_bus(host_bridge->bus, + pci_bus_num(host_bridge->bus))); } return head; diff --git a/migration/migration.c b/migration/migration.c index d5136419bf..1986cb8573 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -793,29 +793,21 @@ void migrate_send_rp_resume_ack(MigrationIncomingState *mis, uint32_t value) MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) { - MigrationCapabilityStatusList *head = NULL; - MigrationCapabilityStatusList *caps; + MigrationCapabilityStatusList *head = NULL, **tail = &head; + MigrationCapabilityStatus *caps; MigrationState *s = migrate_get_current(); int i; - caps = NULL; /* silence compiler warning */ for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { #ifndef CONFIG_LIVE_BLOCK_MIGRATION if (i == MIGRATION_CAPABILITY_BLOCK) { continue; } #endif - if (head == NULL) { - head = g_malloc0(sizeof(*caps)); - caps = head; - } else { - caps->next = g_malloc0(sizeof(*caps)); - caps = caps->next; - } - caps->value = - g_malloc(sizeof(*caps->value)); - caps->value->capability = i; - caps->value->state = s->enabled_capabilities[i]; + caps = g_malloc0(sizeof(*caps)); + caps->capability = i; + caps->state = s->enabled_capabilities[i]; + QAPI_LIST_APPEND(tail, caps); } return head; diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 529f18099e..a48bc1e904 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -1706,7 +1706,8 @@ void hmp_closefd(Monitor *mon, const QDict *qdict) void hmp_sendkey(Monitor *mon, const QDict *qdict) { const char *keys = qdict_get_str(qdict, "keys"); - KeyValueList *keylist, *head = NULL, *tmp = NULL; + KeyValue *v = NULL; + KeyValueList *head = NULL, **tail = &head; int has_hold_time = qdict_haskey(qdict, "hold-time"); int hold_time = qdict_get_try_int(qdict, "hold-time", -1); Error *err = NULL; @@ -1723,16 +1724,7 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict) keyname_len = 4; } - keylist = g_malloc0(sizeof(*keylist)); - keylist->value = g_malloc0(sizeof(*keylist->value)); - - if (!head) { - head = keylist; - } - if (tmp) { - tmp->next = keylist; - } - tmp = keylist; + v = g_malloc0(sizeof(*v)); if (strstart(keys, "0x", NULL)) { char *endp; @@ -1741,16 +1733,18 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict) if (endp != keys + keyname_len) { goto err_out; } - keylist->value->type = KEY_VALUE_KIND_NUMBER; - keylist->value->u.number.data = value; + v->type = KEY_VALUE_KIND_NUMBER; + v->u.number.data = value; } else { int idx = index_from_key(keys, keyname_len); if (idx == Q_KEY_CODE__MAX) { goto err_out; } - keylist->value->type = KEY_VALUE_KIND_QCODE; - keylist->value->u.qcode.data = idx; + v->type = KEY_VALUE_KIND_QCODE; + v->u.qcode.data = idx; } + QAPI_LIST_APPEND(tail, v); + v = NULL; if (!*separator) { break; @@ -1762,6 +1756,7 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, err); out: + qapi_free_KeyValue(v); qapi_free_KeyValueList(head); return; diff --git a/net/net.c b/net/net.c index 2afac24b79..fb7b7dcc25 100644 --- a/net/net.c +++ b/net/net.c @@ -1213,10 +1213,9 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name, Error **errp) { NetClientState *nc; - RxFilterInfoList *filter_list = NULL, *last_entry = NULL; + RxFilterInfoList *filter_list = NULL, **tail = &filter_list; QTAILQ_FOREACH(nc, &net_clients, next) { - RxFilterInfoList *entry; RxFilterInfo *info; if (has_name && strcmp(nc->name, name) != 0) { @@ -1241,15 +1240,7 @@ RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name, if (nc->info->query_rx_filter) { info = nc->info->query_rx_filter(nc); - entry = g_malloc0(sizeof(*entry)); - entry->value = info; - - if (!filter_list) { - filter_list = entry; - } else { - last_entry->next = entry; - } - last_entry = entry; + QAPI_LIST_APPEND(tail, info); } else if (has_name) { error_setg(errp, "net client(%s) doesn't support" " rx-filter querying", name); diff --git a/qga/commands-posix.c b/qga/commands-posix.c index f0a23b0402..8dd94a3314 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -3138,11 +3138,10 @@ static double ga_get_login_time(struct utmpx *user_info) GuestUserList *qmp_guest_get_users(Error **errp) { GHashTable *cache = NULL; - GuestUserList *head = NULL, *cur_item = NULL; + GuestUserList *head = NULL, **tail = &head; struct utmpx *user_info = NULL; gpointer value = NULL; GuestUser *user = NULL; - GuestUserList *item = NULL; double login_time = 0; cache = g_hash_table_new(g_str_hash, g_str_equal); @@ -3165,19 +3164,13 @@ GuestUserList *qmp_guest_get_users(Error **errp) continue; } - item = g_new0(GuestUserList, 1); - item->value = g_new0(GuestUser, 1); - item->value->user = g_strdup(user_info->ut_user); - item->value->login_time = ga_get_login_time(user_info); + user = g_new0(GuestUser, 1); + user->user = g_strdup(user_info->ut_user); + user->login_time = ga_get_login_time(user_info); - g_hash_table_insert(cache, item->value->user, item->value); + g_hash_table_insert(cache, user->user, user); - if (!cur_item) { - head = cur_item = item; - } else { - cur_item->next = item; - cur_item = item; - } + QAPI_LIST_APPEND(tail, user); } endutxent(); g_hash_table_destroy(cache); diff --git a/qga/commands-win32.c b/qga/commands-win32.c index a6cc481bc3..a00e6cb165 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1624,11 +1624,11 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) { IP_ADAPTER_ADDRESSES *adptr_addrs, *addr; IP_ADAPTER_UNICAST_ADDRESS *ip_addr = NULL; - GuestNetworkInterfaceList *head = NULL, *cur_item = NULL; - GuestIpAddressList *head_addr, *cur_addr; - GuestNetworkInterfaceList *info; + GuestNetworkInterfaceList *head = NULL, **tail = &head; + GuestIpAddressList *head_addr, **tail_addr; + GuestNetworkInterface *info; GuestNetworkInterfaceStat *interface_stat = NULL; - GuestIpAddressList *address_item = NULL; + GuestIpAddress *address_item = NULL; unsigned char *mac_addr; char *addr_str; WORD wsa_version; @@ -1651,30 +1651,24 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) for (addr = adptr_addrs; addr; addr = addr->Next) { info = g_malloc0(sizeof(*info)); - if (cur_item == NULL) { - head = cur_item = info; - } else { - cur_item->next = info; - cur_item = info; - } + QAPI_LIST_APPEND(tail, info); - info->value = g_malloc0(sizeof(*info->value)); - info->value->name = guest_wctomb_dup(addr->FriendlyName); + info->name = guest_wctomb_dup(addr->FriendlyName); if (addr->PhysicalAddressLength != 0) { mac_addr = addr->PhysicalAddress; - info->value->hardware_address = + info->hardware_address = g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", (int) mac_addr[0], (int) mac_addr[1], (int) mac_addr[2], (int) mac_addr[3], (int) mac_addr[4], (int) mac_addr[5]); - info->value->has_hardware_address = true; + info->has_hardware_address = true; } head_addr = NULL; - cur_addr = NULL; + tail_addr = &head_addr; for (ip_addr = addr->FirstUnicastAddress; ip_addr; ip_addr = ip_addr->Next) { @@ -1685,37 +1679,29 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) address_item = g_malloc0(sizeof(*address_item)); - if (!cur_addr) { - head_addr = cur_addr = address_item; - } else { - cur_addr->next = address_item; - cur_addr = address_item; - } + QAPI_LIST_APPEND(tail_addr, address_item); - address_item->value = g_malloc0(sizeof(*address_item->value)); - address_item->value->ip_address = addr_str; - address_item->value->prefix = guest_ip_prefix(ip_addr); + address_item->ip_address = addr_str; + address_item->prefix = guest_ip_prefix(ip_addr); if (ip_addr->Address.lpSockaddr->sa_family == AF_INET) { - address_item->value->ip_address_type = - GUEST_IP_ADDRESS_TYPE_IPV4; + address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4; } else if (ip_addr->Address.lpSockaddr->sa_family == AF_INET6) { - address_item->value->ip_address_type = - GUEST_IP_ADDRESS_TYPE_IPV6; + address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6; } } if (head_addr) { - info->value->has_ip_addresses = true; - info->value->ip_addresses = head_addr; + info->has_ip_addresses = true; + info->ip_addresses = head_addr; } - if (!info->value->has_statistics) { + if (!info->has_statistics) { interface_stat = g_malloc0(sizeof(*interface_stat)); if (guest_get_network_stats(addr->AdapterName, interface_stat) == -1) { - info->value->has_statistics = false; + info->has_statistics = false; g_free(interface_stat); } else { - info->value->statistics = interface_stat; - info->value->has_statistics = true; + info->statistics = interface_stat; + info->has_statistics = true; } } } @@ -2082,12 +2068,11 @@ GuestUserList *qmp_guest_get_users(Error **errp) #define QGA_NANOSECONDS 10000000 GHashTable *cache = NULL; - GuestUserList *head = NULL, *cur_item = NULL; + GuestUserList *head = NULL, **tail = &head; DWORD buffer_size = 0, count = 0, i = 0; GA_WTSINFOA *info = NULL; WTS_SESSION_INFOA *entries = NULL; - GuestUserList *item = NULL; GuestUser *user = NULL; gpointer value = NULL; INT64 login = 0; @@ -2123,23 +2108,17 @@ GuestUserList *qmp_guest_get_users(Error **errp) user->login_time = login_time; } } else { - item = g_new0(GuestUserList, 1); - item->value = g_new0(GuestUser, 1); + user = g_new0(GuestUser, 1); - item->value->user = g_strdup(info->UserName); - item->value->domain = g_strdup(info->Domain); - item->value->has_domain = true; + user->user = g_strdup(info->UserName); + user->domain = g_strdup(info->Domain); + user->has_domain = true; - item->value->login_time = login_time; + user->login_time = login_time; - g_hash_table_add(cache, item->value->user); + g_hash_table_add(cache, user->user); - if (!cur_item) { - head = cur_item = item; - } else { - cur_item->next = item; - cur_item = item; - } + QAPI_LIST_APPEND(tail, user); } } WTSFreeMemory(info); @@ -2424,7 +2403,7 @@ static GStrv ga_get_hardware_ids(DEVINST devInstance) GuestDeviceInfoList *qmp_guest_get_devices(Error **errp) { - GuestDeviceInfoList *head = NULL, *cur_item = NULL, *item = NULL; + GuestDeviceInfoList *head = NULL, **tail = &head; HDEVINFO dev_info = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA dev_info_data; int i, j; @@ -2522,14 +2501,7 @@ GuestDeviceInfoList *qmp_guest_get_devices(Error **errp) slog("driver: %s\ndriver version: %" PRId64 ",%s\n", device->driver_name, device->driver_date, device->driver_version); - item = g_new0(GuestDeviceInfoList, 1); - item->value = g_steal_pointer(&device); - if (!cur_item) { - head = cur_item = item; - } else { - cur_item->next = item; - cur_item = item; - } + QAPI_LIST_APPEND(tail, g_steal_pointer(&device)); } if (dev_info != INVALID_HANDLE_VALUE) { diff --git a/softmmu/tpm.c b/softmmu/tpm.c index cab206355a..578563f05a 100644 --- a/softmmu/tpm.c +++ b/softmmu/tpm.c @@ -196,22 +196,14 @@ int tpm_config_parse(QemuOptsList *opts_list, const char *optarg) TPMInfoList *qmp_query_tpm(Error **errp) { TPMBackend *drv; - TPMInfoList *info, *head = NULL, *cur_item = NULL; + TPMInfoList *head = NULL, **tail = &head; QLIST_FOREACH(drv, &tpm_backends, list) { if (!drv->tpmif) { continue; } - info = g_new0(TPMInfoList, 1); - info->value = tpm_backend_query_tpm(drv); - - if (!cur_item) { - head = cur_item = info; - } else { - cur_item->next = info; - cur_item = info; - } + QAPI_LIST_APPEND(tail, tpm_backend_query_tpm(drv)); } return head; @@ -220,44 +212,26 @@ TPMInfoList *qmp_query_tpm(Error **errp) TpmTypeList *qmp_query_tpm_types(Error **errp) { unsigned int i = 0; - TpmTypeList *head = NULL, *prev = NULL, *cur_item; + TpmTypeList *head = NULL, **tail = &head; for (i = 0; i < TPM_TYPE__MAX; i++) { if (!tpm_be_find_by_type(i)) { continue; } - cur_item = g_new0(TpmTypeList, 1); - cur_item->value = i; - - if (prev) { - prev->next = cur_item; - } - if (!head) { - head = cur_item; - } - prev = cur_item; + QAPI_LIST_APPEND(tail, i); } return head; } TpmModelList *qmp_query_tpm_models(Error **errp) { - TpmModelList *head = NULL, *prev = NULL, *cur_item; + TpmModelList *head = NULL, **tail = &head; GSList *e, *l = object_class_get_list(TYPE_TPM_IF, false); for (e = l; e; e = e->next) { TPMIfClass *c = TPM_IF_CLASS(e->data); - cur_item = g_new0(TpmModelList, 1); - cur_item->value = c->model; - - if (prev) { - prev->next = cur_item; - } - if (!head) { - head = cur_item; - } - prev = cur_item; + QAPI_LIST_APPEND(tail, c->model); } g_slist_free(l); diff --git a/ui/spice-core.c b/ui/spice-core.c index 5746d0aae7..514c0f9754 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -354,11 +354,11 @@ static const char *wan_compression_names[] = { static SpiceChannelList *qmp_query_spice_channels(void) { - SpiceChannelList *cur_item = NULL, *head = NULL; + SpiceChannelList *head = NULL, **tail = &head; ChannelList *item; QTAILQ_FOREACH(item, &channel_list, link) { - SpiceChannelList *chan; + SpiceChannel *chan; char host[NI_MAXHOST], port[NI_MAXSERV]; struct sockaddr *paddr; socklen_t plen; @@ -366,29 +366,22 @@ static SpiceChannelList *qmp_query_spice_channels(void) assert(item->info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT); chan = g_malloc0(sizeof(*chan)); - chan->value = g_malloc0(sizeof(*chan->value)); paddr = (struct sockaddr *)&item->info->paddr_ext; plen = item->info->plen_ext; getnameinfo(paddr, plen, host, sizeof(host), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); - chan->value->host = g_strdup(host); - chan->value->port = g_strdup(port); - chan->value->family = inet_netfamily(paddr->sa_family); + chan->host = g_strdup(host); + chan->port = g_strdup(port); + chan->family = inet_netfamily(paddr->sa_family); - chan->value->connection_id = item->info->connection_id; - chan->value->channel_type = item->info->type; - chan->value->channel_id = item->info->id; - chan->value->tls = item->info->flags & SPICE_CHANNEL_EVENT_FLAG_TLS; + chan->connection_id = item->info->connection_id; + chan->channel_type = item->info->type; + chan->channel_id = item->info->id; + chan->tls = item->info->flags & SPICE_CHANNEL_EVENT_FLAG_TLS; - /* XXX: waiting for the qapi to support GSList */ - if (!cur_item) { - head = cur_item = chan; - } else { - cur_item->next = chan; - cur_item = chan; - } + QAPI_LIST_APPEND(tail, chan); } return head;