QAPI patches
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWNyfLAAoJEDhwtADrkYZTV1sP/3doWfI6jU70z+C8RkKM5cEr 10T1G1cKAIRy4ji5CFzRY0/L8lQy6svBrwU6OZUKf9ZM+j2thG7IIibU8N/93DPE bXvcKgVvy873mfq9SoJM1OaqtqVoEepyKZ3snsYVTL5aiJ0E7I0tIcpohnKjxoRs kYcDdv3fID3bk9d9I9sSRYy7W2KL4aicR9x3WKYCVtxRIoZjAQZiJH44iuJUfA6z isxeghJEq2TP5bjBKf8/uMp2+nN8UJagWENf+aGaK1R5MFlHSMGuV1HyVJESZl0U pU8pdathbHx5UUigUQLhzpFDxiqs3fNDODplKe6cIs3zylQBO2djsMRw07/FjBCb QJqJCQrtKXfmCBxAIBa11X/rNeKfigm/GAOAZ1SF1Esk5J7CAX8qwFBlUlpR5OCM ycHzKm8T/zoZN7Hc0Ay/CdDlkRjNXpf51kg4qp14aPiZAcv8sRtWwv0qtIUdzCUM rsrgR0k1vvNp48u+9VeG7SV+PrurP8Mn1y5mthmwJkUJNUo/i1SPoOL/ZG71z4kD Otu5btrLPcJDrHf/nmXEtp1//eRrZPfBE8jHbNEMXMjqZ/wFKchWdJCnXDQ/yjE0 OHp+EaThOvLvUtSnPYgPT7agJFbZZfjXvOheHeAi3dPl3zRdzLUeVAGOI0e2mCAq VPlkkpeIaVOFgzxjaGVL =XPNe -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2015-11-02' into staging QAPI patches # gpg: Signature made Mon 02 Nov 2015 09:07:23 GMT using RSA key ID EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" * remotes/armbru/tags/pull-qapi-2015-11-02: (25 commits) qapi: Simplify gen_struct_field() qapi: Reserve 'u' member name qapi: Finish converting to new qapi union layout tpm: Convert to new qapi union layout memory: Convert to new qapi union layout input: Convert to new qapi union layout char: Convert to new qapi union layout net: Convert to new qapi union layout sockets: Convert to new qapi union layout block: Convert to new qapi union layout tests: Convert to new qapi union layout qapi-visit: Convert to new qapi union layout qapi: Start converting to new qapi union layout qapi-visit: Remove redundant functions for flat union base qapi: Unbox base members qapi: Prefer typesafe upcasts to qapi base classes qapi-types: Refactor base fields output qapi-visit: Split off visit_type_FOO_fields forward decl vnc: Hoist allocation of VncBasicInfo to callers qapi: Reserve 'q_*' and 'has_*' member names ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
						commit
						3d861a0109
					
				
							
								
								
									
										18
									
								
								block/nbd.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								block/nbd.c
									
									
									
									
									
								
							@ -206,24 +206,24 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, char **export,
 | 
			
		||||
    saddr = g_new0(SocketAddress, 1);
 | 
			
		||||
 | 
			
		||||
    if (qdict_haskey(options, "path")) {
 | 
			
		||||
        saddr->kind = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        saddr->q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
        saddr->q_unix->path = g_strdup(qdict_get_str(options, "path"));
 | 
			
		||||
        saddr->type = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
        saddr->u.q_unix->path = g_strdup(qdict_get_str(options, "path"));
 | 
			
		||||
        qdict_del(options, "path");
 | 
			
		||||
    } else {
 | 
			
		||||
        saddr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
        saddr->inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
        saddr->inet->host = g_strdup(qdict_get_str(options, "host"));
 | 
			
		||||
        saddr->type = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
        saddr->u.inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
        saddr->u.inet->host = g_strdup(qdict_get_str(options, "host"));
 | 
			
		||||
        if (!qdict_get_try_str(options, "port")) {
 | 
			
		||||
            saddr->inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
 | 
			
		||||
            saddr->u.inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
 | 
			
		||||
        } else {
 | 
			
		||||
            saddr->inet->port = g_strdup(qdict_get_str(options, "port"));
 | 
			
		||||
            saddr->u.inet->port = g_strdup(qdict_get_str(options, "port"));
 | 
			
		||||
        }
 | 
			
		||||
        qdict_del(options, "host");
 | 
			
		||||
        qdict_del(options, "port");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->client.is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
    s->client.is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
 | 
			
		||||
    *export = g_strdup(qdict_get_try_str(options, "export"));
 | 
			
		||||
    if (*export) {
 | 
			
		||||
 | 
			
		||||
@ -2738,18 +2738,16 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
 | 
			
		||||
    ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1);
 | 
			
		||||
 | 
			
		||||
    *spec_info = (ImageInfoSpecific){
 | 
			
		||||
        .kind  = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
 | 
			
		||||
        {
 | 
			
		||||
            .qcow2 = g_new(ImageInfoSpecificQCow2, 1),
 | 
			
		||||
        },
 | 
			
		||||
        .type  = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
 | 
			
		||||
        .u.qcow2 = g_new(ImageInfoSpecificQCow2, 1),
 | 
			
		||||
    };
 | 
			
		||||
    if (s->qcow_version == 2) {
 | 
			
		||||
        *spec_info->qcow2 = (ImageInfoSpecificQCow2){
 | 
			
		||||
        *spec_info->u.qcow2 = (ImageInfoSpecificQCow2){
 | 
			
		||||
            .compat             = g_strdup("0.10"),
 | 
			
		||||
            .refcount_bits      = s->refcount_bits,
 | 
			
		||||
        };
 | 
			
		||||
    } else if (s->qcow_version == 3) {
 | 
			
		||||
        *spec_info->qcow2 = (ImageInfoSpecificQCow2){
 | 
			
		||||
        *spec_info->u.qcow2 = (ImageInfoSpecificQCow2){
 | 
			
		||||
            .compat             = g_strdup("1.1"),
 | 
			
		||||
            .lazy_refcounts     = s->compatible_features &
 | 
			
		||||
                                  QCOW2_COMPAT_LAZY_REFCOUNTS,
 | 
			
		||||
 | 
			
		||||
@ -2161,19 +2161,19 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)
 | 
			
		||||
    ImageInfoList **next;
 | 
			
		||||
 | 
			
		||||
    *spec_info = (ImageInfoSpecific){
 | 
			
		||||
        .kind = IMAGE_INFO_SPECIFIC_KIND_VMDK,
 | 
			
		||||
        .type = IMAGE_INFO_SPECIFIC_KIND_VMDK,
 | 
			
		||||
        {
 | 
			
		||||
            .vmdk = g_new0(ImageInfoSpecificVmdk, 1),
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    *spec_info->vmdk = (ImageInfoSpecificVmdk) {
 | 
			
		||||
    *spec_info->u.vmdk = (ImageInfoSpecificVmdk) {
 | 
			
		||||
        .create_type = g_strdup(s->create_type),
 | 
			
		||||
        .cid = s->cid,
 | 
			
		||||
        .parent_cid = s->parent_cid,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    next = &spec_info->vmdk->extents;
 | 
			
		||||
    next = &spec_info->u.vmdk->extents;
 | 
			
		||||
    for (i = 0; i < s->num_extents; i++) {
 | 
			
		||||
        *next = g_new0(ImageInfoList, 1);
 | 
			
		||||
        (*next)->value = vmdk_get_extent_info(&s->extents[i]);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										47
									
								
								blockdev.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								blockdev.c
									
									
									
									
									
								
							@ -1137,13 +1137,14 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void blockdev_do_action(int kind, void *data, Error **errp)
 | 
			
		||||
static void blockdev_do_action(TransactionActionKind type, void *data,
 | 
			
		||||
                               Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    TransactionAction action;
 | 
			
		||||
    TransactionActionList list;
 | 
			
		||||
 | 
			
		||||
    action.kind = kind;
 | 
			
		||||
    action.data = data;
 | 
			
		||||
    action.type = type;
 | 
			
		||||
    action.u.data = data;
 | 
			
		||||
    list.value = &action;
 | 
			
		||||
    list.next = NULL;
 | 
			
		||||
    qmp_transaction(&list, errp);
 | 
			
		||||
@ -1388,9 +1389,9 @@ static void internal_snapshot_prepare(BlkTransactionState *common,
 | 
			
		||||
    InternalSnapshotState *state;
 | 
			
		||||
    int ret1;
 | 
			
		||||
 | 
			
		||||
    g_assert(common->action->kind ==
 | 
			
		||||
    g_assert(common->action->type ==
 | 
			
		||||
             TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC);
 | 
			
		||||
    internal = common->action->blockdev_snapshot_internal_sync;
 | 
			
		||||
    internal = common->action->u.blockdev_snapshot_internal_sync;
 | 
			
		||||
    state = DO_UPCAST(InternalSnapshotState, common, common);
 | 
			
		||||
 | 
			
		||||
    /* 1. parse input */
 | 
			
		||||
@ -1536,22 +1537,22 @@ static void external_snapshot_prepare(BlkTransactionState *common,
 | 
			
		||||
    TransactionAction *action = common->action;
 | 
			
		||||
 | 
			
		||||
    /* get parameters */
 | 
			
		||||
    g_assert(action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);
 | 
			
		||||
    g_assert(action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC);
 | 
			
		||||
 | 
			
		||||
    has_device = action->blockdev_snapshot_sync->has_device;
 | 
			
		||||
    device = action->blockdev_snapshot_sync->device;
 | 
			
		||||
    has_node_name = action->blockdev_snapshot_sync->has_node_name;
 | 
			
		||||
    node_name = action->blockdev_snapshot_sync->node_name;
 | 
			
		||||
    has_device = action->u.blockdev_snapshot_sync->has_device;
 | 
			
		||||
    device = action->u.blockdev_snapshot_sync->device;
 | 
			
		||||
    has_node_name = action->u.blockdev_snapshot_sync->has_node_name;
 | 
			
		||||
    node_name = action->u.blockdev_snapshot_sync->node_name;
 | 
			
		||||
    has_snapshot_node_name =
 | 
			
		||||
        action->blockdev_snapshot_sync->has_snapshot_node_name;
 | 
			
		||||
    snapshot_node_name = action->blockdev_snapshot_sync->snapshot_node_name;
 | 
			
		||||
        action->u.blockdev_snapshot_sync->has_snapshot_node_name;
 | 
			
		||||
    snapshot_node_name = action->u.blockdev_snapshot_sync->snapshot_node_name;
 | 
			
		||||
 | 
			
		||||
    new_image_file = action->blockdev_snapshot_sync->snapshot_file;
 | 
			
		||||
    if (action->blockdev_snapshot_sync->has_format) {
 | 
			
		||||
        format = action->blockdev_snapshot_sync->format;
 | 
			
		||||
    new_image_file = action->u.blockdev_snapshot_sync->snapshot_file;
 | 
			
		||||
    if (action->u.blockdev_snapshot_sync->has_format) {
 | 
			
		||||
        format = action->u.blockdev_snapshot_sync->format;
 | 
			
		||||
    }
 | 
			
		||||
    if (action->blockdev_snapshot_sync->has_mode) {
 | 
			
		||||
        mode = action->blockdev_snapshot_sync->mode;
 | 
			
		||||
    if (action->u.blockdev_snapshot_sync->has_mode) {
 | 
			
		||||
        mode = action->u.blockdev_snapshot_sync->mode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* start processing */
 | 
			
		||||
@ -1681,8 +1682,8 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
 | 
			
		||||
    DriveBackup *backup;
 | 
			
		||||
    Error *local_err = NULL;
 | 
			
		||||
 | 
			
		||||
    assert(common->action->kind == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
 | 
			
		||||
    backup = common->action->drive_backup;
 | 
			
		||||
    assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
 | 
			
		||||
    backup = common->action->u.drive_backup;
 | 
			
		||||
 | 
			
		||||
    blk = blk_by_name(backup->device);
 | 
			
		||||
    if (!blk) {
 | 
			
		||||
@ -1754,8 +1755,8 @@ static void blockdev_backup_prepare(BlkTransactionState *common, Error **errp)
 | 
			
		||||
    BlockBackend *blk, *target;
 | 
			
		||||
    Error *local_err = NULL;
 | 
			
		||||
 | 
			
		||||
    assert(common->action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
 | 
			
		||||
    backup = common->action->blockdev_backup;
 | 
			
		||||
    assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
 | 
			
		||||
    backup = common->action->u.blockdev_backup;
 | 
			
		||||
 | 
			
		||||
    blk = blk_by_name(backup->device);
 | 
			
		||||
    if (!blk) {
 | 
			
		||||
@ -1887,9 +1888,9 @@ void qmp_transaction(TransactionActionList *dev_list, Error **errp)
 | 
			
		||||
        dev_info = dev_entry->value;
 | 
			
		||||
        dev_entry = dev_entry->next;
 | 
			
		||||
 | 
			
		||||
        assert(dev_info->kind < ARRAY_SIZE(actions));
 | 
			
		||||
        assert(dev_info->type < ARRAY_SIZE(actions));
 | 
			
		||||
 | 
			
		||||
        ops = &actions[dev_info->kind];
 | 
			
		||||
        ops = &actions[dev_info->type];
 | 
			
		||||
        assert(ops->instance_size > 0);
 | 
			
		||||
 | 
			
		||||
        state = g_malloc0(ops->instance_size);
 | 
			
		||||
 | 
			
		||||
@ -106,12 +106,15 @@ Types, commands, and events share a common namespace.  Therefore,
 | 
			
		||||
generally speaking, type definitions should always use CamelCase for
 | 
			
		||||
user-defined type names, while built-in types are lowercase. Type
 | 
			
		||||
definitions should not end in 'Kind', as this namespace is used for
 | 
			
		||||
creating implicit C enums for visiting union types.  Command names,
 | 
			
		||||
creating implicit C enums for visiting union types, or in 'List', as
 | 
			
		||||
this namespace is used for creating array types.  Command names,
 | 
			
		||||
and field names within a type, should be all lower case with words
 | 
			
		||||
separated by a hyphen.  However, some existing older commands and
 | 
			
		||||
complex types use underscore; when extending such expressions,
 | 
			
		||||
consistency is preferred over blindly avoiding underscore.  Event
 | 
			
		||||
names should be ALL_CAPS with words separated by underscore.
 | 
			
		||||
names should be ALL_CAPS with words separated by underscore.  Field
 | 
			
		||||
names cannot start with 'has-' or 'has_', as this is reserved for
 | 
			
		||||
tracking optional fields.
 | 
			
		||||
 | 
			
		||||
Any name (command, event, type, field, or enum value) beginning with
 | 
			
		||||
"x-" is marked experimental, and may be withdrawn or changed
 | 
			
		||||
@ -122,9 +125,10 @@ vendor), even if the rest of the name uses dash (example:
 | 
			
		||||
__com.redhat_drive-mirror).  Other than downstream extensions (with
 | 
			
		||||
leading underscore and the use of dots), all names should begin with a
 | 
			
		||||
letter, and contain only ASCII letters, digits, dash, and underscore.
 | 
			
		||||
It is okay to reuse names that match C keywords; the generator will
 | 
			
		||||
rename a field named "default" in the QAPI to "q_default" in the
 | 
			
		||||
generated C code.
 | 
			
		||||
Names beginning with 'q_' are reserved for the generator: QMP names
 | 
			
		||||
that resemble C keywords or other problematic strings will be munged
 | 
			
		||||
in C to use this prefix.  For example, a field named "default" in
 | 
			
		||||
qapi becomes "q_default" in the generated C code.
 | 
			
		||||
 | 
			
		||||
In the rest of this document, usage lines are given for each
 | 
			
		||||
expression type, with literal strings written in lower case and
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										26
									
								
								hmp.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								hmp.c
									
									
									
									
									
								
							@ -569,8 +569,8 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict)
 | 
			
		||||
        for (client = info->clients; client; client = client->next) {
 | 
			
		||||
            monitor_printf(mon, "Client:\n");
 | 
			
		||||
            monitor_printf(mon, "     address: %s:%s\n",
 | 
			
		||||
                           client->value->base->host,
 | 
			
		||||
                           client->value->base->service);
 | 
			
		||||
                           client->value->host,
 | 
			
		||||
                           client->value->service);
 | 
			
		||||
            monitor_printf(mon, "  x509_dname: %s\n",
 | 
			
		||||
                           client->value->x509_dname ?
 | 
			
		||||
                           client->value->x509_dname : "none");
 | 
			
		||||
@ -638,7 +638,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict)
 | 
			
		||||
        for (chan = info->channels; chan; chan = chan->next) {
 | 
			
		||||
            monitor_printf(mon, "Channel:\n");
 | 
			
		||||
            monitor_printf(mon, "     address: %s:%s%s\n",
 | 
			
		||||
                           chan->value->base->host, chan->value->base->port,
 | 
			
		||||
                           chan->value->host, chan->value->port,
 | 
			
		||||
                           chan->value->tls ? " [tls]" : "");
 | 
			
		||||
            monitor_printf(mon, "     session: %" PRId64 "\n",
 | 
			
		||||
                           chan->value->connection_id);
 | 
			
		||||
@ -841,11 +841,11 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
 | 
			
		||||
                       c, TpmModel_lookup[ti->model]);
 | 
			
		||||
 | 
			
		||||
        monitor_printf(mon, "  \\ %s: type=%s",
 | 
			
		||||
                       ti->id, TpmTypeOptionsKind_lookup[ti->options->kind]);
 | 
			
		||||
                       ti->id, TpmTypeOptionsKind_lookup[ti->options->type]);
 | 
			
		||||
 | 
			
		||||
        switch (ti->options->kind) {
 | 
			
		||||
        switch (ti->options->type) {
 | 
			
		||||
        case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH:
 | 
			
		||||
            tpo = ti->options->passthrough;
 | 
			
		||||
            tpo = ti->options->u.passthrough;
 | 
			
		||||
            monitor_printf(mon, "%s%s%s%s",
 | 
			
		||||
                           tpo->has_path ? ",path=" : "",
 | 
			
		||||
                           tpo->has_path ? tpo->path : "",
 | 
			
		||||
@ -1735,15 +1735,15 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
 | 
			
		||||
            if (*endp != '\0') {
 | 
			
		||||
                goto err_out;
 | 
			
		||||
            }
 | 
			
		||||
            keylist->value->kind = KEY_VALUE_KIND_NUMBER;
 | 
			
		||||
            keylist->value->number = value;
 | 
			
		||||
            keylist->value->type = KEY_VALUE_KIND_NUMBER;
 | 
			
		||||
            keylist->value->u.number = value;
 | 
			
		||||
        } else {
 | 
			
		||||
            int idx = index_from_key(keyname_buf);
 | 
			
		||||
            if (idx == Q_KEY_CODE_MAX) {
 | 
			
		||||
                goto err_out;
 | 
			
		||||
            }
 | 
			
		||||
            keylist->value->kind = KEY_VALUE_KIND_QCODE;
 | 
			
		||||
            keylist->value->qcode = idx;
 | 
			
		||||
            keylist->value->type = KEY_VALUE_KIND_QCODE;
 | 
			
		||||
            keylist->value->u.qcode = idx;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!separator) {
 | 
			
		||||
@ -1958,12 +1958,12 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
 | 
			
		||||
        value = info->value;
 | 
			
		||||
 | 
			
		||||
        if (value) {
 | 
			
		||||
            switch (value->kind) {
 | 
			
		||||
            switch (value->type) {
 | 
			
		||||
            case MEMORY_DEVICE_INFO_KIND_DIMM:
 | 
			
		||||
                di = value->dimm;
 | 
			
		||||
                di = value->u.dimm;
 | 
			
		||||
 | 
			
		||||
                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
 | 
			
		||||
                               MemoryDeviceInfoKind_lookup[value->kind],
 | 
			
		||||
                               MemoryDeviceInfoKind_lookup[value->type],
 | 
			
		||||
                               di->id ? di->id : "");
 | 
			
		||||
                monitor_printf(mon, "  addr: 0x%" PRIx64 "\n", di->addr);
 | 
			
		||||
                monitor_printf(mon, "  slot: %" PRId64 "\n", di->slot);
 | 
			
		||||
 | 
			
		||||
@ -842,13 +842,13 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
    ChannelState *s = (ChannelState *)dev;
 | 
			
		||||
    int qcode, keycode;
 | 
			
		||||
 | 
			
		||||
    assert(evt->kind == INPUT_EVENT_KIND_KEY);
 | 
			
		||||
    qcode = qemu_input_key_value_to_qcode(evt->key->key);
 | 
			
		||||
    assert(evt->type == INPUT_EVENT_KIND_KEY);
 | 
			
		||||
    qcode = qemu_input_key_value_to_qcode(evt->u.key->key);
 | 
			
		||||
    trace_escc_sunkbd_event_in(qcode, QKeyCode_lookup[qcode],
 | 
			
		||||
                               evt->key->down);
 | 
			
		||||
                               evt->u.key->down);
 | 
			
		||||
 | 
			
		||||
    if (qcode == Q_KEY_CODE_CAPS_LOCK) {
 | 
			
		||||
        if (evt->key->down) {
 | 
			
		||||
        if (evt->u.key->down) {
 | 
			
		||||
            s->caps_lock_mode ^= 1;
 | 
			
		||||
            if (s->caps_lock_mode == 2) {
 | 
			
		||||
                return; /* Drop second press */
 | 
			
		||||
@ -862,7 +862,7 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (qcode == Q_KEY_CODE_NUM_LOCK) {
 | 
			
		||||
        if (evt->key->down) {
 | 
			
		||||
        if (evt->u.key->down) {
 | 
			
		||||
            s->num_lock_mode ^= 1;
 | 
			
		||||
            if (s->num_lock_mode == 2) {
 | 
			
		||||
                return; /* Drop second press */
 | 
			
		||||
@ -876,7 +876,7 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    keycode = qcode_to_keycode[qcode];
 | 
			
		||||
    if (!evt->key->down) {
 | 
			
		||||
    if (!evt->u.key->down) {
 | 
			
		||||
        keycode |= 0x80;
 | 
			
		||||
    }
 | 
			
		||||
    trace_escc_sunkbd_event_out(keycode);
 | 
			
		||||
 | 
			
		||||
@ -119,33 +119,33 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
    assert(hs->n < QUEUE_LENGTH);
 | 
			
		||||
    e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
 | 
			
		||||
 | 
			
		||||
    switch (evt->kind) {
 | 
			
		||||
    switch (evt->type) {
 | 
			
		||||
    case INPUT_EVENT_KIND_REL:
 | 
			
		||||
        if (evt->rel->axis == INPUT_AXIS_X) {
 | 
			
		||||
            e->xdx += evt->rel->value;
 | 
			
		||||
        } else if (evt->rel->axis == INPUT_AXIS_Y) {
 | 
			
		||||
            e->ydy += evt->rel->value;
 | 
			
		||||
        if (evt->u.rel->axis == INPUT_AXIS_X) {
 | 
			
		||||
            e->xdx += evt->u.rel->value;
 | 
			
		||||
        } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
 | 
			
		||||
            e->ydy += evt->u.rel->value;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case INPUT_EVENT_KIND_ABS:
 | 
			
		||||
        if (evt->rel->axis == INPUT_AXIS_X) {
 | 
			
		||||
            e->xdx = evt->rel->value;
 | 
			
		||||
        } else if (evt->rel->axis == INPUT_AXIS_Y) {
 | 
			
		||||
            e->ydy = evt->rel->value;
 | 
			
		||||
        if (evt->u.rel->axis == INPUT_AXIS_X) {
 | 
			
		||||
            e->xdx = evt->u.rel->value;
 | 
			
		||||
        } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
 | 
			
		||||
            e->ydy = evt->u.rel->value;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case INPUT_EVENT_KIND_BTN:
 | 
			
		||||
        if (evt->btn->down) {
 | 
			
		||||
            e->buttons_state |= bmap[evt->btn->button];
 | 
			
		||||
            if (evt->btn->button == INPUT_BUTTON_WHEEL_UP) {
 | 
			
		||||
        if (evt->u.btn->down) {
 | 
			
		||||
            e->buttons_state |= bmap[evt->u.btn->button];
 | 
			
		||||
            if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
 | 
			
		||||
                e->dz--;
 | 
			
		||||
            } else if (evt->btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 | 
			
		||||
            } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 | 
			
		||||
                e->dz++;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            e->buttons_state &= ~bmap[evt->btn->button];
 | 
			
		||||
            e->buttons_state &= ~bmap[evt->u.btn->button];
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
@ -223,8 +223,8 @@ static void hid_keyboard_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
    int scancodes[3], i, count;
 | 
			
		||||
    int slot;
 | 
			
		||||
 | 
			
		||||
    count = qemu_input_key_value_to_scancode(evt->key->key,
 | 
			
		||||
                                             evt->key->down,
 | 
			
		||||
    count = qemu_input_key_value_to_scancode(evt->u.key->key,
 | 
			
		||||
                                             evt->u.key->down,
 | 
			
		||||
                                             scancodes);
 | 
			
		||||
    if (hs->n + count > QUEUE_LENGTH) {
 | 
			
		||||
        fprintf(stderr, "usb-kbd: warning: key event queue full\n");
 | 
			
		||||
 | 
			
		||||
@ -183,8 +183,8 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
    int scancodes[3], i, count;
 | 
			
		||||
 | 
			
		||||
    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 | 
			
		||||
    count = qemu_input_key_value_to_scancode(evt->key->key,
 | 
			
		||||
                                             evt->key->down,
 | 
			
		||||
    count = qemu_input_key_value_to_scancode(evt->u.key->key,
 | 
			
		||||
                                             evt->u.key->down,
 | 
			
		||||
                                             scancodes);
 | 
			
		||||
    for (i = 0; i < count; i++) {
 | 
			
		||||
        ps2_put_keycode(s, scancodes[i]);
 | 
			
		||||
@ -393,25 +393,25 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    switch (evt->kind) {
 | 
			
		||||
    switch (evt->type) {
 | 
			
		||||
    case INPUT_EVENT_KIND_REL:
 | 
			
		||||
        if (evt->rel->axis == INPUT_AXIS_X) {
 | 
			
		||||
            s->mouse_dx += evt->rel->value;
 | 
			
		||||
        } else if (evt->rel->axis == INPUT_AXIS_Y) {
 | 
			
		||||
            s->mouse_dy -= evt->rel->value;
 | 
			
		||||
        if (evt->u.rel->axis == INPUT_AXIS_X) {
 | 
			
		||||
            s->mouse_dx += evt->u.rel->value;
 | 
			
		||||
        } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
 | 
			
		||||
            s->mouse_dy -= evt->u.rel->value;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case INPUT_EVENT_KIND_BTN:
 | 
			
		||||
        if (evt->btn->down) {
 | 
			
		||||
            s->mouse_buttons |= bmap[evt->btn->button];
 | 
			
		||||
            if (evt->btn->button == INPUT_BUTTON_WHEEL_UP) {
 | 
			
		||||
        if (evt->u.btn->down) {
 | 
			
		||||
            s->mouse_buttons |= bmap[evt->u.btn->button];
 | 
			
		||||
            if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
 | 
			
		||||
                s->mouse_dz--;
 | 
			
		||||
            } else if (evt->btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 | 
			
		||||
            } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 | 
			
		||||
                s->mouse_dz++;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            s->mouse_buttons &= ~bmap[evt->btn->button];
 | 
			
		||||
            s->mouse_buttons &= ~bmap[evt->u.btn->button];
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -191,44 +191,45 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
    virtio_input_event event;
 | 
			
		||||
    int qcode;
 | 
			
		||||
 | 
			
		||||
    switch (evt->kind) {
 | 
			
		||||
    switch (evt->type) {
 | 
			
		||||
    case INPUT_EVENT_KIND_KEY:
 | 
			
		||||
        qcode = qemu_input_key_value_to_qcode(evt->key->key);
 | 
			
		||||
        qcode = qemu_input_key_value_to_qcode(evt->u.key->key);
 | 
			
		||||
        if (qcode && keymap_qcode[qcode]) {
 | 
			
		||||
            event.type  = cpu_to_le16(EV_KEY);
 | 
			
		||||
            event.code  = cpu_to_le16(keymap_qcode[qcode]);
 | 
			
		||||
            event.value = cpu_to_le32(evt->key->down ? 1 : 0);
 | 
			
		||||
            event.value = cpu_to_le32(evt->u.key->down ? 1 : 0);
 | 
			
		||||
            virtio_input_send(vinput, &event);
 | 
			
		||||
        } else {
 | 
			
		||||
            if (evt->key->down) {
 | 
			
		||||
            if (evt->u.key->down) {
 | 
			
		||||
                fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__,
 | 
			
		||||
                        qcode, QKeyCode_lookup[qcode]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case INPUT_EVENT_KIND_BTN:
 | 
			
		||||
        if (keymap_button[evt->btn->button]) {
 | 
			
		||||
        if (keymap_button[evt->u.btn->button]) {
 | 
			
		||||
            event.type  = cpu_to_le16(EV_KEY);
 | 
			
		||||
            event.code  = cpu_to_le16(keymap_button[evt->btn->button]);
 | 
			
		||||
            event.value = cpu_to_le32(evt->btn->down ? 1 : 0);
 | 
			
		||||
            event.code  = cpu_to_le16(keymap_button[evt->u.btn->button]);
 | 
			
		||||
            event.value = cpu_to_le32(evt->u.btn->down ? 1 : 0);
 | 
			
		||||
            virtio_input_send(vinput, &event);
 | 
			
		||||
        } else {
 | 
			
		||||
            if (evt->btn->down) {
 | 
			
		||||
            if (evt->u.btn->down) {
 | 
			
		||||
                fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__,
 | 
			
		||||
                        evt->btn->button, InputButton_lookup[evt->btn->button]);
 | 
			
		||||
                        evt->u.btn->button,
 | 
			
		||||
                        InputButton_lookup[evt->u.btn->button]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case INPUT_EVENT_KIND_REL:
 | 
			
		||||
        event.type  = cpu_to_le16(EV_REL);
 | 
			
		||||
        event.code  = cpu_to_le16(axismap_rel[evt->rel->axis]);
 | 
			
		||||
        event.value = cpu_to_le32(evt->rel->value);
 | 
			
		||||
        event.code  = cpu_to_le16(axismap_rel[evt->u.rel->axis]);
 | 
			
		||||
        event.value = cpu_to_le32(evt->u.rel->value);
 | 
			
		||||
        virtio_input_send(vinput, &event);
 | 
			
		||||
        break;
 | 
			
		||||
    case INPUT_EVENT_KIND_ABS:
 | 
			
		||||
        event.type  = cpu_to_le16(EV_ABS);
 | 
			
		||||
        event.code  = cpu_to_le16(axismap_abs[evt->abs->axis]);
 | 
			
		||||
        event.value = cpu_to_le32(evt->abs->value);
 | 
			
		||||
        event.code  = cpu_to_le16(axismap_abs[evt->u.abs->axis]);
 | 
			
		||||
        event.value = cpu_to_le32(evt->u.abs->value);
 | 
			
		||||
        virtio_input_send(vinput, &event);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
 | 
			
		||||
@ -179,7 +179,7 @@ int qmp_pc_dimm_device_list(Object *obj, void *opaque)
 | 
			
		||||
                                               NULL);
 | 
			
		||||
            di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem));
 | 
			
		||||
 | 
			
		||||
            info->dimm = di;
 | 
			
		||||
            info->u.dimm = di;
 | 
			
		||||
            elem->value = info;
 | 
			
		||||
            elem->next = NULL;
 | 
			
		||||
            **prev = elem;
 | 
			
		||||
@ -203,9 +203,9 @@ ram_addr_t get_current_ram_size(void)
 | 
			
		||||
        MemoryDeviceInfo *value = info->value;
 | 
			
		||||
 | 
			
		||||
        if (value) {
 | 
			
		||||
            switch (value->kind) {
 | 
			
		||||
            switch (value->type) {
 | 
			
		||||
            case MEMORY_DEVICE_INFO_KIND_DIMM:
 | 
			
		||||
                size += value->dimm->size;
 | 
			
		||||
                size += value->u.dimm->size;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
@ -187,8 +187,8 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
 | 
			
		||||
    NetClientState *nc;
 | 
			
		||||
    DumpNetClient *dnc;
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_DUMP);
 | 
			
		||||
    dump = opts->dump;
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_DUMP);
 | 
			
		||||
    dump = opts->u.dump;
 | 
			
		||||
 | 
			
		||||
    assert(peer);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -285,9 +285,9 @@ int net_init_hubport(const NetClientOptions *opts, const char *name,
 | 
			
		||||
{
 | 
			
		||||
    const NetdevHubPortOptions *hubport;
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_HUBPORT);
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_HUBPORT);
 | 
			
		||||
    assert(!peer);
 | 
			
		||||
    hubport = opts->hubport;
 | 
			
		||||
    hubport = opts->u.hubport;
 | 
			
		||||
 | 
			
		||||
    net_hub_add_port(hubport->hubid, name);
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
@ -545,8 +545,8 @@ int net_init_l2tpv3(const NetClientOptions *opts,
 | 
			
		||||
    s->queue_tail = 0;
 | 
			
		||||
    s->header_mismatch = false;
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_L2TPV3);
 | 
			
		||||
    l2tpv3 = opts->l2tpv3;
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_L2TPV3);
 | 
			
		||||
    l2tpv3 = opts->u.l2tpv3;
 | 
			
		||||
 | 
			
		||||
    if (l2tpv3->has_ipv6 && l2tpv3->ipv6) {
 | 
			
		||||
        s->ipv6 = l2tpv3->ipv6;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								net/net.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								net/net.c
									
									
									
									
									
								
							@ -882,8 +882,8 @@ static int net_init_nic(const NetClientOptions *opts, const char *name,
 | 
			
		||||
    NICInfo *nd;
 | 
			
		||||
    const NetLegacyNicOptions *nic;
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_NIC);
 | 
			
		||||
    nic = opts->nic;
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_NIC);
 | 
			
		||||
    nic = opts->u.nic;
 | 
			
		||||
 | 
			
		||||
    idx = nic_get_free_idx();
 | 
			
		||||
    if (idx == -1 || nb_nics >= MAX_NICS) {
 | 
			
		||||
@ -984,9 +984,9 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
 | 
			
		||||
        opts = netdev->opts;
 | 
			
		||||
        name = netdev->id;
 | 
			
		||||
 | 
			
		||||
        if (opts->kind == NET_CLIENT_OPTIONS_KIND_DUMP ||
 | 
			
		||||
            opts->kind == NET_CLIENT_OPTIONS_KIND_NIC ||
 | 
			
		||||
            !net_client_init_fun[opts->kind]) {
 | 
			
		||||
        if (opts->type == NET_CLIENT_OPTIONS_KIND_DUMP ||
 | 
			
		||||
            opts->type == NET_CLIENT_OPTIONS_KIND_NIC ||
 | 
			
		||||
            !net_client_init_fun[opts->type]) {
 | 
			
		||||
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
 | 
			
		||||
                       "a netdev backend type");
 | 
			
		||||
            return -1;
 | 
			
		||||
@ -997,16 +997,16 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
 | 
			
		||||
        /* missing optional values have been initialized to "all bits zero" */
 | 
			
		||||
        name = net->has_id ? net->id : net->name;
 | 
			
		||||
 | 
			
		||||
        if (opts->kind == NET_CLIENT_OPTIONS_KIND_NONE) {
 | 
			
		||||
        if (opts->type == NET_CLIENT_OPTIONS_KIND_NONE) {
 | 
			
		||||
            return 0; /* nothing to do */
 | 
			
		||||
        }
 | 
			
		||||
        if (opts->kind == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
 | 
			
		||||
        if (opts->type == NET_CLIENT_OPTIONS_KIND_HUBPORT) {
 | 
			
		||||
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
 | 
			
		||||
                       "a net type");
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!net_client_init_fun[opts->kind]) {
 | 
			
		||||
        if (!net_client_init_fun[opts->type]) {
 | 
			
		||||
            error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
 | 
			
		||||
                       "a net backend type (maybe it is not compiled "
 | 
			
		||||
                       "into this binary)");
 | 
			
		||||
@ -1014,17 +1014,17 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Do not add to a vlan if it's a nic with a netdev= parameter. */
 | 
			
		||||
        if (opts->kind != NET_CLIENT_OPTIONS_KIND_NIC ||
 | 
			
		||||
            !opts->nic->has_netdev) {
 | 
			
		||||
        if (opts->type != NET_CLIENT_OPTIONS_KIND_NIC ||
 | 
			
		||||
            !opts->u.nic->has_netdev) {
 | 
			
		||||
            peer = net_hub_add_port(net->has_vlan ? net->vlan : 0, NULL);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (net_client_init_fun[opts->kind](opts, name, peer, errp) < 0) {
 | 
			
		||||
    if (net_client_init_fun[opts->type](opts, name, peer, errp) < 0) {
 | 
			
		||||
        /* FIXME drop when all init functions store an Error */
 | 
			
		||||
        if (errp && !*errp) {
 | 
			
		||||
            error_setg(errp, QERR_DEVICE_INIT_FAILED,
 | 
			
		||||
                       NetClientOptionsKind_lookup[opts->kind]);
 | 
			
		||||
                       NetClientOptionsKind_lookup[opts->type]);
 | 
			
		||||
        }
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -746,8 +746,8 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,
 | 
			
		||||
    const NetdevUserOptions *user;
 | 
			
		||||
    const char **dnssearch;
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_USER);
 | 
			
		||||
    user = opts->user;
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_USER);
 | 
			
		||||
    user = opts->u.user;
 | 
			
		||||
 | 
			
		||||
    vnet = user->has_net ? g_strdup(user->net) :
 | 
			
		||||
           user->has_ip  ? g_strdup_printf("%s/24", user->ip) :
 | 
			
		||||
 | 
			
		||||
@ -706,8 +706,8 @@ int net_init_socket(const NetClientOptions *opts, const char *name,
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
    const NetdevSocketOptions *sock;
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_SOCKET);
 | 
			
		||||
    sock = opts->socket;
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_SOCKET);
 | 
			
		||||
    sock = opts->u.socket;
 | 
			
		||||
 | 
			
		||||
    if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast +
 | 
			
		||||
        sock->has_udp != 1) {
 | 
			
		||||
 | 
			
		||||
@ -767,8 +767,8 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
 | 
			
		||||
    /* FIXME error_setg(errp, ...) on failure */
 | 
			
		||||
    const NetdevTapOptions *tap;
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_TAP);
 | 
			
		||||
    tap = opts->tap;
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_TAP);
 | 
			
		||||
    tap = opts->u.tap;
 | 
			
		||||
 | 
			
		||||
    if (!tap->has_ifname) {
 | 
			
		||||
        error_report("tap: no interface name");
 | 
			
		||||
 | 
			
		||||
@ -565,8 +565,8 @@ int net_init_bridge(const NetClientOptions *opts, const char *name,
 | 
			
		||||
    TAPState *s;
 | 
			
		||||
    int fd, vnet_hdr;
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_BRIDGE);
 | 
			
		||||
    bridge = opts->bridge;
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_BRIDGE);
 | 
			
		||||
    bridge = opts->u.bridge;
 | 
			
		||||
 | 
			
		||||
    helper = bridge->has_helper ? bridge->helper : DEFAULT_BRIDGE_HELPER;
 | 
			
		||||
    br     = bridge->has_br     ? bridge->br     : DEFAULT_BRIDGE_INTERFACE;
 | 
			
		||||
@ -728,8 +728,8 @@ int net_init_tap(const NetClientOptions *opts, const char *name,
 | 
			
		||||
    const char *vhostfdname;
 | 
			
		||||
    char ifname[128];
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_TAP);
 | 
			
		||||
    tap = opts->tap;
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_TAP);
 | 
			
		||||
    tap = opts->u.tap;
 | 
			
		||||
    queues = tap->has_queues ? tap->queues : 1;
 | 
			
		||||
    vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -115,8 +115,8 @@ int net_init_vde(const NetClientOptions *opts, const char *name,
 | 
			
		||||
    /* FIXME error_setg(errp, ...) on failure */
 | 
			
		||||
    const NetdevVdeOptions *vde;
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_VDE);
 | 
			
		||||
    vde = opts->vde;
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_VDE);
 | 
			
		||||
    vde = opts->u.vde;
 | 
			
		||||
 | 
			
		||||
    /* missing optional values have been initialized to "all bits zero" */
 | 
			
		||||
    if (net_vde_init(peer, "vde", name, vde->sock, vde->port, vde->group,
 | 
			
		||||
 | 
			
		||||
@ -301,8 +301,8 @@ int net_init_vhost_user(const NetClientOptions *opts, const char *name,
 | 
			
		||||
    const NetdevVhostUserOptions *vhost_user_opts;
 | 
			
		||||
    CharDriverState *chr;
 | 
			
		||||
 | 
			
		||||
    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
 | 
			
		||||
    vhost_user_opts = opts->vhost_user;
 | 
			
		||||
    assert(opts->type == NET_CLIENT_OPTIONS_KIND_VHOST_USER);
 | 
			
		||||
    vhost_user_opts = opts->u.vhost_user;
 | 
			
		||||
 | 
			
		||||
    chr = net_vhost_parse_chardev(vhost_user_opts, errp);
 | 
			
		||||
    if (!chr) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								numa.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								numa.c
									
									
									
									
									
								
							@ -226,9 +226,9 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
 | 
			
		||||
        goto error;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (object->kind) {
 | 
			
		||||
    switch (object->type) {
 | 
			
		||||
    case NUMA_OPTIONS_KIND_NODE:
 | 
			
		||||
        numa_node_parse(object->node, opts, &err);
 | 
			
		||||
        numa_node_parse(object->u.node, opts, &err);
 | 
			
		||||
        if (err) {
 | 
			
		||||
            goto error;
 | 
			
		||||
        }
 | 
			
		||||
@ -487,9 +487,9 @@ static void numa_stat_memory_devices(uint64_t node_mem[])
 | 
			
		||||
        MemoryDeviceInfo *value = info->value;
 | 
			
		||||
 | 
			
		||||
        if (value) {
 | 
			
		||||
            switch (value->kind) {
 | 
			
		||||
            switch (value->type) {
 | 
			
		||||
            case MEMORY_DEVICE_INFO_KIND_DIMM:
 | 
			
		||||
                node_mem[value->dimm->node] += value->dimm->size;
 | 
			
		||||
                node_mem[value->u.dimm->node] += value->u.dimm->size;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
@ -2614,9 +2614,7 @@
 | 
			
		||||
#
 | 
			
		||||
# @host: host part of the address
 | 
			
		||||
#
 | 
			
		||||
# @port: port part of the address, or lowest port if @to is present.
 | 
			
		||||
#        Kernel selects a free port if omitted for listener addresses.
 | 
			
		||||
#        #optional
 | 
			
		||||
# @port: port part of the address, or lowest port if @to is present
 | 
			
		||||
#
 | 
			
		||||
# @to: highest port to try
 | 
			
		||||
#
 | 
			
		||||
@ -2631,7 +2629,7 @@
 | 
			
		||||
{ 'struct': 'InetSocketAddress',
 | 
			
		||||
  'data': {
 | 
			
		||||
    'host': 'str',
 | 
			
		||||
    '*port': 'str',
 | 
			
		||||
    'port': 'str',
 | 
			
		||||
    '*to': 'uint16',
 | 
			
		||||
    '*ipv4': 'bool',
 | 
			
		||||
    '*ipv6': 'bool' } }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										164
									
								
								qemu-char.c
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								qemu-char.c
									
									
									
									
									
								
							@ -97,18 +97,18 @@ static int SocketAddress_to_str(char *dest, int max_len,
 | 
			
		||||
                                const char *prefix, SocketAddress *addr,
 | 
			
		||||
                                bool is_listen, bool is_telnet)
 | 
			
		||||
{
 | 
			
		||||
    switch (addr->kind) {
 | 
			
		||||
    switch (addr->type) {
 | 
			
		||||
    case SOCKET_ADDRESS_KIND_INET:
 | 
			
		||||
        return snprintf(dest, max_len, "%s%s:%s:%s%s", prefix,
 | 
			
		||||
                        is_telnet ? "telnet" : "tcp", addr->inet->host,
 | 
			
		||||
                        addr->inet->port, is_listen ? ",server" : "");
 | 
			
		||||
                        is_telnet ? "telnet" : "tcp", addr->u.inet->host,
 | 
			
		||||
                        addr->u.inet->port, is_listen ? ",server" : "");
 | 
			
		||||
        break;
 | 
			
		||||
    case SOCKET_ADDRESS_KIND_UNIX:
 | 
			
		||||
        return snprintf(dest, max_len, "%sunix:%s%s", prefix,
 | 
			
		||||
                        addr->q_unix->path, is_listen ? ",server" : "");
 | 
			
		||||
                        addr->u.q_unix->path, is_listen ? ",server" : "");
 | 
			
		||||
        break;
 | 
			
		||||
    case SOCKET_ADDRESS_KIND_FD:
 | 
			
		||||
        return snprintf(dest, max_len, "%sfd:%s%s", prefix, addr->fd->str,
 | 
			
		||||
        return snprintf(dest, max_len, "%sfd:%s%s", prefix, addr->u.fd->str,
 | 
			
		||||
                        is_listen ? ",server" : "");
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
@ -661,7 +661,7 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
 | 
			
		||||
                                          ChardevBackend *backend,
 | 
			
		||||
                                          ChardevReturn *ret, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevMux *mux = backend->mux;
 | 
			
		||||
    ChardevMux *mux = backend->u.mux;
 | 
			
		||||
    CharDriverState *chr, *drv;
 | 
			
		||||
    MuxDriver *d;
 | 
			
		||||
 | 
			
		||||
@ -1070,7 +1070,7 @@ static CharDriverState *qemu_chr_open_pipe(const char *id,
 | 
			
		||||
                                           ChardevReturn *ret,
 | 
			
		||||
                                           Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevHostdev *opts = backend->pipe;
 | 
			
		||||
    ChardevHostdev *opts = backend->u.pipe;
 | 
			
		||||
    int fd_in, fd_out;
 | 
			
		||||
    char filename_in[CHR_MAX_FILENAME_SIZE];
 | 
			
		||||
    char filename_out[CHR_MAX_FILENAME_SIZE];
 | 
			
		||||
@ -1148,7 +1148,7 @@ static CharDriverState *qemu_chr_open_stdio(const char *id,
 | 
			
		||||
                                            ChardevReturn *ret,
 | 
			
		||||
                                            Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevStdio *opts = backend->stdio;
 | 
			
		||||
    ChardevStdio *opts = backend->u.stdio;
 | 
			
		||||
    CharDriverState *chr;
 | 
			
		||||
    struct sigaction act;
 | 
			
		||||
 | 
			
		||||
@ -2147,7 +2147,7 @@ static CharDriverState *qemu_chr_open_pipe(const char *id,
 | 
			
		||||
                                           ChardevReturn *ret,
 | 
			
		||||
                                           Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevHostdev *opts = backend->pipe;
 | 
			
		||||
    ChardevHostdev *opts = backend->u.pipe;
 | 
			
		||||
    const char *filename = opts->device;
 | 
			
		||||
    CharDriverState *chr;
 | 
			
		||||
    WinCharState *s;
 | 
			
		||||
@ -3202,7 +3202,7 @@ static CharDriverState *qemu_chr_open_ringbuf(const char *id,
 | 
			
		||||
                                              ChardevReturn *ret,
 | 
			
		||||
                                              Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevRingbuf *opts = backend->ringbuf;
 | 
			
		||||
    ChardevRingbuf *opts = backend->u.ringbuf;
 | 
			
		||||
    CharDriverState *chr;
 | 
			
		||||
    RingBufCharDriver *d;
 | 
			
		||||
 | 
			
		||||
@ -3477,16 +3477,16 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
        error_setg(errp, "chardev: file: no filename given");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    backend->file = g_new0(ChardevFile, 1);
 | 
			
		||||
    backend->file->out = g_strdup(path);
 | 
			
		||||
    backend->u.file = g_new0(ChardevFile, 1);
 | 
			
		||||
    backend->u.file->out = g_strdup(path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
                                 Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    backend->stdio = g_new0(ChardevStdio, 1);
 | 
			
		||||
    backend->stdio->has_signal = true;
 | 
			
		||||
    backend->stdio->signal = qemu_opt_get_bool(opts, "signal", true);
 | 
			
		||||
    backend->u.stdio = g_new0(ChardevStdio, 1);
 | 
			
		||||
    backend->u.stdio->has_signal = true;
 | 
			
		||||
    backend->u.stdio->signal = qemu_opt_get_bool(opts, "signal", true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CHARDEV_SERIAL
 | 
			
		||||
@ -3499,8 +3499,8 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
        error_setg(errp, "chardev: serial/tty: no device path given");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    backend->serial = g_new0(ChardevHostdev, 1);
 | 
			
		||||
    backend->serial->device = g_strdup(device);
 | 
			
		||||
    backend->u.serial = g_new0(ChardevHostdev, 1);
 | 
			
		||||
    backend->u.serial->device = g_strdup(device);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -3514,8 +3514,8 @@ static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
        error_setg(errp, "chardev: parallel: no device path given");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    backend->parallel = g_new0(ChardevHostdev, 1);
 | 
			
		||||
    backend->parallel->device = g_strdup(device);
 | 
			
		||||
    backend->u.parallel = g_new0(ChardevHostdev, 1);
 | 
			
		||||
    backend->u.parallel->device = g_strdup(device);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -3528,8 +3528,8 @@ static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
        error_setg(errp, "chardev: pipe: no device path given");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    backend->pipe = g_new0(ChardevHostdev, 1);
 | 
			
		||||
    backend->pipe->device = g_strdup(device);
 | 
			
		||||
    backend->u.pipe = g_new0(ChardevHostdev, 1);
 | 
			
		||||
    backend->u.pipe->device = g_strdup(device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
@ -3537,12 +3537,12 @@ static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
{
 | 
			
		||||
    int val;
 | 
			
		||||
 | 
			
		||||
    backend->ringbuf = g_new0(ChardevRingbuf, 1);
 | 
			
		||||
    backend->u.ringbuf = g_new0(ChardevRingbuf, 1);
 | 
			
		||||
 | 
			
		||||
    val = qemu_opt_get_size(opts, "size", 0);
 | 
			
		||||
    if (val != 0) {
 | 
			
		||||
        backend->ringbuf->has_size = true;
 | 
			
		||||
        backend->ringbuf->size = val;
 | 
			
		||||
        backend->u.ringbuf->has_size = true;
 | 
			
		||||
        backend->u.ringbuf->size = val;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3555,8 +3555,8 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
        error_setg(errp, "chardev: mux: no chardev given");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    backend->mux = g_new0(ChardevMux, 1);
 | 
			
		||||
    backend->mux->chardev = g_strdup(chardev);
 | 
			
		||||
    backend->u.mux = g_new0(ChardevMux, 1);
 | 
			
		||||
    backend->u.mux->chardev = g_strdup(chardev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
@ -3583,37 +3583,37 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    backend->socket = g_new0(ChardevSocket, 1);
 | 
			
		||||
    backend->u.socket = g_new0(ChardevSocket, 1);
 | 
			
		||||
 | 
			
		||||
    backend->socket->has_nodelay = true;
 | 
			
		||||
    backend->socket->nodelay = do_nodelay;
 | 
			
		||||
    backend->socket->has_server = true;
 | 
			
		||||
    backend->socket->server = is_listen;
 | 
			
		||||
    backend->socket->has_telnet = true;
 | 
			
		||||
    backend->socket->telnet = is_telnet;
 | 
			
		||||
    backend->socket->has_wait = true;
 | 
			
		||||
    backend->socket->wait = is_waitconnect;
 | 
			
		||||
    backend->socket->has_reconnect = true;
 | 
			
		||||
    backend->socket->reconnect = reconnect;
 | 
			
		||||
    backend->u.socket->has_nodelay = true;
 | 
			
		||||
    backend->u.socket->nodelay = do_nodelay;
 | 
			
		||||
    backend->u.socket->has_server = true;
 | 
			
		||||
    backend->u.socket->server = is_listen;
 | 
			
		||||
    backend->u.socket->has_telnet = true;
 | 
			
		||||
    backend->u.socket->telnet = is_telnet;
 | 
			
		||||
    backend->u.socket->has_wait = true;
 | 
			
		||||
    backend->u.socket->wait = is_waitconnect;
 | 
			
		||||
    backend->u.socket->has_reconnect = true;
 | 
			
		||||
    backend->u.socket->reconnect = reconnect;
 | 
			
		||||
 | 
			
		||||
    addr = g_new0(SocketAddress, 1);
 | 
			
		||||
    if (path) {
 | 
			
		||||
        addr->kind = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        addr->q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
        addr->q_unix->path = g_strdup(path);
 | 
			
		||||
        addr->type = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        addr->u.q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
        addr->u.q_unix->path = g_strdup(path);
 | 
			
		||||
    } else {
 | 
			
		||||
        addr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
        addr->inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
        addr->inet->host = g_strdup(host);
 | 
			
		||||
        addr->inet->port = g_strdup(port);
 | 
			
		||||
        addr->inet->has_to = qemu_opt_get(opts, "to");
 | 
			
		||||
        addr->inet->to = qemu_opt_get_number(opts, "to", 0);
 | 
			
		||||
        addr->inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
 | 
			
		||||
        addr->inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
 | 
			
		||||
        addr->inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
 | 
			
		||||
        addr->inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
 | 
			
		||||
        addr->type = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
        addr->u.inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
        addr->u.inet->host = g_strdup(host);
 | 
			
		||||
        addr->u.inet->port = g_strdup(port);
 | 
			
		||||
        addr->u.inet->has_to = qemu_opt_get(opts, "to");
 | 
			
		||||
        addr->u.inet->to = qemu_opt_get_number(opts, "to", 0);
 | 
			
		||||
        addr->u.inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
 | 
			
		||||
        addr->u.inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
 | 
			
		||||
        addr->u.inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
 | 
			
		||||
        addr->u.inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
 | 
			
		||||
    }
 | 
			
		||||
    backend->socket->addr = addr;
 | 
			
		||||
    backend->u.socket->addr = addr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
@ -3644,27 +3644,27 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
        has_local = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    backend->udp = g_new0(ChardevUdp, 1);
 | 
			
		||||
    backend->u.udp = g_new0(ChardevUdp, 1);
 | 
			
		||||
 | 
			
		||||
    addr = g_new0(SocketAddress, 1);
 | 
			
		||||
    addr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
    addr->inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
    addr->inet->host = g_strdup(host);
 | 
			
		||||
    addr->inet->port = g_strdup(port);
 | 
			
		||||
    addr->inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
 | 
			
		||||
    addr->inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
 | 
			
		||||
    addr->inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
 | 
			
		||||
    addr->inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
 | 
			
		||||
    backend->udp->remote = addr;
 | 
			
		||||
    addr->type = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
    addr->u.inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
    addr->u.inet->host = g_strdup(host);
 | 
			
		||||
    addr->u.inet->port = g_strdup(port);
 | 
			
		||||
    addr->u.inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
 | 
			
		||||
    addr->u.inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
 | 
			
		||||
    addr->u.inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
 | 
			
		||||
    addr->u.inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
 | 
			
		||||
    backend->u.udp->remote = addr;
 | 
			
		||||
 | 
			
		||||
    if (has_local) {
 | 
			
		||||
        backend->udp->has_local = true;
 | 
			
		||||
        backend->u.udp->has_local = true;
 | 
			
		||||
        addr = g_new0(SocketAddress, 1);
 | 
			
		||||
        addr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
        addr->inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
        addr->inet->host = g_strdup(localaddr);
 | 
			
		||||
        addr->inet->port = g_strdup(localport);
 | 
			
		||||
        backend->udp->local = addr;
 | 
			
		||||
        addr->type = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
        addr->u.inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
        addr->u.inet->host = g_strdup(localaddr);
 | 
			
		||||
        addr->u.inet->port = g_strdup(localport);
 | 
			
		||||
        backend->u.udp->local = addr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3737,7 +3737,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    chr = NULL;
 | 
			
		||||
    backend->kind = cd->kind;
 | 
			
		||||
    backend->type = cd->kind;
 | 
			
		||||
    if (cd->parse) {
 | 
			
		||||
        cd->parse(opts, backend, &local_err);
 | 
			
		||||
        if (local_err) {
 | 
			
		||||
@ -3754,9 +3754,9 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 | 
			
		||||
        qapi_free_ChardevBackend(backend);
 | 
			
		||||
        qapi_free_ChardevReturn(ret);
 | 
			
		||||
        backend = g_new0(ChardevBackend, 1);
 | 
			
		||||
        backend->mux = g_new0(ChardevMux, 1);
 | 
			
		||||
        backend->kind = CHARDEV_BACKEND_KIND_MUX;
 | 
			
		||||
        backend->mux->chardev = g_strdup(bid);
 | 
			
		||||
        backend->u.mux = g_new0(ChardevMux, 1);
 | 
			
		||||
        backend->type = CHARDEV_BACKEND_KIND_MUX;
 | 
			
		||||
        backend->u.mux->chardev = g_strdup(bid);
 | 
			
		||||
        ret = qmp_chardev_add(id, backend, errp);
 | 
			
		||||
        if (!ret) {
 | 
			
		||||
            chr = qemu_chr_find(bid);
 | 
			
		||||
@ -4048,7 +4048,7 @@ static CharDriverState *qmp_chardev_open_file(const char *id,
 | 
			
		||||
                                              ChardevReturn *ret,
 | 
			
		||||
                                              Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevFile *file = backend->file;
 | 
			
		||||
    ChardevFile *file = backend->u.file;
 | 
			
		||||
    HANDLE out;
 | 
			
		||||
 | 
			
		||||
    if (file->has_in) {
 | 
			
		||||
@ -4070,7 +4070,7 @@ static CharDriverState *qmp_chardev_open_serial(const char *id,
 | 
			
		||||
                                                ChardevReturn *ret,
 | 
			
		||||
                                                Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevHostdev *serial = backend->serial;
 | 
			
		||||
    ChardevHostdev *serial = backend->u.serial;
 | 
			
		||||
    return qemu_chr_open_win_path(serial->device, errp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4093,7 +4093,7 @@ static CharDriverState *qmp_chardev_open_file(const char *id,
 | 
			
		||||
                                              ChardevReturn *ret,
 | 
			
		||||
                                              Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevFile *file = backend->file;
 | 
			
		||||
    ChardevFile *file = backend->u.file;
 | 
			
		||||
    int flags, in = -1, out;
 | 
			
		||||
 | 
			
		||||
    flags = O_WRONLY | O_TRUNC | O_CREAT | O_BINARY;
 | 
			
		||||
@ -4120,7 +4120,7 @@ static CharDriverState *qmp_chardev_open_serial(const char *id,
 | 
			
		||||
                                                ChardevReturn *ret,
 | 
			
		||||
                                                Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevHostdev *serial = backend->serial;
 | 
			
		||||
    ChardevHostdev *serial = backend->u.serial;
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);
 | 
			
		||||
@ -4138,7 +4138,7 @@ static CharDriverState *qmp_chardev_open_parallel(const char *id,
 | 
			
		||||
                                                  ChardevReturn *ret,
 | 
			
		||||
                                                  Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevHostdev *parallel = backend->parallel;
 | 
			
		||||
    ChardevHostdev *parallel = backend->u.parallel;
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
 | 
			
		||||
@ -4183,7 +4183,7 @@ static CharDriverState *qmp_chardev_open_socket(const char *id,
 | 
			
		||||
{
 | 
			
		||||
    CharDriverState *chr;
 | 
			
		||||
    TCPCharDriver *s;
 | 
			
		||||
    ChardevSocket *sock = backend->socket;
 | 
			
		||||
    ChardevSocket *sock = backend->u.socket;
 | 
			
		||||
    SocketAddress *addr = sock->addr;
 | 
			
		||||
    bool do_nodelay     = sock->has_nodelay ? sock->nodelay : false;
 | 
			
		||||
    bool is_listen      = sock->has_server  ? sock->server  : true;
 | 
			
		||||
@ -4196,7 +4196,7 @@ static CharDriverState *qmp_chardev_open_socket(const char *id,
 | 
			
		||||
 | 
			
		||||
    s->fd = -1;
 | 
			
		||||
    s->listen_fd = -1;
 | 
			
		||||
    s->is_unix = addr->kind == SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
    s->is_unix = addr->type == SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
    s->is_listen = is_listen;
 | 
			
		||||
    s->is_telnet = is_telnet;
 | 
			
		||||
    s->do_nodelay = do_nodelay;
 | 
			
		||||
@ -4250,7 +4250,7 @@ static CharDriverState *qmp_chardev_open_udp(const char *id,
 | 
			
		||||
                                             ChardevReturn *ret,
 | 
			
		||||
                                             Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ChardevUdp *udp = backend->udp;
 | 
			
		||||
    ChardevUdp *udp = backend->u.udp;
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    fd = socket_dgram(udp->remote, udp->local, errp);
 | 
			
		||||
@ -4279,7 +4279,7 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
 | 
			
		||||
    for (i = backends; i; i = i->next) {
 | 
			
		||||
        cd = i->data;
 | 
			
		||||
 | 
			
		||||
        if (cd->kind == backend->kind) {
 | 
			
		||||
        if (cd->kind == backend->type) {
 | 
			
		||||
            chr = cd->create(id, backend, ret, &local_err);
 | 
			
		||||
            if (local_err) {
 | 
			
		||||
                error_propagate(errp, local_err);
 | 
			
		||||
@ -4297,9 +4297,9 @@ ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,
 | 
			
		||||
 | 
			
		||||
    chr->label = g_strdup(id);
 | 
			
		||||
    chr->avail_connections =
 | 
			
		||||
        (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
 | 
			
		||||
        (backend->type == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;
 | 
			
		||||
    if (!chr->filename) {
 | 
			
		||||
        chr->filename = g_strdup(ChardevBackendKind_lookup[backend->kind]);
 | 
			
		||||
        chr->filename = g_strdup(ChardevBackendKind_lookup[backend->type]);
 | 
			
		||||
    }
 | 
			
		||||
    if (!chr->explicit_be_open) {
 | 
			
		||||
        qemu_chr_be_event(chr, CHR_EVENT_OPENED);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								qemu-nbd.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								qemu-nbd.c
									
									
									
									
									
								
							@ -362,17 +362,17 @@ static SocketAddress *nbd_build_socket_address(const char *sockpath,
 | 
			
		||||
 | 
			
		||||
    saddr = g_new0(SocketAddress, 1);
 | 
			
		||||
    if (sockpath) {
 | 
			
		||||
        saddr->kind = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        saddr->q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
        saddr->q_unix->path = g_strdup(sockpath);
 | 
			
		||||
        saddr->type = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
        saddr->u.q_unix->path = g_strdup(sockpath);
 | 
			
		||||
    } else {
 | 
			
		||||
        saddr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
        saddr->inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
        saddr->inet->host = g_strdup(bindto);
 | 
			
		||||
        saddr->type = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
        saddr->u.inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
        saddr->u.inet->host = g_strdup(bindto);
 | 
			
		||||
        if (port) {
 | 
			
		||||
            saddr->inet->port = g_strdup(port);
 | 
			
		||||
            saddr->u.inet->port = g_strdup(port);
 | 
			
		||||
        } else  {
 | 
			
		||||
            saddr->inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
 | 
			
		||||
            saddr->u.inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -175,7 +175,9 @@ def gen_marshal(name, arg_type, ret_type):
 | 
			
		||||
    ret += gen_marshal_input_visit(arg_type)
 | 
			
		||||
    ret += gen_call(name, arg_type, ret_type)
 | 
			
		||||
 | 
			
		||||
    if re.search('^ *goto out;', ret, re.MULTILINE):
 | 
			
		||||
    # 'goto out' produced by gen_marshal_input_visit->gen_visit_fields()
 | 
			
		||||
    # for each arg_type member, and by gen_call() for ret_type
 | 
			
		||||
    if (arg_type and arg_type.members) or ret_type:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
 | 
			
		||||
@ -36,26 +36,37 @@ struct %(c_name)s {
 | 
			
		||||
                 c_name=c_name(name), c_type=element_type.c_type())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_struct_field(name, typ, optional):
 | 
			
		||||
def gen_struct_field(member):
 | 
			
		||||
    ret = ''
 | 
			
		||||
 | 
			
		||||
    if optional:
 | 
			
		||||
    if member.optional:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    bool has_%(c_name)s;
 | 
			
		||||
''',
 | 
			
		||||
                     c_name=c_name(name))
 | 
			
		||||
                     c_name=c_name(member.name))
 | 
			
		||||
    ret += mcgen('''
 | 
			
		||||
    %(c_type)s %(c_name)s;
 | 
			
		||||
''',
 | 
			
		||||
                 c_type=typ.c_type(), c_name=c_name(name))
 | 
			
		||||
                 c_type=member.type.c_type(), c_name=c_name(member.name))
 | 
			
		||||
    return ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_struct_fields(members):
 | 
			
		||||
def gen_struct_fields(local_members, base=None):
 | 
			
		||||
    ret = ''
 | 
			
		||||
 | 
			
		||||
    for memb in members:
 | 
			
		||||
        ret += gen_struct_field(memb.name, memb.type, memb.optional)
 | 
			
		||||
    if base:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    /* Members inherited from %(c_name)s: */
 | 
			
		||||
''',
 | 
			
		||||
                     c_name=base.c_name())
 | 
			
		||||
        for memb in base.members:
 | 
			
		||||
            ret += gen_struct_field(memb)
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    /* Own members: */
 | 
			
		||||
''')
 | 
			
		||||
 | 
			
		||||
    for memb in local_members:
 | 
			
		||||
        ret += gen_struct_field(memb)
 | 
			
		||||
    return ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -66,16 +77,13 @@ struct %(c_name)s {
 | 
			
		||||
''',
 | 
			
		||||
                c_name=c_name(name))
 | 
			
		||||
 | 
			
		||||
    if base:
 | 
			
		||||
        ret += gen_struct_field('base', base, False)
 | 
			
		||||
 | 
			
		||||
    ret += gen_struct_fields(members)
 | 
			
		||||
    ret += gen_struct_fields(members, base)
 | 
			
		||||
 | 
			
		||||
    # Make sure that all structs have at least one field; this avoids
 | 
			
		||||
    # potential issues with attempting to malloc space for zero-length
 | 
			
		||||
    # structs in C, and also incompatibility with C++ (where an empty
 | 
			
		||||
    # struct is size 1).
 | 
			
		||||
    if not base and not members:
 | 
			
		||||
    if not (base and base.members) and not members:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    char qapi_dummy_field_for_empty_struct;
 | 
			
		||||
''')
 | 
			
		||||
@ -87,6 +95,19 @@ struct %(c_name)s {
 | 
			
		||||
    return ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_upcast(name, base):
 | 
			
		||||
    # C makes const-correctness ugly.  We have to cast away const to let
 | 
			
		||||
    # this function work for both const and non-const obj.
 | 
			
		||||
    return mcgen('''
 | 
			
		||||
 | 
			
		||||
static inline %(base)s *qapi_%(c_name)s_base(const %(c_name)s *obj)
 | 
			
		||||
{
 | 
			
		||||
    return (%(base)s *)obj;
 | 
			
		||||
}
 | 
			
		||||
''',
 | 
			
		||||
                 c_name=c_name(name), base=base.c_name())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_alternate_qtypes_decl(name):
 | 
			
		||||
    return mcgen('''
 | 
			
		||||
 | 
			
		||||
@ -126,19 +147,9 @@ struct %(c_name)s {
 | 
			
		||||
''',
 | 
			
		||||
                c_name=c_name(name))
 | 
			
		||||
    if base:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    /* Members inherited from %(c_name)s: */
 | 
			
		||||
''',
 | 
			
		||||
                     c_name=c_name(base.name))
 | 
			
		||||
        ret += gen_struct_fields(base.members)
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    /* Own members: */
 | 
			
		||||
''')
 | 
			
		||||
        ret += gen_struct_fields([], base)
 | 
			
		||||
    else:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    %(c_type)s kind;
 | 
			
		||||
''',
 | 
			
		||||
                     c_type=c_name(variants.tag_member.type.name))
 | 
			
		||||
        ret += gen_struct_field(variants.tag_member)
 | 
			
		||||
 | 
			
		||||
    # FIXME: What purpose does data serve, besides preventing a union that
 | 
			
		||||
    # has a branch named 'data'? We use it in qapi-visit.py to decide
 | 
			
		||||
@ -152,10 +163,7 @@ struct %(c_name)s {
 | 
			
		||||
    union { /* union tag is @%(c_name)s */
 | 
			
		||||
        void *data;
 | 
			
		||||
''',
 | 
			
		||||
                 # TODO ugly special case for simple union
 | 
			
		||||
                 # Use same tag name in C as on the wire to get rid of
 | 
			
		||||
                 # it, then: c_name=c_name(variants.tag_member.name)
 | 
			
		||||
                 c_name=c_name(variants.tag_name or 'kind'))
 | 
			
		||||
                 c_name=c_name(variants.tag_member.name))
 | 
			
		||||
 | 
			
		||||
    for var in variants.variants:
 | 
			
		||||
        # Ugly special case for simple union TODO get rid of it
 | 
			
		||||
@ -167,7 +175,7 @@ struct %(c_name)s {
 | 
			
		||||
                     c_name=c_name(var.name))
 | 
			
		||||
 | 
			
		||||
    ret += mcgen('''
 | 
			
		||||
    };
 | 
			
		||||
    } u;
 | 
			
		||||
};
 | 
			
		||||
''')
 | 
			
		||||
 | 
			
		||||
@ -265,6 +273,8 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
 | 
			
		||||
            self.decl += gen_union(name, base, variants)
 | 
			
		||||
        else:
 | 
			
		||||
            self.decl += gen_struct(name, base, members)
 | 
			
		||||
        if base:
 | 
			
		||||
            self.decl += gen_upcast(name, base)
 | 
			
		||||
        self._gen_type_cleanup(name)
 | 
			
		||||
 | 
			
		||||
    def visit_alternate_type(self, name, info, variants):
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,12 @@
 | 
			
		||||
from qapi import *
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
# visit_type_FOO_implicit() is emitted as needed; track if it has already
 | 
			
		||||
# been output.
 | 
			
		||||
implicit_structs_seen = set()
 | 
			
		||||
 | 
			
		||||
# visit_type_FOO_fields() is always emitted; track if a forward declaration
 | 
			
		||||
# or implementation has already been output.
 | 
			
		||||
struct_fields_seen = set()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,19 +34,24 @@ void visit_type_%(c_name)s(Visitor *v, %(c_type)sobj, const char *name, Error **
 | 
			
		||||
                 c_name=c_name(name), c_type=c_type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_visit_implicit_struct(typ):
 | 
			
		||||
    if typ in implicit_structs_seen:
 | 
			
		||||
        return ''
 | 
			
		||||
    implicit_structs_seen.add(typ)
 | 
			
		||||
 | 
			
		||||
def gen_visit_fields_decl(typ):
 | 
			
		||||
    ret = ''
 | 
			
		||||
    if typ.name not in struct_fields_seen:
 | 
			
		||||
        # Need a forward declaration
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
 | 
			
		||||
static void visit_type_%(c_type)s_fields(Visitor *v, %(c_type)s **obj, Error **errp);
 | 
			
		||||
''',
 | 
			
		||||
                     c_type=typ.c_name())
 | 
			
		||||
        struct_fields_seen.add(typ.name)
 | 
			
		||||
    return ret
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_visit_implicit_struct(typ):
 | 
			
		||||
    if typ in implicit_structs_seen:
 | 
			
		||||
        return ''
 | 
			
		||||
    implicit_structs_seen.add(typ)
 | 
			
		||||
 | 
			
		||||
    ret = gen_visit_fields_decl(typ)
 | 
			
		||||
 | 
			
		||||
    ret += mcgen('''
 | 
			
		||||
 | 
			
		||||
@ -62,13 +72,12 @@ static void visit_type_implicit_%(c_type)s(Visitor *v, %(c_type)s **obj, Error *
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def gen_visit_struct_fields(name, base, members):
 | 
			
		||||
    struct_fields_seen.add(name)
 | 
			
		||||
 | 
			
		||||
    ret = ''
 | 
			
		||||
 | 
			
		||||
    if base:
 | 
			
		||||
        ret += gen_visit_implicit_struct(base)
 | 
			
		||||
        ret += gen_visit_fields_decl(base)
 | 
			
		||||
 | 
			
		||||
    struct_fields_seen.add(name)
 | 
			
		||||
    ret += mcgen('''
 | 
			
		||||
 | 
			
		||||
static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s **obj, Error **errp)
 | 
			
		||||
@ -80,14 +89,15 @@ static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s **obj, Error **e
 | 
			
		||||
 | 
			
		||||
    if base:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    visit_type_implicit_%(c_type)s(v, &(*obj)->%(c_name)s, &err);
 | 
			
		||||
    visit_type_%(c_type)s_fields(v, (%(c_type)s **)obj, &err);
 | 
			
		||||
''',
 | 
			
		||||
                     c_type=base.c_name(), c_name=c_name('base'))
 | 
			
		||||
                     c_type=base.c_name())
 | 
			
		||||
        ret += gen_err_check()
 | 
			
		||||
 | 
			
		||||
    ret += gen_visit_fields(members, prefix='(*obj)->')
 | 
			
		||||
 | 
			
		||||
    if re.search('^ *goto out;', ret, re.MULTILINE):
 | 
			
		||||
    # 'goto out' produced for base, and by gen_visit_fields() for each member
 | 
			
		||||
    if base or members:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
@ -179,18 +189,18 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
 | 
			
		||||
    if (err) {
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    visit_get_next_type(v, (int*) &(*obj)->kind, %(c_name)s_qtypes, name, &err);
 | 
			
		||||
    visit_get_next_type(v, (int*) &(*obj)->type, %(c_name)s_qtypes, name, &err);
 | 
			
		||||
    if (err) {
 | 
			
		||||
        goto out_obj;
 | 
			
		||||
    }
 | 
			
		||||
    switch ((*obj)->kind) {
 | 
			
		||||
    switch ((*obj)->type) {
 | 
			
		||||
''',
 | 
			
		||||
                c_name=c_name(name))
 | 
			
		||||
 | 
			
		||||
    for var in variants.variants:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    case %(case)s:
 | 
			
		||||
        visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, name, &err);
 | 
			
		||||
        visit_type_%(c_type)s(v, &(*obj)->u.%(c_name)s, name, &err);
 | 
			
		||||
        break;
 | 
			
		||||
''',
 | 
			
		||||
                     case=c_enum_const(variants.tag_member.type.name,
 | 
			
		||||
@ -218,8 +228,7 @@ def gen_visit_union(name, base, variants):
 | 
			
		||||
    ret = ''
 | 
			
		||||
 | 
			
		||||
    if base:
 | 
			
		||||
        members = [m for m in base.members if m != variants.tag_member]
 | 
			
		||||
        ret += gen_visit_struct_fields(name, None, members)
 | 
			
		||||
        ret += gen_visit_fields_decl(base)
 | 
			
		||||
 | 
			
		||||
    for var in variants.variants:
 | 
			
		||||
        # Ugly special case for simple union TODO get rid of it
 | 
			
		||||
@ -244,31 +253,24 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
 | 
			
		||||
 | 
			
		||||
    if base:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    visit_type_%(c_name)s_fields(v, obj, &err);
 | 
			
		||||
    visit_type_%(c_name)s_fields(v, (%(c_name)s **)obj, &err);
 | 
			
		||||
''',
 | 
			
		||||
                     c_name=c_name(name))
 | 
			
		||||
        ret += gen_err_check(label='out_obj')
 | 
			
		||||
 | 
			
		||||
    tag_key = variants.tag_member.name
 | 
			
		||||
    if not variants.tag_name:
 | 
			
		||||
        # we pointlessly use a different key for simple unions
 | 
			
		||||
        tag_key = 'type'
 | 
			
		||||
                     c_name=base.c_name())
 | 
			
		||||
    else:
 | 
			
		||||
        ret += mcgen('''
 | 
			
		||||
    visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "%(name)s", &err);
 | 
			
		||||
    if (err) {
 | 
			
		||||
        goto out_obj;
 | 
			
		||||
    }
 | 
			
		||||
    if (!visit_start_union(v, !!(*obj)->data, &err) || err) {
 | 
			
		||||
''',
 | 
			
		||||
                     c_type=variants.tag_member.type.c_name(),
 | 
			
		||||
                     c_name=c_name(variants.tag_member.name),
 | 
			
		||||
                     name=variants.tag_member.name)
 | 
			
		||||
    ret += gen_err_check(label='out_obj')
 | 
			
		||||
    ret += mcgen('''
 | 
			
		||||
    if (!visit_start_union(v, !!(*obj)->u.data, &err) || err) {
 | 
			
		||||
        goto out_obj;
 | 
			
		||||
    }
 | 
			
		||||
    switch ((*obj)->%(c_name)s) {
 | 
			
		||||
''',
 | 
			
		||||
                 c_type=variants.tag_member.type.c_name(),
 | 
			
		||||
                 # TODO ugly special case for simple union
 | 
			
		||||
                 # Use same tag name in C as on the wire to get rid of
 | 
			
		||||
                 # it, then: c_name=c_name(variants.tag_member.name)
 | 
			
		||||
                 c_name=c_name(variants.tag_name or 'kind'),
 | 
			
		||||
                 name=tag_key)
 | 
			
		||||
                 c_name=c_name(variants.tag_member.name))
 | 
			
		||||
 | 
			
		||||
    for var in variants.variants:
 | 
			
		||||
        # TODO ugly special case for simple union
 | 
			
		||||
@ -280,13 +282,13 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
 | 
			
		||||
                                       var.name))
 | 
			
		||||
        if simple_union_type:
 | 
			
		||||
            ret += mcgen('''
 | 
			
		||||
        visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "data", &err);
 | 
			
		||||
        visit_type_%(c_type)s(v, &(*obj)->u.%(c_name)s, "data", &err);
 | 
			
		||||
''',
 | 
			
		||||
                         c_type=simple_union_type.c_name(),
 | 
			
		||||
                         c_name=c_name(var.name))
 | 
			
		||||
        else:
 | 
			
		||||
            ret += mcgen('''
 | 
			
		||||
        visit_type_implicit_%(c_type)s(v, &(*obj)->%(c_name)s, &err);
 | 
			
		||||
        visit_type_implicit_%(c_type)s(v, &(*obj)->u.%(c_name)s, &err);
 | 
			
		||||
''',
 | 
			
		||||
                         c_type=var.type.c_name(),
 | 
			
		||||
                         c_name=c_name(var.name))
 | 
			
		||||
@ -302,7 +304,7 @@ out_obj:
 | 
			
		||||
    error_propagate(errp, err);
 | 
			
		||||
    err = NULL;
 | 
			
		||||
    if (*obj) {
 | 
			
		||||
        visit_end_union(v, !!(*obj)->data, &err);
 | 
			
		||||
        visit_end_union(v, !!(*obj)->u.data, &err);
 | 
			
		||||
    }
 | 
			
		||||
    error_propagate(errp, err);
 | 
			
		||||
    err = NULL;
 | 
			
		||||
 | 
			
		||||
@ -172,7 +172,7 @@ class QAPISchemaParser(object):
 | 
			
		||||
 | 
			
		||||
            if self.tok == '#':
 | 
			
		||||
                self.cursor = self.src.find('\n', self.cursor)
 | 
			
		||||
            elif self.tok in ['{', '}', ':', ',', '[', ']']:
 | 
			
		||||
            elif self.tok in "{}:,[]":
 | 
			
		||||
                return
 | 
			
		||||
            elif self.tok == "'":
 | 
			
		||||
                string = ''
 | 
			
		||||
@ -376,7 +376,9 @@ def check_name(expr_info, source, name, allow_optional=False,
 | 
			
		||||
    # code always prefixes it with the enum name
 | 
			
		||||
    if enum_member:
 | 
			
		||||
        membername = '_' + membername
 | 
			
		||||
    if not valid_name.match(membername):
 | 
			
		||||
    # Reserve the entire 'q_' namespace for c_name()
 | 
			
		||||
    if not valid_name.match(membername) or \
 | 
			
		||||
       c_name(membername, False).startswith('q_'):
 | 
			
		||||
        raise QAPIExprError(expr_info,
 | 
			
		||||
                            "%s uses invalid name '%s'" % (source, name))
 | 
			
		||||
 | 
			
		||||
@ -390,10 +392,10 @@ def add_name(name, info, meta, implicit=False):
 | 
			
		||||
        raise QAPIExprError(info,
 | 
			
		||||
                            "%s '%s' is already defined"
 | 
			
		||||
                            % (all_names[name], name))
 | 
			
		||||
    if not implicit and name[-4:] == 'Kind':
 | 
			
		||||
    if not implicit and (name.endswith('Kind') or name.endswith('List')):
 | 
			
		||||
        raise QAPIExprError(info,
 | 
			
		||||
                            "%s '%s' should not end in 'Kind'"
 | 
			
		||||
                            % (meta, name))
 | 
			
		||||
                            "%s '%s' should not end in '%s'"
 | 
			
		||||
                            % (meta, name, name[-4:]))
 | 
			
		||||
    all_names[name] = meta
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -488,6 +490,10 @@ def check_type(expr_info, source, value, allow_array=False,
 | 
			
		||||
    for (key, arg) in value.items():
 | 
			
		||||
        check_name(expr_info, "Member of %s" % source, key,
 | 
			
		||||
                   allow_optional=allow_optional)
 | 
			
		||||
        if c_name(key, False) == 'u' or c_name(key, False).startswith('has_'):
 | 
			
		||||
            raise QAPIExprError(expr_info,
 | 
			
		||||
                                "Member of %s uses reserved name '%s'"
 | 
			
		||||
                                % (source, key))
 | 
			
		||||
        # Todo: allow dictionaries to represent default values of
 | 
			
		||||
        # an optional argument.
 | 
			
		||||
        check_type(expr_info, "Member '%s' of %s" % (key, source), arg,
 | 
			
		||||
@ -542,7 +548,8 @@ def check_union(expr, expr_info):
 | 
			
		||||
    base = expr.get('base')
 | 
			
		||||
    discriminator = expr.get('discriminator')
 | 
			
		||||
    members = expr['data']
 | 
			
		||||
    values = {'MAX': '(automatic)', 'KIND': '(automatic)'}
 | 
			
		||||
    values = {'MAX': '(automatic)', 'KIND': '(automatic)',
 | 
			
		||||
              'TYPE': '(automatic)'}
 | 
			
		||||
 | 
			
		||||
    # Two types of unions, determined by discriminator.
 | 
			
		||||
 | 
			
		||||
@ -910,7 +917,7 @@ class QAPISchemaEnumType(QAPISchemaType):
 | 
			
		||||
 | 
			
		||||
    def is_implicit(self):
 | 
			
		||||
        # See QAPISchema._make_implicit_enum_type()
 | 
			
		||||
        return self.name[-4:] == 'Kind'
 | 
			
		||||
        return self.name.endswith('Kind')
 | 
			
		||||
 | 
			
		||||
    def c_type(self, is_param=False):
 | 
			
		||||
        return c_name(self.name)
 | 
			
		||||
@ -1196,9 +1203,7 @@ class QAPISchema(object):
 | 
			
		||||
        return name
 | 
			
		||||
 | 
			
		||||
    def _make_array_type(self, element_type, info):
 | 
			
		||||
        # TODO fooList namespace is not reserved; user can create collisions,
 | 
			
		||||
        # or abuse our type system with ['fooList'] for 2D array
 | 
			
		||||
        name = element_type + 'List'
 | 
			
		||||
        name = element_type + 'List'   # Use namespace reserved by add_name()
 | 
			
		||||
        if not self.lookup_type(name):
 | 
			
		||||
            self._def_entity(QAPISchemaArrayType(name, info, element_type))
 | 
			
		||||
        return name
 | 
			
		||||
 | 
			
		||||
@ -301,7 +301,7 @@ static CharDriverState *qemu_chr_open_spice_vmc(const char *id,
 | 
			
		||||
                                                ChardevReturn *ret,
 | 
			
		||||
                                                Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    const char *type = backend->spicevmc->type;
 | 
			
		||||
    const char *type = backend->u.spicevmc->type;
 | 
			
		||||
    const char **psubtype = spice_server_char_device_recognized_subtypes();
 | 
			
		||||
 | 
			
		||||
    for (; *psubtype != NULL; ++psubtype) {
 | 
			
		||||
@ -324,7 +324,7 @@ static CharDriverState *qemu_chr_open_spice_port(const char *id,
 | 
			
		||||
                                                 ChardevReturn *ret,
 | 
			
		||||
                                                 Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    const char *name = backend->spiceport->fqdn;
 | 
			
		||||
    const char *name = backend->u.spiceport->fqdn;
 | 
			
		||||
    CharDriverState *chr;
 | 
			
		||||
    SpiceCharDriver *s;
 | 
			
		||||
 | 
			
		||||
@ -362,8 +362,8 @@ static void qemu_chr_parse_spice_vmc(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
        error_setg(errp, "chardev: spice channel: no name given");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    backend->spicevmc = g_new0(ChardevSpiceChannel, 1);
 | 
			
		||||
    backend->spicevmc->type = g_strdup(name);
 | 
			
		||||
    backend->u.spicevmc = g_new0(ChardevSpiceChannel, 1);
 | 
			
		||||
    backend->u.spicevmc->type = g_strdup(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
@ -375,8 +375,8 @@ static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
        error_setg(errp, "chardev: spice port: no name given");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    backend->spiceport = g_new0(ChardevSpicePort, 1);
 | 
			
		||||
    backend->spiceport->fqdn = g_strdup(name);
 | 
			
		||||
    backend->u.spiceport = g_new0(ChardevSpicePort, 1);
 | 
			
		||||
    backend->u.spiceport->fqdn = g_strdup(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void register_types(void)
 | 
			
		||||
 | 
			
		||||
@ -265,7 +265,6 @@ qapi-schema += enum-dict-member.json
 | 
			
		||||
qapi-schema += enum-int-member.json
 | 
			
		||||
qapi-schema += enum-max-member.json
 | 
			
		||||
qapi-schema += enum-missing-data.json
 | 
			
		||||
qapi-schema += enum-union-clash.json
 | 
			
		||||
qapi-schema += enum-wrong-data.json
 | 
			
		||||
qapi-schema += escape-outside-string.json
 | 
			
		||||
qapi-schema += escape-too-big.json
 | 
			
		||||
@ -316,12 +315,17 @@ qapi-schema += redefined-builtin.json
 | 
			
		||||
qapi-schema += redefined-command.json
 | 
			
		||||
qapi-schema += redefined-event.json
 | 
			
		||||
qapi-schema += redefined-type.json
 | 
			
		||||
qapi-schema += reserved-command-q.json
 | 
			
		||||
qapi-schema += reserved-member-has.json
 | 
			
		||||
qapi-schema += reserved-member-q.json
 | 
			
		||||
qapi-schema += reserved-member-u.json
 | 
			
		||||
qapi-schema += reserved-type-kind.json
 | 
			
		||||
qapi-schema += reserved-type-list.json
 | 
			
		||||
qapi-schema += returns-alternate.json
 | 
			
		||||
qapi-schema += returns-array-bad.json
 | 
			
		||||
qapi-schema += returns-dict.json
 | 
			
		||||
qapi-schema += returns-unknown.json
 | 
			
		||||
qapi-schema += returns-whitelist.json
 | 
			
		||||
qapi-schema += struct-base-clash-base.json
 | 
			
		||||
qapi-schema += struct-base-clash-deep.json
 | 
			
		||||
qapi-schema += struct-base-clash.json
 | 
			
		||||
qapi-schema += struct-data-invalid.json
 | 
			
		||||
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
tests/qapi-schema/enum-union-clash.json:2: enum 'UnionKind' should not end in 'Kind'
 | 
			
		||||
@ -11,6 +11,10 @@
 | 
			
		||||
# An empty enum, although unusual, is currently acceptable
 | 
			
		||||
{ 'enum': 'MyEnum', 'data': [ ] }
 | 
			
		||||
 | 
			
		||||
# Likewise for an empty struct, including an empty base
 | 
			
		||||
{ 'struct': 'Empty1', 'data': { } }
 | 
			
		||||
{ 'struct': 'Empty2', 'base': 'Empty1', 'data': { } }
 | 
			
		||||
 | 
			
		||||
# for testing override of default naming heuristic
 | 
			
		||||
{ 'enum': 'QEnumTwo',
 | 
			
		||||
  'prefix': 'QENUM_TWO',
 | 
			
		||||
 | 
			
		||||
@ -81,6 +81,9 @@ event EVENT_A None
 | 
			
		||||
event EVENT_B None
 | 
			
		||||
event EVENT_C :obj-EVENT_C-arg
 | 
			
		||||
event EVENT_D :obj-EVENT_D-arg
 | 
			
		||||
object Empty1
 | 
			
		||||
object Empty2
 | 
			
		||||
    base Empty1
 | 
			
		||||
enum EnumOne ['value1', 'value2', 'value3']
 | 
			
		||||
object EventStructOne
 | 
			
		||||
    member struct1: UserDefOne optional=False
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-command-q.err
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-command-q.err
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
tests/qapi-schema/reserved-command-q.json:5: 'command' uses invalid name 'q-unix'
 | 
			
		||||
							
								
								
									
										5
									
								
								tests/qapi-schema/reserved-command-q.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/qapi-schema/reserved-command-q.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
# C entity name collision
 | 
			
		||||
# We reject names like 'q-unix', because they can collide with the mangled
 | 
			
		||||
# name for 'unix' in generated C.
 | 
			
		||||
{ 'command': 'unix' }
 | 
			
		||||
{ 'command': 'q-unix' }
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-member-has.err
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-member-has.err
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
tests/qapi-schema/reserved-member-has.json:5: Member of 'data' for command 'oops' uses reserved name 'has-a'
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-member-has.exit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-member-has.exit
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
1
 | 
			
		||||
							
								
								
									
										5
									
								
								tests/qapi-schema/reserved-member-has.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/qapi-schema/reserved-member-has.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
# C member name collision
 | 
			
		||||
# We reject names like 'has-a', because they can collide with the flag
 | 
			
		||||
# for an optional 'a' in generated C.
 | 
			
		||||
# TODO we could munge the optional flag name to avoid the collision.
 | 
			
		||||
{ 'command': 'oops', 'data': { '*a': 'str', 'has-a': 'str' } }
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-member-q.err
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-member-q.err
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
tests/qapi-schema/reserved-member-q.json:4: Member of 'data' for struct 'Foo' uses invalid name 'q-unix'
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-member-q.exit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-member-q.exit
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
1
 | 
			
		||||
							
								
								
									
										4
									
								
								tests/qapi-schema/reserved-member-q.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								tests/qapi-schema/reserved-member-q.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
# C member name collision
 | 
			
		||||
# We reject names like 'q-unix', because they can collide with the mangled
 | 
			
		||||
# name for 'unix' in generated C.
 | 
			
		||||
{ 'struct': 'Foo', 'data': { 'unix':'int', 'q-unix':'bool' } }
 | 
			
		||||
							
								
								
									
										0
									
								
								tests/qapi-schema/reserved-member-q.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/qapi-schema/reserved-member-q.out
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-member-u.err
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-member-u.err
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
tests/qapi-schema/reserved-member-u.json:7: Member of 'data' for struct 'Oops' uses reserved name 'u'
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-member-u.exit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-member-u.exit
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
1
 | 
			
		||||
							
								
								
									
										7
									
								
								tests/qapi-schema/reserved-member-u.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/qapi-schema/reserved-member-u.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
# Potential C member name collision
 | 
			
		||||
# We reject use of 'u' as a member name, to allow it for internal use in
 | 
			
		||||
# putting union branch members in a separate namespace from QMP members.
 | 
			
		||||
# This is true even for non-unions, because it is possible to convert a
 | 
			
		||||
# struct to flat union while remaining backwards compatible in QMP.
 | 
			
		||||
# TODO - we could munge the member name to 'q_u' to avoid the collision
 | 
			
		||||
{ 'struct': 'Oops', 'data': { 'u': 'str' } }
 | 
			
		||||
							
								
								
									
										0
									
								
								tests/qapi-schema/reserved-member-u.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/qapi-schema/reserved-member-u.out
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-type-kind.err
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-type-kind.err
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
tests/qapi-schema/reserved-type-kind.json:2: enum 'UnionKind' should not end in 'Kind'
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-type-kind.exit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-type-kind.exit
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
1
 | 
			
		||||
@ -1,4 +1,2 @@
 | 
			
		||||
# we reject types that would conflict with implicit union enum
 | 
			
		||||
{ 'enum': 'UnionKind', 'data': [ 'oops' ] }
 | 
			
		||||
{ 'union': 'Union',
 | 
			
		||||
  'data': { 'a': 'int' } }
 | 
			
		||||
							
								
								
									
										0
									
								
								tests/qapi-schema/reserved-type-kind.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/qapi-schema/reserved-type-kind.out
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-type-list.err
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-type-list.err
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
tests/qapi-schema/reserved-type-list.json:5: struct 'FooList' should not end in 'List'
 | 
			
		||||
							
								
								
									
										1
									
								
								tests/qapi-schema/reserved-type-list.exit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/qapi-schema/reserved-type-list.exit
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
1
 | 
			
		||||
							
								
								
									
										5
									
								
								tests/qapi-schema/reserved-type-list.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								tests/qapi-schema/reserved-type-list.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
# Potential C name collision
 | 
			
		||||
# We reserve names ending in 'List' for use by array types.
 | 
			
		||||
# TODO - we could choose array names to avoid collision with user types,
 | 
			
		||||
# in order to let this compile
 | 
			
		||||
{ 'struct': 'FooList', 'data': { 's': 'str' } }
 | 
			
		||||
							
								
								
									
										0
									
								
								tests/qapi-schema/reserved-type-list.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/qapi-schema/reserved-type-list.out
									
									
									
									
									
										Normal file
									
								
							@ -1 +0,0 @@
 | 
			
		||||
0
 | 
			
		||||
@ -1,9 +0,0 @@
 | 
			
		||||
# Struct member 'base'
 | 
			
		||||
# FIXME: this parses, but then fails to compile due to a duplicate 'base'
 | 
			
		||||
# (one explicit in QMP, the other used to box the base class members).
 | 
			
		||||
# We should either reject the collision at parse time, or change the
 | 
			
		||||
# generated struct to allow this to compile.
 | 
			
		||||
{ 'struct': 'Base', 'data': {} }
 | 
			
		||||
{ 'struct': 'Sub',
 | 
			
		||||
  'base': 'Base',
 | 
			
		||||
  'data': { 'base': 'str' } }
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
object :empty
 | 
			
		||||
object Base
 | 
			
		||||
object Sub
 | 
			
		||||
    base Base
 | 
			
		||||
    member base: str optional=False
 | 
			
		||||
@ -25,11 +25,9 @@ UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a,
 | 
			
		||||
    UserDefOne *ud1d = g_malloc0(sizeof(UserDefOne));
 | 
			
		||||
 | 
			
		||||
    ud1c->string = strdup(ud1a->string);
 | 
			
		||||
    ud1c->base = g_new0(UserDefZero, 1);
 | 
			
		||||
    ud1c->base->integer = ud1a->base->integer;
 | 
			
		||||
    ud1c->integer = ud1a->integer;
 | 
			
		||||
    ud1d->string = strdup(has_udb1 ? ud1b->string : "blah0");
 | 
			
		||||
    ud1d->base = g_new0(UserDefZero, 1);
 | 
			
		||||
    ud1d->base->integer = has_udb1 ? ud1b->base->integer : 0;
 | 
			
		||||
    ud1d->integer = has_udb1 ? ud1b->integer : 0;
 | 
			
		||||
 | 
			
		||||
    ret = g_new0(UserDefTwo, 1);
 | 
			
		||||
    ret->string0 = strdup("blah1");
 | 
			
		||||
@ -64,8 +62,8 @@ __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
 | 
			
		||||
{
 | 
			
		||||
    __org_qemu_x_Union1 *ret = g_new0(__org_qemu_x_Union1, 1);
 | 
			
		||||
 | 
			
		||||
    ret->kind = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;
 | 
			
		||||
    ret->__org_qemu_x_branch = strdup("blah1");
 | 
			
		||||
    ret->type = ORG_QEMU_X_UNION1_KIND___ORG_QEMU_X_BRANCH;
 | 
			
		||||
    ret->u.__org_qemu_x_branch = strdup("blah1");
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
@ -176,20 +174,17 @@ static void test_dealloc_types(void)
 | 
			
		||||
    UserDefOneList *ud1list;
 | 
			
		||||
 | 
			
		||||
    ud1test = g_malloc0(sizeof(UserDefOne));
 | 
			
		||||
    ud1test->base = g_new0(UserDefZero, 1);
 | 
			
		||||
    ud1test->base->integer = 42;
 | 
			
		||||
    ud1test->integer = 42;
 | 
			
		||||
    ud1test->string = g_strdup("hi there 42");
 | 
			
		||||
 | 
			
		||||
    qapi_free_UserDefOne(ud1test);
 | 
			
		||||
 | 
			
		||||
    ud1a = g_malloc0(sizeof(UserDefOne));
 | 
			
		||||
    ud1a->base = g_new0(UserDefZero, 1);
 | 
			
		||||
    ud1a->base->integer = 43;
 | 
			
		||||
    ud1a->integer = 43;
 | 
			
		||||
    ud1a->string = g_strdup("hi there 43");
 | 
			
		||||
 | 
			
		||||
    ud1b = g_malloc0(sizeof(UserDefOne));
 | 
			
		||||
    ud1b->base = g_new0(UserDefZero, 1);
 | 
			
		||||
    ud1b->base->integer = 44;
 | 
			
		||||
    ud1b->integer = 44;
 | 
			
		||||
    ud1b->string = g_strdup("hi there 44");
 | 
			
		||||
 | 
			
		||||
    ud1list = g_malloc0(sizeof(UserDefOneList));
 | 
			
		||||
 | 
			
		||||
@ -179,9 +179,7 @@ static void test_event_c(TestEventData *data,
 | 
			
		||||
    QDict *d, *d_data, *d_b;
 | 
			
		||||
 | 
			
		||||
    UserDefOne b;
 | 
			
		||||
    UserDefZero z;
 | 
			
		||||
    z.integer = 2;
 | 
			
		||||
    b.base = &z;
 | 
			
		||||
    b.integer = 2;
 | 
			
		||||
    b.string = g_strdup("test1");
 | 
			
		||||
    b.has_enum1 = false;
 | 
			
		||||
 | 
			
		||||
@ -209,11 +207,9 @@ static void test_event_d(TestEventData *data,
 | 
			
		||||
{
 | 
			
		||||
    UserDefOne struct1;
 | 
			
		||||
    EventStructOne a;
 | 
			
		||||
    UserDefZero z;
 | 
			
		||||
    QDict *d, *d_data, *d_a, *d_struct1;
 | 
			
		||||
 | 
			
		||||
    z.integer = 2;
 | 
			
		||||
    struct1.base = &z;
 | 
			
		||||
    struct1.integer = 2;
 | 
			
		||||
    struct1.string = g_strdup("test1");
 | 
			
		||||
    struct1.has_enum1 = true;
 | 
			
		||||
    struct1.enum1 = ENUM_ONE_VALUE1;
 | 
			
		||||
 | 
			
		||||
@ -262,7 +262,7 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
 | 
			
		||||
 | 
			
		||||
    check_and_free_str(udp->string0, "string0");
 | 
			
		||||
    check_and_free_str(udp->dict1->string1, "string1");
 | 
			
		||||
    g_assert_cmpint(udp->dict1->dict2->userdef->base->integer, ==, 42);
 | 
			
		||||
    g_assert_cmpint(udp->dict1->dict2->userdef->integer, ==, 42);
 | 
			
		||||
    check_and_free_str(udp->dict1->dict2->userdef->string, "string");
 | 
			
		||||
    check_and_free_str(udp->dict1->dict2->string, "string2");
 | 
			
		||||
    g_assert(udp->dict1->has_dict3 == false);
 | 
			
		||||
@ -292,7 +292,7 @@ static void test_visitor_in_list(TestInputVisitorData *data,
 | 
			
		||||
 | 
			
		||||
        snprintf(string, sizeof(string), "string%d", i);
 | 
			
		||||
        g_assert_cmpstr(item->value->string, ==, string);
 | 
			
		||||
        g_assert_cmpint(item->value->base->integer, ==, 42 + i);
 | 
			
		||||
        g_assert_cmpint(item->value->integer, ==, 42 + i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qapi_free_UserDefOneList(head);
 | 
			
		||||
@ -347,6 +347,7 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
 | 
			
		||||
    Visitor *v;
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
    UserDefFlatUnion *tmp;
 | 
			
		||||
    UserDefUnionBase *base;
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data,
 | 
			
		||||
                                "{ 'enum1': 'value1', "
 | 
			
		||||
@ -359,7 +360,11 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
 | 
			
		||||
    g_assert_cmpint(tmp->enum1, ==, ENUM_ONE_VALUE1);
 | 
			
		||||
    g_assert_cmpstr(tmp->string, ==, "str");
 | 
			
		||||
    g_assert_cmpint(tmp->integer, ==, 41);
 | 
			
		||||
    g_assert_cmpint(tmp->value1->boolean, ==, true);
 | 
			
		||||
    g_assert_cmpint(tmp->u.value1->boolean, ==, true);
 | 
			
		||||
 | 
			
		||||
    base = qapi_UserDefFlatUnion_base(tmp);
 | 
			
		||||
    g_assert(&base->enum1 == &tmp->enum1);
 | 
			
		||||
 | 
			
		||||
    qapi_free_UserDefFlatUnion(tmp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -372,15 +377,15 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data, "42");
 | 
			
		||||
    visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
 | 
			
		||||
    g_assert_cmpint(tmp->kind, ==, USER_DEF_ALTERNATE_KIND_I);
 | 
			
		||||
    g_assert_cmpint(tmp->i, ==, 42);
 | 
			
		||||
    g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_I);
 | 
			
		||||
    g_assert_cmpint(tmp->u.i, ==, 42);
 | 
			
		||||
    qapi_free_UserDefAlternate(tmp);
 | 
			
		||||
    visitor_input_teardown(data, NULL);
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data, "'string'");
 | 
			
		||||
    visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort);
 | 
			
		||||
    g_assert_cmpint(tmp->kind, ==, USER_DEF_ALTERNATE_KIND_S);
 | 
			
		||||
    g_assert_cmpstr(tmp->s, ==, "string");
 | 
			
		||||
    g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_S);
 | 
			
		||||
    g_assert_cmpstr(tmp->u.s, ==, "string");
 | 
			
		||||
    qapi_free_UserDefAlternate(tmp);
 | 
			
		||||
    visitor_input_teardown(data, NULL);
 | 
			
		||||
 | 
			
		||||
@ -419,8 +424,8 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 | 
			
		||||
     * parse the same as ans */
 | 
			
		||||
    v = visitor_input_test_init(data, "42");
 | 
			
		||||
    visit_type_AltStrNum(v, &asn, NULL, &err);
 | 
			
		||||
    /* FIXME g_assert_cmpint(asn->kind, == ALT_STR_NUM_KIND_N); */
 | 
			
		||||
    /* FIXME g_assert_cmpfloat(asn->n, ==, 42); */
 | 
			
		||||
    /* FIXME g_assert_cmpint(asn->type, == ALT_STR_NUM_KIND_N); */
 | 
			
		||||
    /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */
 | 
			
		||||
    g_assert(err);
 | 
			
		||||
    error_free(err);
 | 
			
		||||
    err = NULL;
 | 
			
		||||
@ -429,29 +434,29 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data, "42");
 | 
			
		||||
    visit_type_AltNumStr(v, &ans, NULL, &error_abort);
 | 
			
		||||
    g_assert_cmpint(ans->kind, ==, ALT_NUM_STR_KIND_N);
 | 
			
		||||
    g_assert_cmpfloat(ans->n, ==, 42);
 | 
			
		||||
    g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
 | 
			
		||||
    g_assert_cmpfloat(ans->u.n, ==, 42);
 | 
			
		||||
    qapi_free_AltNumStr(ans);
 | 
			
		||||
    visitor_input_teardown(data, NULL);
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data, "42");
 | 
			
		||||
    visit_type_AltStrInt(v, &asi, NULL, &error_abort);
 | 
			
		||||
    g_assert_cmpint(asi->kind, ==, ALT_STR_INT_KIND_I);
 | 
			
		||||
    g_assert_cmpint(asi->i, ==, 42);
 | 
			
		||||
    g_assert_cmpint(asi->type, ==, ALT_STR_INT_KIND_I);
 | 
			
		||||
    g_assert_cmpint(asi->u.i, ==, 42);
 | 
			
		||||
    qapi_free_AltStrInt(asi);
 | 
			
		||||
    visitor_input_teardown(data, NULL);
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data, "42");
 | 
			
		||||
    visit_type_AltIntNum(v, &ain, NULL, &error_abort);
 | 
			
		||||
    g_assert_cmpint(ain->kind, ==, ALT_INT_NUM_KIND_I);
 | 
			
		||||
    g_assert_cmpint(ain->i, ==, 42);
 | 
			
		||||
    g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_I);
 | 
			
		||||
    g_assert_cmpint(ain->u.i, ==, 42);
 | 
			
		||||
    qapi_free_AltIntNum(ain);
 | 
			
		||||
    visitor_input_teardown(data, NULL);
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data, "42");
 | 
			
		||||
    visit_type_AltNumInt(v, &ani, NULL, &error_abort);
 | 
			
		||||
    g_assert_cmpint(ani->kind, ==, ALT_NUM_INT_KIND_I);
 | 
			
		||||
    g_assert_cmpint(ani->i, ==, 42);
 | 
			
		||||
    g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_I);
 | 
			
		||||
    g_assert_cmpint(ani->u.i, ==, 42);
 | 
			
		||||
    qapi_free_AltNumInt(ani);
 | 
			
		||||
    visitor_input_teardown(data, NULL);
 | 
			
		||||
 | 
			
		||||
@ -467,15 +472,15 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data, "42.5");
 | 
			
		||||
    visit_type_AltStrNum(v, &asn, NULL, &error_abort);
 | 
			
		||||
    g_assert_cmpint(asn->kind, ==, ALT_STR_NUM_KIND_N);
 | 
			
		||||
    g_assert_cmpfloat(asn->n, ==, 42.5);
 | 
			
		||||
    g_assert_cmpint(asn->type, ==, ALT_STR_NUM_KIND_N);
 | 
			
		||||
    g_assert_cmpfloat(asn->u.n, ==, 42.5);
 | 
			
		||||
    qapi_free_AltStrNum(asn);
 | 
			
		||||
    visitor_input_teardown(data, NULL);
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data, "42.5");
 | 
			
		||||
    visit_type_AltNumStr(v, &ans, NULL, &error_abort);
 | 
			
		||||
    g_assert_cmpint(ans->kind, ==, ALT_NUM_STR_KIND_N);
 | 
			
		||||
    g_assert_cmpfloat(ans->n, ==, 42.5);
 | 
			
		||||
    g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N);
 | 
			
		||||
    g_assert_cmpfloat(ans->u.n, ==, 42.5);
 | 
			
		||||
    qapi_free_AltNumStr(ans);
 | 
			
		||||
    visitor_input_teardown(data, NULL);
 | 
			
		||||
 | 
			
		||||
@ -489,15 +494,15 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data,
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data, "42.5");
 | 
			
		||||
    visit_type_AltIntNum(v, &ain, NULL, &error_abort);
 | 
			
		||||
    g_assert_cmpint(ain->kind, ==, ALT_INT_NUM_KIND_N);
 | 
			
		||||
    g_assert_cmpfloat(ain->n, ==, 42.5);
 | 
			
		||||
    g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_N);
 | 
			
		||||
    g_assert_cmpfloat(ain->u.n, ==, 42.5);
 | 
			
		||||
    qapi_free_AltIntNum(ain);
 | 
			
		||||
    visitor_input_teardown(data, NULL);
 | 
			
		||||
 | 
			
		||||
    v = visitor_input_test_init(data, "42.5");
 | 
			
		||||
    visit_type_AltNumInt(v, &ani, NULL, &error_abort);
 | 
			
		||||
    g_assert_cmpint(ani->kind, ==, ALT_NUM_INT_KIND_N);
 | 
			
		||||
    g_assert_cmpfloat(ani->n, ==, 42.5);
 | 
			
		||||
    g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_N);
 | 
			
		||||
    g_assert_cmpfloat(ani->u.n, ==, 42.5);
 | 
			
		||||
    qapi_free_AltNumInt(ani);
 | 
			
		||||
    visitor_input_teardown(data, NULL);
 | 
			
		||||
}
 | 
			
		||||
@ -527,68 +532,68 @@ static void test_native_list_integer_helper(TestInputVisitorData *data,
 | 
			
		||||
    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
 | 
			
		||||
    g_assert(err == NULL);
 | 
			
		||||
    g_assert(cvalue != NULL);
 | 
			
		||||
    g_assert_cmpint(cvalue->kind, ==, kind);
 | 
			
		||||
    g_assert_cmpint(cvalue->type, ==, kind);
 | 
			
		||||
 | 
			
		||||
    switch (kind) {
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
 | 
			
		||||
        intList *elem = NULL;
 | 
			
		||||
        for (i = 0, elem = cvalue->integer; elem; elem = elem->next, i++) {
 | 
			
		||||
        for (i = 0, elem = cvalue->u.integer; elem; elem = elem->next, i++) {
 | 
			
		||||
            g_assert_cmpint(elem->value, ==, i);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
 | 
			
		||||
        int8List *elem = NULL;
 | 
			
		||||
        for (i = 0, elem = cvalue->s8; elem; elem = elem->next, i++) {
 | 
			
		||||
        for (i = 0, elem = cvalue->u.s8; elem; elem = elem->next, i++) {
 | 
			
		||||
            g_assert_cmpint(elem->value, ==, i);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
 | 
			
		||||
        int16List *elem = NULL;
 | 
			
		||||
        for (i = 0, elem = cvalue->s16; elem; elem = elem->next, i++) {
 | 
			
		||||
        for (i = 0, elem = cvalue->u.s16; elem; elem = elem->next, i++) {
 | 
			
		||||
            g_assert_cmpint(elem->value, ==, i);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
 | 
			
		||||
        int32List *elem = NULL;
 | 
			
		||||
        for (i = 0, elem = cvalue->s32; elem; elem = elem->next, i++) {
 | 
			
		||||
        for (i = 0, elem = cvalue->u.s32; elem; elem = elem->next, i++) {
 | 
			
		||||
            g_assert_cmpint(elem->value, ==, i);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
 | 
			
		||||
        int64List *elem = NULL;
 | 
			
		||||
        for (i = 0, elem = cvalue->s64; elem; elem = elem->next, i++) {
 | 
			
		||||
        for (i = 0, elem = cvalue->u.s64; elem; elem = elem->next, i++) {
 | 
			
		||||
            g_assert_cmpint(elem->value, ==, i);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
 | 
			
		||||
        uint8List *elem = NULL;
 | 
			
		||||
        for (i = 0, elem = cvalue->u8; elem; elem = elem->next, i++) {
 | 
			
		||||
        for (i = 0, elem = cvalue->u.u8; elem; elem = elem->next, i++) {
 | 
			
		||||
            g_assert_cmpint(elem->value, ==, i);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
 | 
			
		||||
        uint16List *elem = NULL;
 | 
			
		||||
        for (i = 0, elem = cvalue->u16; elem; elem = elem->next, i++) {
 | 
			
		||||
        for (i = 0, elem = cvalue->u.u16; elem; elem = elem->next, i++) {
 | 
			
		||||
            g_assert_cmpint(elem->value, ==, i);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
 | 
			
		||||
        uint32List *elem = NULL;
 | 
			
		||||
        for (i = 0, elem = cvalue->u32; elem; elem = elem->next, i++) {
 | 
			
		||||
        for (i = 0, elem = cvalue->u.u32; elem; elem = elem->next, i++) {
 | 
			
		||||
            g_assert_cmpint(elem->value, ==, i);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
 | 
			
		||||
        uint64List *elem = NULL;
 | 
			
		||||
        for (i = 0, elem = cvalue->u64; elem; elem = elem->next, i++) {
 | 
			
		||||
        for (i = 0, elem = cvalue->u.u64; elem; elem = elem->next, i++) {
 | 
			
		||||
            g_assert_cmpint(elem->value, ==, i);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
@ -690,9 +695,9 @@ static void test_visitor_in_native_list_bool(TestInputVisitorData *data,
 | 
			
		||||
    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
 | 
			
		||||
    g_assert(err == NULL);
 | 
			
		||||
    g_assert(cvalue != NULL);
 | 
			
		||||
    g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
 | 
			
		||||
    g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN);
 | 
			
		||||
 | 
			
		||||
    for (i = 0, elem = cvalue->boolean; elem; elem = elem->next, i++) {
 | 
			
		||||
    for (i = 0, elem = cvalue->u.boolean; elem; elem = elem->next, i++) {
 | 
			
		||||
        g_assert_cmpint(elem->value, ==, (i % 3 == 0) ? 1 : 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -725,9 +730,9 @@ static void test_visitor_in_native_list_string(TestInputVisitorData *data,
 | 
			
		||||
    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
 | 
			
		||||
    g_assert(err == NULL);
 | 
			
		||||
    g_assert(cvalue != NULL);
 | 
			
		||||
    g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
 | 
			
		||||
    g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_STRING);
 | 
			
		||||
 | 
			
		||||
    for (i = 0, elem = cvalue->string; elem; elem = elem->next, i++) {
 | 
			
		||||
    for (i = 0, elem = cvalue->u.string; elem; elem = elem->next, i++) {
 | 
			
		||||
        gchar str[8];
 | 
			
		||||
        sprintf(str, "%d", i);
 | 
			
		||||
        g_assert_cmpstr(elem->value, ==, str);
 | 
			
		||||
@ -764,9 +769,9 @@ static void test_visitor_in_native_list_number(TestInputVisitorData *data,
 | 
			
		||||
    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);
 | 
			
		||||
    g_assert(err == NULL);
 | 
			
		||||
    g_assert(cvalue != NULL);
 | 
			
		||||
    g_assert_cmpint(cvalue->kind, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
 | 
			
		||||
    g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);
 | 
			
		||||
 | 
			
		||||
    for (i = 0, elem = cvalue->number; elem; elem = elem->next, i++) {
 | 
			
		||||
    for (i = 0, elem = cvalue->u.number; elem; elem = elem->next, i++) {
 | 
			
		||||
        GString *double_expected = g_string_new("");
 | 
			
		||||
        GString *double_actual = g_string_new("");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -250,16 +250,14 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
 | 
			
		||||
    ud2->dict1->dict2 = g_malloc0(sizeof(*ud2->dict1->dict2));
 | 
			
		||||
    ud2->dict1->dict2->userdef = g_new0(UserDefOne, 1);
 | 
			
		||||
    ud2->dict1->dict2->userdef->string = g_strdup(string);
 | 
			
		||||
    ud2->dict1->dict2->userdef->base = g_new0(UserDefZero, 1);
 | 
			
		||||
    ud2->dict1->dict2->userdef->base->integer = value;
 | 
			
		||||
    ud2->dict1->dict2->userdef->integer = value;
 | 
			
		||||
    ud2->dict1->dict2->string = g_strdup(strings[2]);
 | 
			
		||||
 | 
			
		||||
    ud2->dict1->dict3 = g_malloc0(sizeof(*ud2->dict1->dict3));
 | 
			
		||||
    ud2->dict1->has_dict3 = true;
 | 
			
		||||
    ud2->dict1->dict3->userdef = g_new0(UserDefOne, 1);
 | 
			
		||||
    ud2->dict1->dict3->userdef->string = g_strdup(string);
 | 
			
		||||
    ud2->dict1->dict3->userdef->base = g_new0(UserDefZero, 1);
 | 
			
		||||
    ud2->dict1->dict3->userdef->base->integer = value;
 | 
			
		||||
    ud2->dict1->dict3->userdef->integer = value;
 | 
			
		||||
    ud2->dict1->dict3->string = g_strdup(strings[3]);
 | 
			
		||||
 | 
			
		||||
    visit_type_UserDefTwo(data->ov, &ud2, "unused", &err);
 | 
			
		||||
@ -301,8 +299,8 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
 | 
			
		||||
                                           const void *unused)
 | 
			
		||||
{
 | 
			
		||||
    EnumOne bad_values[] = { ENUM_ONE_MAX, -1 };
 | 
			
		||||
    UserDefZero b;
 | 
			
		||||
    UserDefOne u = { .base = &b }, *pu = &u;
 | 
			
		||||
    UserDefOne u = {0};
 | 
			
		||||
    UserDefOne *pu = &u;
 | 
			
		||||
    Error *err;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
@ -416,8 +414,7 @@ static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
 | 
			
		||||
        p->value->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);
 | 
			
		||||
        p->value->dict1->dict2->userdef = g_new0(UserDefOne, 1);
 | 
			
		||||
        p->value->dict1->dict2->userdef->string = g_strdup(string);
 | 
			
		||||
        p->value->dict1->dict2->userdef->base = g_new0(UserDefZero, 1);
 | 
			
		||||
        p->value->dict1->dict2->userdef->base->integer = 42;
 | 
			
		||||
        p->value->dict1->dict2->userdef->integer = 42;
 | 
			
		||||
        p->value->dict1->dict2->string = g_strdup(string);
 | 
			
		||||
        p->value->dict1->has_dict3 = false;
 | 
			
		||||
 | 
			
		||||
@ -490,9 +487,9 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
 | 
			
		||||
    UserDefFlatUnion *tmp = g_malloc0(sizeof(UserDefFlatUnion));
 | 
			
		||||
    tmp->enum1 = ENUM_ONE_VALUE1;
 | 
			
		||||
    tmp->string = g_strdup("str");
 | 
			
		||||
    tmp->value1 = g_malloc0(sizeof(UserDefA));
 | 
			
		||||
    /* TODO when generator bug is fixed: tmp->integer = 41; */
 | 
			
		||||
    tmp->value1->boolean = true;
 | 
			
		||||
    tmp->u.value1 = g_malloc0(sizeof(UserDefA));
 | 
			
		||||
    tmp->integer = 41;
 | 
			
		||||
    tmp->u.value1->boolean = true;
 | 
			
		||||
 | 
			
		||||
    visit_type_UserDefFlatUnion(data->ov, &tmp, NULL, &err);
 | 
			
		||||
    g_assert(err == NULL);
 | 
			
		||||
@ -503,7 +500,7 @@ static void test_visitor_out_union_flat(TestOutputVisitorData *data,
 | 
			
		||||
 | 
			
		||||
    g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");
 | 
			
		||||
    g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");
 | 
			
		||||
    /* TODO g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41); */
 | 
			
		||||
    g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 41);
 | 
			
		||||
    g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);
 | 
			
		||||
 | 
			
		||||
    qapi_free_UserDefFlatUnion(tmp);
 | 
			
		||||
@ -517,8 +514,8 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
 | 
			
		||||
    UserDefAlternate *tmp = g_malloc0(sizeof(UserDefAlternate));
 | 
			
		||||
    tmp->kind = USER_DEF_ALTERNATE_KIND_I;
 | 
			
		||||
    tmp->i = 42;
 | 
			
		||||
    tmp->type = USER_DEF_ALTERNATE_KIND_I;
 | 
			
		||||
    tmp->u.i = 42;
 | 
			
		||||
 | 
			
		||||
    visit_type_UserDefAlternate(data->ov, &tmp, NULL, &err);
 | 
			
		||||
    g_assert(err == NULL);
 | 
			
		||||
@ -543,9 +540,9 @@ static void test_visitor_out_empty(TestOutputVisitorData *data,
 | 
			
		||||
static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    switch (cvalue->kind) {
 | 
			
		||||
    switch (cvalue->type) {
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: {
 | 
			
		||||
        intList **list = &cvalue->integer;
 | 
			
		||||
        intList **list = &cvalue->u.integer;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(intList, 1);
 | 
			
		||||
            (*list)->value = i;
 | 
			
		||||
@ -555,7 +552,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_S8: {
 | 
			
		||||
        int8List **list = &cvalue->s8;
 | 
			
		||||
        int8List **list = &cvalue->u.s8;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(int8List, 1);
 | 
			
		||||
            (*list)->value = i;
 | 
			
		||||
@ -565,7 +562,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_S16: {
 | 
			
		||||
        int16List **list = &cvalue->s16;
 | 
			
		||||
        int16List **list = &cvalue->u.s16;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(int16List, 1);
 | 
			
		||||
            (*list)->value = i;
 | 
			
		||||
@ -575,7 +572,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_S32: {
 | 
			
		||||
        int32List **list = &cvalue->s32;
 | 
			
		||||
        int32List **list = &cvalue->u.s32;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(int32List, 1);
 | 
			
		||||
            (*list)->value = i;
 | 
			
		||||
@ -585,7 +582,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_S64: {
 | 
			
		||||
        int64List **list = &cvalue->s64;
 | 
			
		||||
        int64List **list = &cvalue->u.s64;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(int64List, 1);
 | 
			
		||||
            (*list)->value = i;
 | 
			
		||||
@ -595,7 +592,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_U8: {
 | 
			
		||||
        uint8List **list = &cvalue->u8;
 | 
			
		||||
        uint8List **list = &cvalue->u.u8;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(uint8List, 1);
 | 
			
		||||
            (*list)->value = i;
 | 
			
		||||
@ -605,7 +602,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_U16: {
 | 
			
		||||
        uint16List **list = &cvalue->u16;
 | 
			
		||||
        uint16List **list = &cvalue->u.u16;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(uint16List, 1);
 | 
			
		||||
            (*list)->value = i;
 | 
			
		||||
@ -615,7 +612,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_U32: {
 | 
			
		||||
        uint32List **list = &cvalue->u32;
 | 
			
		||||
        uint32List **list = &cvalue->u.u32;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(uint32List, 1);
 | 
			
		||||
            (*list)->value = i;
 | 
			
		||||
@ -625,7 +622,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_U64: {
 | 
			
		||||
        uint64List **list = &cvalue->u64;
 | 
			
		||||
        uint64List **list = &cvalue->u.u64;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(uint64List, 1);
 | 
			
		||||
            (*list)->value = i;
 | 
			
		||||
@ -635,7 +632,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_BOOLEAN: {
 | 
			
		||||
        boolList **list = &cvalue->boolean;
 | 
			
		||||
        boolList **list = &cvalue->u.boolean;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(boolList, 1);
 | 
			
		||||
            (*list)->value = (i % 3 == 0);
 | 
			
		||||
@ -645,7 +642,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_STRING: {
 | 
			
		||||
        strList **list = &cvalue->string;
 | 
			
		||||
        strList **list = &cvalue->u.string;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(strList, 1);
 | 
			
		||||
            (*list)->value = g_strdup_printf("%d", i);
 | 
			
		||||
@ -655,7 +652,7 @@ static void init_native_list(UserDefNativeListUnion *cvalue)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: {
 | 
			
		||||
        numberList **list = &cvalue->number;
 | 
			
		||||
        numberList **list = &cvalue->u.number;
 | 
			
		||||
        for (i = 0; i < 32; i++) {
 | 
			
		||||
            *list = g_new0(numberList, 1);
 | 
			
		||||
            (*list)->value = (double)i / 3;
 | 
			
		||||
@ -764,14 +761,14 @@ static void test_native_list(TestOutputVisitorData *data,
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
    QObject *obj;
 | 
			
		||||
 | 
			
		||||
    cvalue->kind = kind;
 | 
			
		||||
    cvalue->type = kind;
 | 
			
		||||
    init_native_list(cvalue);
 | 
			
		||||
 | 
			
		||||
    visit_type_UserDefNativeListUnion(data->ov, &cvalue, NULL, &err);
 | 
			
		||||
    g_assert(err == NULL);
 | 
			
		||||
 | 
			
		||||
    obj = qmp_output_get_qobject(data->qov);
 | 
			
		||||
    check_native_list(obj, cvalue->kind);
 | 
			
		||||
    check_native_list(obj, cvalue->type);
 | 
			
		||||
    qapi_free_UserDefNativeListUnion(cvalue);
 | 
			
		||||
    qobject_decref(obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -258,15 +258,13 @@ static UserDefTwo *nested_struct_create(void)
 | 
			
		||||
    udnp->dict1->string1 = strdup("test_string1");
 | 
			
		||||
    udnp->dict1->dict2 = g_malloc0(sizeof(*udnp->dict1->dict2));
 | 
			
		||||
    udnp->dict1->dict2->userdef = g_new0(UserDefOne, 1);
 | 
			
		||||
    udnp->dict1->dict2->userdef->base = g_new0(UserDefZero, 1);
 | 
			
		||||
    udnp->dict1->dict2->userdef->base->integer = 42;
 | 
			
		||||
    udnp->dict1->dict2->userdef->integer = 42;
 | 
			
		||||
    udnp->dict1->dict2->userdef->string = strdup("test_string");
 | 
			
		||||
    udnp->dict1->dict2->string = strdup("test_string2");
 | 
			
		||||
    udnp->dict1->dict3 = g_malloc0(sizeof(*udnp->dict1->dict3));
 | 
			
		||||
    udnp->dict1->has_dict3 = true;
 | 
			
		||||
    udnp->dict1->dict3->userdef = g_new0(UserDefOne, 1);
 | 
			
		||||
    udnp->dict1->dict3->userdef->base = g_new0(UserDefZero, 1);
 | 
			
		||||
    udnp->dict1->dict3->userdef->base->integer = 43;
 | 
			
		||||
    udnp->dict1->dict3->userdef->integer = 43;
 | 
			
		||||
    udnp->dict1->dict3->userdef->string = strdup("test_string");
 | 
			
		||||
    udnp->dict1->dict3->string = strdup("test_string3");
 | 
			
		||||
    return udnp;
 | 
			
		||||
@ -278,15 +276,15 @@ static void nested_struct_compare(UserDefTwo *udnp1, UserDefTwo *udnp2)
 | 
			
		||||
    g_assert(udnp2);
 | 
			
		||||
    g_assert_cmpstr(udnp1->string0, ==, udnp2->string0);
 | 
			
		||||
    g_assert_cmpstr(udnp1->dict1->string1, ==, udnp2->dict1->string1);
 | 
			
		||||
    g_assert_cmpint(udnp1->dict1->dict2->userdef->base->integer, ==,
 | 
			
		||||
                    udnp2->dict1->dict2->userdef->base->integer);
 | 
			
		||||
    g_assert_cmpint(udnp1->dict1->dict2->userdef->integer, ==,
 | 
			
		||||
                    udnp2->dict1->dict2->userdef->integer);
 | 
			
		||||
    g_assert_cmpstr(udnp1->dict1->dict2->userdef->string, ==,
 | 
			
		||||
                    udnp2->dict1->dict2->userdef->string);
 | 
			
		||||
    g_assert_cmpstr(udnp1->dict1->dict2->string, ==,
 | 
			
		||||
                    udnp2->dict1->dict2->string);
 | 
			
		||||
    g_assert(udnp1->dict1->has_dict3 == udnp2->dict1->has_dict3);
 | 
			
		||||
    g_assert_cmpint(udnp1->dict1->dict3->userdef->base->integer, ==,
 | 
			
		||||
                    udnp2->dict1->dict3->userdef->base->integer);
 | 
			
		||||
    g_assert_cmpint(udnp1->dict1->dict3->userdef->integer, ==,
 | 
			
		||||
                    udnp2->dict1->dict3->userdef->integer);
 | 
			
		||||
    g_assert_cmpstr(udnp1->dict1->dict3->userdef->string, ==,
 | 
			
		||||
                    udnp2->dict1->dict3->userdef->string);
 | 
			
		||||
    g_assert_cmpstr(udnp1->dict1->dict3->string, ==,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								tpm.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tpm.c
									
									
									
									
									
								
							@ -260,9 +260,9 @@ static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv)
 | 
			
		||||
 | 
			
		||||
    switch (drv->ops->type) {
 | 
			
		||||
    case TPM_TYPE_PASSTHROUGH:
 | 
			
		||||
        res->options->kind = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH;
 | 
			
		||||
        res->options->type = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH;
 | 
			
		||||
        tpo = g_new0(TPMPassthroughOptions, 1);
 | 
			
		||||
        res->options->passthrough = tpo;
 | 
			
		||||
        res->options->u.passthrough = tpo;
 | 
			
		||||
        if (drv->path) {
 | 
			
		||||
            tpo->path = g_strdup(drv->path);
 | 
			
		||||
            tpo->has_path = true;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								ui/console.c
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								ui/console.c
									
									
									
									
									
								
							@ -2016,7 +2016,7 @@ static VcHandler *vc_handler = text_console_init;
 | 
			
		||||
static CharDriverState *vc_init(const char *id, ChardevBackend *backend,
 | 
			
		||||
                                ChardevReturn *ret, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    return vc_handler(backend->vc, errp);
 | 
			
		||||
    return vc_handler(backend->u.vc, errp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void register_vc_handler(VcHandler *handler)
 | 
			
		||||
@ -2057,30 +2057,30 @@ static void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend,
 | 
			
		||||
{
 | 
			
		||||
    int val;
 | 
			
		||||
 | 
			
		||||
    backend->vc = g_new0(ChardevVC, 1);
 | 
			
		||||
    backend->u.vc = g_new0(ChardevVC, 1);
 | 
			
		||||
 | 
			
		||||
    val = qemu_opt_get_number(opts, "width", 0);
 | 
			
		||||
    if (val != 0) {
 | 
			
		||||
        backend->vc->has_width = true;
 | 
			
		||||
        backend->vc->width = val;
 | 
			
		||||
        backend->u.vc->has_width = true;
 | 
			
		||||
        backend->u.vc->width = val;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    val = qemu_opt_get_number(opts, "height", 0);
 | 
			
		||||
    if (val != 0) {
 | 
			
		||||
        backend->vc->has_height = true;
 | 
			
		||||
        backend->vc->height = val;
 | 
			
		||||
        backend->u.vc->has_height = true;
 | 
			
		||||
        backend->u.vc->height = val;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    val = qemu_opt_get_number(opts, "cols", 0);
 | 
			
		||||
    if (val != 0) {
 | 
			
		||||
        backend->vc->has_cols = true;
 | 
			
		||||
        backend->vc->cols = val;
 | 
			
		||||
        backend->u.vc->has_cols = true;
 | 
			
		||||
        backend->u.vc->cols = val;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    val = qemu_opt_get_number(opts, "rows", 0);
 | 
			
		||||
    if (val != 0) {
 | 
			
		||||
        backend->vc->has_rows = true;
 | 
			
		||||
        backend->vc->rows = val;
 | 
			
		||||
        backend->u.vc->has_rows = true;
 | 
			
		||||
        backend->u.vc->rows = val;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -139,11 +139,11 @@ static int number_to_qcode[0x100];
 | 
			
		||||
 | 
			
		||||
int qemu_input_key_value_to_number(const KeyValue *value)
 | 
			
		||||
{
 | 
			
		||||
    if (value->kind == KEY_VALUE_KIND_QCODE) {
 | 
			
		||||
        return qcode_to_number[value->qcode];
 | 
			
		||||
    if (value->type == KEY_VALUE_KIND_QCODE) {
 | 
			
		||||
        return qcode_to_number[value->u.qcode];
 | 
			
		||||
    } else {
 | 
			
		||||
        assert(value->kind == KEY_VALUE_KIND_NUMBER);
 | 
			
		||||
        return value->number;
 | 
			
		||||
        assert(value->type == KEY_VALUE_KIND_NUMBER);
 | 
			
		||||
        return value->u.number;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -166,11 +166,11 @@ int qemu_input_key_number_to_qcode(uint8_t nr)
 | 
			
		||||
 | 
			
		||||
int qemu_input_key_value_to_qcode(const KeyValue *value)
 | 
			
		||||
{
 | 
			
		||||
    if (value->kind == KEY_VALUE_KIND_QCODE) {
 | 
			
		||||
        return value->qcode;
 | 
			
		||||
    if (value->type == KEY_VALUE_KIND_QCODE) {
 | 
			
		||||
        return value->u.qcode;
 | 
			
		||||
    } else {
 | 
			
		||||
        assert(value->kind == KEY_VALUE_KIND_NUMBER);
 | 
			
		||||
        return qemu_input_key_number_to_qcode(value->number);
 | 
			
		||||
        assert(value->type == KEY_VALUE_KIND_NUMBER);
 | 
			
		||||
        return qemu_input_key_number_to_qcode(value->u.number);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -180,8 +180,8 @@ int qemu_input_key_value_to_scancode(const KeyValue *value, bool down,
 | 
			
		||||
    int keycode = qemu_input_key_value_to_number(value);
 | 
			
		||||
    int count = 0;
 | 
			
		||||
 | 
			
		||||
    if (value->kind == KEY_VALUE_KIND_QCODE &&
 | 
			
		||||
        value->qcode == Q_KEY_CODE_PAUSE) {
 | 
			
		||||
    if (value->type == KEY_VALUE_KIND_QCODE &&
 | 
			
		||||
        value->u.qcode == Q_KEY_CODE_PAUSE) {
 | 
			
		||||
        /* specific case */
 | 
			
		||||
        int v = down ? 0 : 0x80;
 | 
			
		||||
        codes[count++] = 0xe1;
 | 
			
		||||
 | 
			
		||||
@ -113,8 +113,8 @@ static void legacy_kbd_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
    if (!entry || !entry->put_kbd) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    count = qemu_input_key_value_to_scancode(evt->key->key,
 | 
			
		||||
                                             evt->key->down,
 | 
			
		||||
    count = qemu_input_key_value_to_scancode(evt->u.key->key,
 | 
			
		||||
                                             evt->u.key->down,
 | 
			
		||||
                                             scancodes);
 | 
			
		||||
    for (i = 0; i < count; i++) {
 | 
			
		||||
        entry->put_kbd(entry->opaque, scancodes[i]);
 | 
			
		||||
@ -150,21 +150,22 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
    };
 | 
			
		||||
    QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
 | 
			
		||||
 | 
			
		||||
    switch (evt->kind) {
 | 
			
		||||
    switch (evt->type) {
 | 
			
		||||
    case INPUT_EVENT_KIND_BTN:
 | 
			
		||||
        if (evt->btn->down) {
 | 
			
		||||
            s->buttons |= bmap[evt->btn->button];
 | 
			
		||||
        if (evt->u.btn->down) {
 | 
			
		||||
            s->buttons |= bmap[evt->u.btn->button];
 | 
			
		||||
        } else {
 | 
			
		||||
            s->buttons &= ~bmap[evt->btn->button];
 | 
			
		||||
            s->buttons &= ~bmap[evt->u.btn->button];
 | 
			
		||||
        }
 | 
			
		||||
        if (evt->btn->down && evt->btn->button == INPUT_BUTTON_WHEEL_UP) {
 | 
			
		||||
        if (evt->u.btn->down && evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) {
 | 
			
		||||
            s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
 | 
			
		||||
                                    s->axis[INPUT_AXIS_X],
 | 
			
		||||
                                    s->axis[INPUT_AXIS_Y],
 | 
			
		||||
                                    -1,
 | 
			
		||||
                                    s->buttons);
 | 
			
		||||
        }
 | 
			
		||||
        if (evt->btn->down && evt->btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 | 
			
		||||
        if (evt->u.btn->down &&
 | 
			
		||||
            evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 | 
			
		||||
            s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
 | 
			
		||||
                                    s->axis[INPUT_AXIS_X],
 | 
			
		||||
                                    s->axis[INPUT_AXIS_Y],
 | 
			
		||||
@ -173,10 +174,10 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case INPUT_EVENT_KIND_ABS:
 | 
			
		||||
        s->axis[evt->abs->axis] = evt->abs->value;
 | 
			
		||||
        s->axis[evt->u.abs->axis] = evt->u.abs->value;
 | 
			
		||||
        break;
 | 
			
		||||
    case INPUT_EVENT_KIND_REL:
 | 
			
		||||
        s->axis[evt->rel->axis] += evt->rel->value;
 | 
			
		||||
        s->axis[evt->u.rel->axis] += evt->u.rel->value;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										84
									
								
								ui/input.c
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								ui/input.c
									
									
									
									
									
								
							@ -147,10 +147,10 @@ void qmp_x_input_send_event(bool has_console, int64_t console,
 | 
			
		||||
    for (e = events; e != NULL; e = e->next) {
 | 
			
		||||
        InputEvent *event = e->value;
 | 
			
		||||
 | 
			
		||||
        if (!qemu_input_find_handler(1 << event->kind, con)) {
 | 
			
		||||
        if (!qemu_input_find_handler(1 << event->type, con)) {
 | 
			
		||||
            error_setg(errp, "Input handler not found for "
 | 
			
		||||
                             "event type %s",
 | 
			
		||||
                            InputEventKind_lookup[event->kind]);
 | 
			
		||||
                            InputEventKind_lookup[event->type]);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -168,22 +168,22 @@ static void qemu_input_transform_abs_rotate(InputEvent *evt)
 | 
			
		||||
{
 | 
			
		||||
    switch (graphic_rotate) {
 | 
			
		||||
    case 90:
 | 
			
		||||
        if (evt->abs->axis == INPUT_AXIS_X) {
 | 
			
		||||
            evt->abs->axis = INPUT_AXIS_Y;
 | 
			
		||||
        } else if (evt->abs->axis == INPUT_AXIS_Y) {
 | 
			
		||||
            evt->abs->axis = INPUT_AXIS_X;
 | 
			
		||||
            evt->abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->value;
 | 
			
		||||
        if (evt->u.abs->axis == INPUT_AXIS_X) {
 | 
			
		||||
            evt->u.abs->axis = INPUT_AXIS_Y;
 | 
			
		||||
        } else if (evt->u.abs->axis == INPUT_AXIS_Y) {
 | 
			
		||||
            evt->u.abs->axis = INPUT_AXIS_X;
 | 
			
		||||
            evt->u.abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->u.abs->value;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 180:
 | 
			
		||||
        evt->abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->value;
 | 
			
		||||
        evt->u.abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->u.abs->value;
 | 
			
		||||
        break;
 | 
			
		||||
    case 270:
 | 
			
		||||
        if (evt->abs->axis == INPUT_AXIS_X) {
 | 
			
		||||
            evt->abs->axis = INPUT_AXIS_Y;
 | 
			
		||||
            evt->abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->value;
 | 
			
		||||
        } else if (evt->abs->axis == INPUT_AXIS_Y) {
 | 
			
		||||
            evt->abs->axis = INPUT_AXIS_X;
 | 
			
		||||
        if (evt->u.abs->axis == INPUT_AXIS_X) {
 | 
			
		||||
            evt->u.abs->axis = INPUT_AXIS_Y;
 | 
			
		||||
            evt->u.abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->u.abs->value;
 | 
			
		||||
        } else if (evt->u.abs->axis == INPUT_AXIS_Y) {
 | 
			
		||||
            evt->u.abs->axis = INPUT_AXIS_X;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
@ -197,18 +197,18 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)
 | 
			
		||||
    if (src) {
 | 
			
		||||
        idx = qemu_console_get_index(src);
 | 
			
		||||
    }
 | 
			
		||||
    switch (evt->kind) {
 | 
			
		||||
    switch (evt->type) {
 | 
			
		||||
    case INPUT_EVENT_KIND_KEY:
 | 
			
		||||
        switch (evt->key->key->kind) {
 | 
			
		||||
        switch (evt->u.key->key->type) {
 | 
			
		||||
        case KEY_VALUE_KIND_NUMBER:
 | 
			
		||||
            qcode = qemu_input_key_number_to_qcode(evt->key->key->number);
 | 
			
		||||
            qcode = qemu_input_key_number_to_qcode(evt->u.key->key->u.number);
 | 
			
		||||
            name = QKeyCode_lookup[qcode];
 | 
			
		||||
            trace_input_event_key_number(idx, evt->key->key->number,
 | 
			
		||||
                                         name, evt->key->down);
 | 
			
		||||
            trace_input_event_key_number(idx, evt->u.key->key->u.number,
 | 
			
		||||
                                         name, evt->u.key->down);
 | 
			
		||||
            break;
 | 
			
		||||
        case KEY_VALUE_KIND_QCODE:
 | 
			
		||||
            name = QKeyCode_lookup[evt->key->key->qcode];
 | 
			
		||||
            trace_input_event_key_qcode(idx, name, evt->key->down);
 | 
			
		||||
            name = QKeyCode_lookup[evt->u.key->key->u.qcode];
 | 
			
		||||
            trace_input_event_key_qcode(idx, name, evt->u.key->down);
 | 
			
		||||
            break;
 | 
			
		||||
        case KEY_VALUE_KIND_MAX:
 | 
			
		||||
            /* keep gcc happy */
 | 
			
		||||
@ -216,16 +216,16 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case INPUT_EVENT_KIND_BTN:
 | 
			
		||||
        name = InputButton_lookup[evt->btn->button];
 | 
			
		||||
        trace_input_event_btn(idx, name, evt->btn->down);
 | 
			
		||||
        name = InputButton_lookup[evt->u.btn->button];
 | 
			
		||||
        trace_input_event_btn(idx, name, evt->u.btn->down);
 | 
			
		||||
        break;
 | 
			
		||||
    case INPUT_EVENT_KIND_REL:
 | 
			
		||||
        name = InputAxis_lookup[evt->rel->axis];
 | 
			
		||||
        trace_input_event_rel(idx, name, evt->rel->value);
 | 
			
		||||
        name = InputAxis_lookup[evt->u.rel->axis];
 | 
			
		||||
        trace_input_event_rel(idx, name, evt->u.rel->value);
 | 
			
		||||
        break;
 | 
			
		||||
    case INPUT_EVENT_KIND_ABS:
 | 
			
		||||
        name = InputAxis_lookup[evt->abs->axis];
 | 
			
		||||
        trace_input_event_abs(idx, name, evt->abs->value);
 | 
			
		||||
        name = InputAxis_lookup[evt->u.abs->axis];
 | 
			
		||||
        trace_input_event_abs(idx, name, evt->u.abs->value);
 | 
			
		||||
        break;
 | 
			
		||||
    case INPUT_EVENT_KIND_MAX:
 | 
			
		||||
        /* keep gcc happy */
 | 
			
		||||
@ -311,12 +311,12 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
 | 
			
		||||
    qemu_input_event_trace(src, evt);
 | 
			
		||||
 | 
			
		||||
    /* pre processing */
 | 
			
		||||
    if (graphic_rotate && (evt->kind == INPUT_EVENT_KIND_ABS)) {
 | 
			
		||||
    if (graphic_rotate && (evt->type == INPUT_EVENT_KIND_ABS)) {
 | 
			
		||||
            qemu_input_transform_abs_rotate(evt);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* send event */
 | 
			
		||||
    s = qemu_input_find_handler(1 << evt->kind, src);
 | 
			
		||||
    s = qemu_input_find_handler(1 << evt->type, src);
 | 
			
		||||
    if (!s) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
@ -348,10 +348,10 @@ void qemu_input_event_sync(void)
 | 
			
		||||
InputEvent *qemu_input_event_new_key(KeyValue *key, bool down)
 | 
			
		||||
{
 | 
			
		||||
    InputEvent *evt = g_new0(InputEvent, 1);
 | 
			
		||||
    evt->key = g_new0(InputKeyEvent, 1);
 | 
			
		||||
    evt->kind = INPUT_EVENT_KIND_KEY;
 | 
			
		||||
    evt->key->key = key;
 | 
			
		||||
    evt->key->down = down;
 | 
			
		||||
    evt->u.key = g_new0(InputKeyEvent, 1);
 | 
			
		||||
    evt->type = INPUT_EVENT_KIND_KEY;
 | 
			
		||||
    evt->u.key->key = key;
 | 
			
		||||
    evt->u.key->down = down;
 | 
			
		||||
    return evt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -372,16 +372,16 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
 | 
			
		||||
void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down)
 | 
			
		||||
{
 | 
			
		||||
    KeyValue *key = g_new0(KeyValue, 1);
 | 
			
		||||
    key->kind = KEY_VALUE_KIND_NUMBER;
 | 
			
		||||
    key->number = num;
 | 
			
		||||
    key->type = KEY_VALUE_KIND_NUMBER;
 | 
			
		||||
    key->u.number = num;
 | 
			
		||||
    qemu_input_event_send_key(src, key, down);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down)
 | 
			
		||||
{
 | 
			
		||||
    KeyValue *key = g_new0(KeyValue, 1);
 | 
			
		||||
    key->kind = KEY_VALUE_KIND_QCODE;
 | 
			
		||||
    key->qcode = q;
 | 
			
		||||
    key->type = KEY_VALUE_KIND_QCODE;
 | 
			
		||||
    key->u.qcode = q;
 | 
			
		||||
    qemu_input_event_send_key(src, key, down);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -398,10 +398,10 @@ void qemu_input_event_send_key_delay(uint32_t delay_ms)
 | 
			
		||||
InputEvent *qemu_input_event_new_btn(InputButton btn, bool down)
 | 
			
		||||
{
 | 
			
		||||
    InputEvent *evt = g_new0(InputEvent, 1);
 | 
			
		||||
    evt->btn = g_new0(InputBtnEvent, 1);
 | 
			
		||||
    evt->kind = INPUT_EVENT_KIND_BTN;
 | 
			
		||||
    evt->btn->button = btn;
 | 
			
		||||
    evt->btn->down = down;
 | 
			
		||||
    evt->u.btn = g_new0(InputBtnEvent, 1);
 | 
			
		||||
    evt->type = INPUT_EVENT_KIND_BTN;
 | 
			
		||||
    evt->u.btn->button = btn;
 | 
			
		||||
    evt->u.btn->down = down;
 | 
			
		||||
    return evt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -451,8 +451,8 @@ InputEvent *qemu_input_event_new_move(InputEventKind kind,
 | 
			
		||||
    InputEvent *evt = g_new0(InputEvent, 1);
 | 
			
		||||
    InputMoveEvent *move = g_new0(InputMoveEvent, 1);
 | 
			
		||||
 | 
			
		||||
    evt->kind = kind;
 | 
			
		||||
    evt->data = move;
 | 
			
		||||
    evt->type = kind;
 | 
			
		||||
    evt->u.data = move;
 | 
			
		||||
    move->axis = axis;
 | 
			
		||||
    move->value = value;
 | 
			
		||||
    return evt;
 | 
			
		||||
 | 
			
		||||
@ -200,8 +200,6 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
 | 
			
		||||
{
 | 
			
		||||
    SpiceServerInfo *server = g_malloc0(sizeof(*server));
 | 
			
		||||
    SpiceChannel *client = g_malloc0(sizeof(*client));
 | 
			
		||||
    server->base = g_malloc0(sizeof(*server->base));
 | 
			
		||||
    client->base = g_malloc0(sizeof(*client->base));
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Spice server might have called us from spice worker thread
 | 
			
		||||
@ -218,9 +216,11 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
 | 
			
		||||
        add_addr_info(client->base, (struct sockaddr *)&info->paddr_ext,
 | 
			
		||||
        add_addr_info(qapi_SpiceChannel_base(client),
 | 
			
		||||
                      (struct sockaddr *)&info->paddr_ext,
 | 
			
		||||
                      info->plen_ext);
 | 
			
		||||
        add_addr_info(server->base, (struct sockaddr *)&info->laddr_ext,
 | 
			
		||||
        add_addr_info(qapi_SpiceServerInfo_base(server),
 | 
			
		||||
                      (struct sockaddr *)&info->laddr_ext,
 | 
			
		||||
                      info->llen_ext);
 | 
			
		||||
    } else {
 | 
			
		||||
        error_report("spice: %s, extended address is expected",
 | 
			
		||||
@ -229,7 +229,9 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
 | 
			
		||||
 | 
			
		||||
    switch (event) {
 | 
			
		||||
    case SPICE_CHANNEL_EVENT_CONNECTED:
 | 
			
		||||
        qapi_event_send_spice_connected(server->base, client->base, &error_abort);
 | 
			
		||||
        qapi_event_send_spice_connected(qapi_SpiceServerInfo_base(server),
 | 
			
		||||
                                        qapi_SpiceChannel_base(client),
 | 
			
		||||
                                        &error_abort);
 | 
			
		||||
        break;
 | 
			
		||||
    case SPICE_CHANNEL_EVENT_INITIALIZED:
 | 
			
		||||
        if (auth) {
 | 
			
		||||
@ -242,7 +244,9 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
 | 
			
		||||
        break;
 | 
			
		||||
    case SPICE_CHANNEL_EVENT_DISCONNECTED:
 | 
			
		||||
        channel_list_del(info);
 | 
			
		||||
        qapi_event_send_spice_disconnected(server->base, client->base, &error_abort);
 | 
			
		||||
        qapi_event_send_spice_disconnected(qapi_SpiceServerInfo_base(server),
 | 
			
		||||
                                           qapi_SpiceChannel_base(client),
 | 
			
		||||
                                           &error_abort);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
@ -378,16 +382,15 @@ static SpiceChannelList *qmp_query_spice_channels(void)
 | 
			
		||||
 | 
			
		||||
        chan = g_malloc0(sizeof(*chan));
 | 
			
		||||
        chan->value = g_malloc0(sizeof(*chan->value));
 | 
			
		||||
        chan->value->base = g_malloc0(sizeof(*chan->value->base));
 | 
			
		||||
 | 
			
		||||
        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->base->host = g_strdup(host);
 | 
			
		||||
        chan->value->base->port = g_strdup(port);
 | 
			
		||||
        chan->value->base->family = inet_netfamily(paddr->sa_family);
 | 
			
		||||
        chan->value->host = g_strdup(host);
 | 
			
		||||
        chan->value->port = g_strdup(port);
 | 
			
		||||
        chan->value->family = inet_netfamily(paddr->sa_family);
 | 
			
		||||
 | 
			
		||||
        chan->value->connection_id = item->info->connection_id;
 | 
			
		||||
        chan->value->channel_type = item->info->type;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										112
									
								
								ui/vnc.c
									
									
									
									
									
								
							
							
						
						
									
										112
									
								
								ui/vnc.c
									
									
									
									
									
								
							@ -156,10 +156,11 @@ char *vnc_socket_remote_addr(const char *format, int fd) {
 | 
			
		||||
    return addr_to_string(format, &sa, salen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VncBasicInfo *vnc_basic_info_get(struct sockaddr_storage *sa,
 | 
			
		||||
                                        socklen_t salen)
 | 
			
		||||
static void vnc_init_basic_info(struct sockaddr_storage *sa,
 | 
			
		||||
                                socklen_t salen,
 | 
			
		||||
                                VncBasicInfo *info,
 | 
			
		||||
                                Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    VncBasicInfo *info;
 | 
			
		||||
    char host[NI_MAXHOST];
 | 
			
		||||
    char serv[NI_MAXSERV];
 | 
			
		||||
    int err;
 | 
			
		||||
@ -168,42 +169,44 @@ static VncBasicInfo *vnc_basic_info_get(struct sockaddr_storage *sa,
 | 
			
		||||
                           host, sizeof(host),
 | 
			
		||||
                           serv, sizeof(serv),
 | 
			
		||||
                           NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
 | 
			
		||||
        VNC_DEBUG("Cannot resolve address %d: %s\n",
 | 
			
		||||
                  err, gai_strerror(err));
 | 
			
		||||
        return NULL;
 | 
			
		||||
        error_setg(errp, "Cannot resolve address: %s",
 | 
			
		||||
                   gai_strerror(err));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    info = g_malloc0(sizeof(VncBasicInfo));
 | 
			
		||||
    info->host = g_strdup(host);
 | 
			
		||||
    info->service = g_strdup(serv);
 | 
			
		||||
    info->family = inet_netfamily(sa->ss_family);
 | 
			
		||||
    return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VncBasicInfo *vnc_basic_info_get_from_server_addr(int fd)
 | 
			
		||||
static void vnc_init_basic_info_from_server_addr(int fd, VncBasicInfo *info,
 | 
			
		||||
                                                 Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    struct sockaddr_storage sa;
 | 
			
		||||
    socklen_t salen;
 | 
			
		||||
 | 
			
		||||
    salen = sizeof(sa);
 | 
			
		||||
    if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) {
 | 
			
		||||
        return NULL;
 | 
			
		||||
        error_setg_errno(errp, errno, "getsockname failed");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return vnc_basic_info_get(&sa, salen);
 | 
			
		||||
    vnc_init_basic_info(&sa, salen, info, errp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VncBasicInfo *vnc_basic_info_get_from_remote_addr(int fd)
 | 
			
		||||
static void vnc_init_basic_info_from_remote_addr(int fd, VncBasicInfo *info,
 | 
			
		||||
                                                 Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    struct sockaddr_storage sa;
 | 
			
		||||
    socklen_t salen;
 | 
			
		||||
 | 
			
		||||
    salen = sizeof(sa);
 | 
			
		||||
    if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) {
 | 
			
		||||
        return NULL;
 | 
			
		||||
        error_setg_errno(errp, errno, "getpeername failed");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return vnc_basic_info_get(&sa, salen);
 | 
			
		||||
    vnc_init_basic_info(&sa, salen, info, errp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *vnc_auth_name(VncDisplay *vd) {
 | 
			
		||||
@ -256,15 +259,18 @@ static const char *vnc_auth_name(VncDisplay *vd) {
 | 
			
		||||
static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
 | 
			
		||||
{
 | 
			
		||||
    VncServerInfo *info;
 | 
			
		||||
    VncBasicInfo *bi = vnc_basic_info_get_from_server_addr(vd->lsock);
 | 
			
		||||
    if (!bi) {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
 | 
			
		||||
    info = g_malloc(sizeof(*info));
 | 
			
		||||
    info->base = bi;
 | 
			
		||||
    vnc_init_basic_info_from_server_addr(vd->lsock,
 | 
			
		||||
                                         qapi_VncServerInfo_base(info), &err);
 | 
			
		||||
    info->has_auth = true;
 | 
			
		||||
    info->auth = g_strdup(vnc_auth_name(vd));
 | 
			
		||||
    if (err) {
 | 
			
		||||
        qapi_free_VncServerInfo(info);
 | 
			
		||||
        info = NULL;
 | 
			
		||||
        error_free(err);
 | 
			
		||||
    }
 | 
			
		||||
    return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -291,11 +297,16 @@ static void vnc_client_cache_auth(VncState *client)
 | 
			
		||||
 | 
			
		||||
static void vnc_client_cache_addr(VncState *client)
 | 
			
		||||
{
 | 
			
		||||
    VncBasicInfo *bi = vnc_basic_info_get_from_remote_addr(client->csock);
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
 | 
			
		||||
    if (bi) {
 | 
			
		||||
    client->info = g_malloc0(sizeof(*client->info));
 | 
			
		||||
        client->info->base = bi;
 | 
			
		||||
    vnc_init_basic_info_from_remote_addr(client->csock,
 | 
			
		||||
                                         qapi_VncClientInfo_base(client->info),
 | 
			
		||||
                                         &err);
 | 
			
		||||
    if (err) {
 | 
			
		||||
        qapi_free_VncClientInfo(client->info);
 | 
			
		||||
        client->info = NULL;
 | 
			
		||||
        error_free(err);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -306,7 +317,6 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
 | 
			
		||||
    if (!vs->info) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    g_assert(vs->info->base);
 | 
			
		||||
 | 
			
		||||
    si = vnc_server_info_get(vs->vd);
 | 
			
		||||
    if (!si) {
 | 
			
		||||
@ -315,7 +325,8 @@ static void vnc_qmp_event(VncState *vs, QAPIEvent event)
 | 
			
		||||
 | 
			
		||||
    switch (event) {
 | 
			
		||||
    case QAPI_EVENT_VNC_CONNECTED:
 | 
			
		||||
        qapi_event_send_vnc_connected(si, vs->info->base, &error_abort);
 | 
			
		||||
        qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
 | 
			
		||||
                                      &error_abort);
 | 
			
		||||
        break;
 | 
			
		||||
    case QAPI_EVENT_VNC_INITIALIZED:
 | 
			
		||||
        qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
 | 
			
		||||
@ -350,11 +361,10 @@ static VncClientInfo *qmp_query_vnc_client(const VncState *client)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    info = g_malloc0(sizeof(*info));
 | 
			
		||||
    info->base = g_malloc0(sizeof(*info->base));
 | 
			
		||||
    info->base->host = g_strdup(host);
 | 
			
		||||
    info->base->service = g_strdup(serv);
 | 
			
		||||
    info->base->family = inet_netfamily(sa.ss_family);
 | 
			
		||||
    info->base->websocket = client->websocket;
 | 
			
		||||
    info->host = g_strdup(host);
 | 
			
		||||
    info->service = g_strdup(serv);
 | 
			
		||||
    info->family = inet_netfamily(sa.ss_family);
 | 
			
		||||
    info->websocket = client->websocket;
 | 
			
		||||
 | 
			
		||||
    if (client->tls) {
 | 
			
		||||
        info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
 | 
			
		||||
@ -3514,9 +3524,9 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (strncmp(vnc, "unix:", 5) == 0) {
 | 
			
		||||
            saddr->kind = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
            saddr->q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
            saddr->q_unix->path = g_strdup(vnc + 5);
 | 
			
		||||
            saddr->type = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
            saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
            saddr->u.q_unix->path = g_strdup(vnc + 5);
 | 
			
		||||
 | 
			
		||||
            if (vs->ws_enabled) {
 | 
			
		||||
                error_setg(errp, "UNIX sockets not supported with websock");
 | 
			
		||||
@ -3524,12 +3534,12 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            unsigned long long baseport;
 | 
			
		||||
            saddr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
            saddr->inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
            saddr->type = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
            saddr->u.inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
            if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
 | 
			
		||||
                saddr->inet->host = g_strndup(vnc + 1, hlen - 2);
 | 
			
		||||
                saddr->u.inet->host = g_strndup(vnc + 1, hlen - 2);
 | 
			
		||||
            } else {
 | 
			
		||||
                saddr->inet->host = g_strndup(vnc, hlen);
 | 
			
		||||
                saddr->u.inet->host = g_strndup(vnc, hlen);
 | 
			
		||||
            }
 | 
			
		||||
            if (parse_uint_full(h + 1, &baseport, 10) < 0) {
 | 
			
		||||
                error_setg(errp, "can't convert to a number: %s", h + 1);
 | 
			
		||||
@ -3540,28 +3550,28 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		||||
                error_setg(errp, "port %s out of range", h + 1);
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
            saddr->inet->port = g_strdup_printf(
 | 
			
		||||
            saddr->u.inet->port = g_strdup_printf(
 | 
			
		||||
                "%d", (int)baseport + 5900);
 | 
			
		||||
 | 
			
		||||
            if (to) {
 | 
			
		||||
                saddr->inet->has_to = true;
 | 
			
		||||
                saddr->inet->to = to;
 | 
			
		||||
                saddr->u.inet->has_to = true;
 | 
			
		||||
                saddr->u.inet->to = to;
 | 
			
		||||
            }
 | 
			
		||||
            saddr->inet->ipv4 = saddr->inet->has_ipv4 = has_ipv4;
 | 
			
		||||
            saddr->inet->ipv6 = saddr->inet->has_ipv6 = has_ipv6;
 | 
			
		||||
            saddr->u.inet->ipv4 = saddr->u.inet->has_ipv4 = has_ipv4;
 | 
			
		||||
            saddr->u.inet->ipv6 = saddr->u.inet->has_ipv6 = has_ipv6;
 | 
			
		||||
 | 
			
		||||
            if (vs->ws_enabled) {
 | 
			
		||||
                wsaddr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
                wsaddr->inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
                wsaddr->inet->host = g_strdup(saddr->inet->host);
 | 
			
		||||
                wsaddr->inet->port = g_strdup(websocket);
 | 
			
		||||
                wsaddr->type = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
                wsaddr->u.inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
                wsaddr->u.inet->host = g_strdup(saddr->u.inet->host);
 | 
			
		||||
                wsaddr->u.inet->port = g_strdup(websocket);
 | 
			
		||||
 | 
			
		||||
                if (to) {
 | 
			
		||||
                    wsaddr->inet->has_to = true;
 | 
			
		||||
                    wsaddr->inet->to = to;
 | 
			
		||||
                    wsaddr->u.inet->has_to = true;
 | 
			
		||||
                    wsaddr->u.inet->to = to;
 | 
			
		||||
                }
 | 
			
		||||
                wsaddr->inet->ipv4 = wsaddr->inet->has_ipv4 = has_ipv4;
 | 
			
		||||
                wsaddr->inet->ipv6 = wsaddr->inet->has_ipv6 = has_ipv6;
 | 
			
		||||
                wsaddr->u.inet->ipv4 = wsaddr->u.inet->has_ipv4 = has_ipv4;
 | 
			
		||||
                wsaddr->u.inet->ipv6 = wsaddr->u.inet->has_ipv6 = has_ipv6;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
@ -3760,7 +3770,7 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		||||
        if (csock < 0) {
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
        vs->is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        vnc_connect(vs, csock, false, false);
 | 
			
		||||
    } else {
 | 
			
		||||
        /* listen for connects */
 | 
			
		||||
@ -3768,7 +3778,7 @@ void vnc_display_open(const char *id, Error **errp)
 | 
			
		||||
        if (vs->lsock < 0) {
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
        vs->is_unix = saddr->kind == SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
        if (vs->ws_enabled) {
 | 
			
		||||
            vs->lwebsock = socket_listen(wsaddr, errp);
 | 
			
		||||
            if (vs->lwebsock < 0) {
 | 
			
		||||
 | 
			
		||||
@ -918,23 +918,23 @@ SocketAddress *socket_parse(const char *str, Error **errp)
 | 
			
		||||
            error_setg(errp, "invalid Unix socket address");
 | 
			
		||||
            goto fail;
 | 
			
		||||
        } else {
 | 
			
		||||
            addr->kind = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
            addr->q_unix = g_new(UnixSocketAddress, 1);
 | 
			
		||||
            addr->q_unix->path = g_strdup(str + 5);
 | 
			
		||||
            addr->type = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
            addr->u.q_unix = g_new(UnixSocketAddress, 1);
 | 
			
		||||
            addr->u.q_unix->path = g_strdup(str + 5);
 | 
			
		||||
        }
 | 
			
		||||
    } else if (strstart(str, "fd:", NULL)) {
 | 
			
		||||
        if (str[3] == '\0') {
 | 
			
		||||
            error_setg(errp, "invalid file descriptor address");
 | 
			
		||||
            goto fail;
 | 
			
		||||
        } else {
 | 
			
		||||
            addr->kind = SOCKET_ADDRESS_KIND_FD;
 | 
			
		||||
            addr->fd = g_new(String, 1);
 | 
			
		||||
            addr->fd->str = g_strdup(str + 3);
 | 
			
		||||
            addr->type = SOCKET_ADDRESS_KIND_FD;
 | 
			
		||||
            addr->u.fd = g_new(String, 1);
 | 
			
		||||
            addr->u.fd->str = g_strdup(str + 3);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        addr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
        addr->inet = inet_parse(str, errp);
 | 
			
		||||
        if (addr->inet == NULL) {
 | 
			
		||||
        addr->type = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
        addr->u.inet = inet_parse(str, errp);
 | 
			
		||||
        if (addr->u.inet == NULL) {
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -952,19 +952,19 @@ int socket_connect(SocketAddress *addr, Error **errp,
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
 | 
			
		||||
    switch (addr->kind) {
 | 
			
		||||
    switch (addr->type) {
 | 
			
		||||
    case SOCKET_ADDRESS_KIND_INET:
 | 
			
		||||
        inet_addr_to_opts(opts, addr->inet);
 | 
			
		||||
        inet_addr_to_opts(opts, addr->u.inet);
 | 
			
		||||
        fd = inet_connect_opts(opts, errp, callback, opaque);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case SOCKET_ADDRESS_KIND_UNIX:
 | 
			
		||||
        qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort);
 | 
			
		||||
        qemu_opt_set(opts, "path", addr->u.q_unix->path, &error_abort);
 | 
			
		||||
        fd = unix_connect_opts(opts, errp, callback, opaque);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case SOCKET_ADDRESS_KIND_FD:
 | 
			
		||||
        fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
 | 
			
		||||
        fd = monitor_get_fd(cur_mon, addr->u.fd->str, errp);
 | 
			
		||||
        if (fd >= 0 && callback) {
 | 
			
		||||
            qemu_set_nonblock(fd);
 | 
			
		||||
            callback(fd, NULL, opaque);
 | 
			
		||||
@ -984,19 +984,19 @@ int socket_listen(SocketAddress *addr, Error **errp)
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
 | 
			
		||||
    switch (addr->kind) {
 | 
			
		||||
    switch (addr->type) {
 | 
			
		||||
    case SOCKET_ADDRESS_KIND_INET:
 | 
			
		||||
        inet_addr_to_opts(opts, addr->inet);
 | 
			
		||||
        inet_addr_to_opts(opts, addr->u.inet);
 | 
			
		||||
        fd = inet_listen_opts(opts, 0, errp);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case SOCKET_ADDRESS_KIND_UNIX:
 | 
			
		||||
        qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort);
 | 
			
		||||
        qemu_opt_set(opts, "path", addr->u.q_unix->path, &error_abort);
 | 
			
		||||
        fd = unix_listen_opts(opts, errp);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case SOCKET_ADDRESS_KIND_FD:
 | 
			
		||||
        fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
 | 
			
		||||
        fd = monitor_get_fd(cur_mon, addr->u.fd->str, errp);
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
@ -1012,12 +1012,12 @@ int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    opts = qemu_opts_create(&socket_optslist, NULL, 0, &error_abort);
 | 
			
		||||
    switch (remote->kind) {
 | 
			
		||||
    switch (remote->type) {
 | 
			
		||||
    case SOCKET_ADDRESS_KIND_INET:
 | 
			
		||||
        inet_addr_to_opts(opts, remote->inet);
 | 
			
		||||
        inet_addr_to_opts(opts, remote->u.inet);
 | 
			
		||||
        if (local) {
 | 
			
		||||
            qemu_opt_set(opts, "localaddr", local->inet->host, &error_abort);
 | 
			
		||||
            qemu_opt_set(opts, "localport", local->inet->port, &error_abort);
 | 
			
		||||
            qemu_opt_set(opts, "localaddr", local->u.inet->host, &error_abort);
 | 
			
		||||
            qemu_opt_set(opts, "localport", local->u.inet->port, &error_abort);
 | 
			
		||||
        }
 | 
			
		||||
        fd = inet_dgram_opts(opts, errp);
 | 
			
		||||
        break;
 | 
			
		||||
@ -1052,14 +1052,14 @@ socket_sockaddr_to_address_inet(struct sockaddr_storage *sa,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addr = g_new0(SocketAddress, 1);
 | 
			
		||||
    addr->kind = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
    addr->inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
    addr->inet->host = g_strdup(host);
 | 
			
		||||
    addr->inet->port = g_strdup(serv);
 | 
			
		||||
    addr->type = SOCKET_ADDRESS_KIND_INET;
 | 
			
		||||
    addr->u.inet = g_new0(InetSocketAddress, 1);
 | 
			
		||||
    addr->u.inet->host = g_strdup(host);
 | 
			
		||||
    addr->u.inet->port = g_strdup(serv);
 | 
			
		||||
    if (sa->ss_family == AF_INET) {
 | 
			
		||||
        addr->inet->has_ipv4 = addr->inet->ipv4 = true;
 | 
			
		||||
        addr->u.inet->has_ipv4 = addr->u.inet->ipv4 = true;
 | 
			
		||||
    } else {
 | 
			
		||||
        addr->inet->has_ipv6 = addr->inet->ipv6 = true;
 | 
			
		||||
        addr->u.inet->has_ipv6 = addr->u.inet->ipv6 = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return addr;
 | 
			
		||||
@ -1076,10 +1076,10 @@ socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
 | 
			
		||||
    struct sockaddr_un *su = (struct sockaddr_un *)sa;
 | 
			
		||||
 | 
			
		||||
    addr = g_new0(SocketAddress, 1);
 | 
			
		||||
    addr->kind = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
    addr->q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
    addr->type = SOCKET_ADDRESS_KIND_UNIX;
 | 
			
		||||
    addr->u.q_unix = g_new0(UnixSocketAddress, 1);
 | 
			
		||||
    if (su->sun_path[0]) {
 | 
			
		||||
        addr->q_unix->path = g_strndup(su->sun_path,
 | 
			
		||||
        addr->u.q_unix->path = g_strndup(su->sun_path,
 | 
			
		||||
                                         sizeof(su->sun_path));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user