Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2016-03-04' into staging
QAPI patches for 2016-03-04 # gpg: Signature made Sat 05 Mar 2016 09:47:19 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-2016-03-04: qapi: Drop useless 'data' member of unions chardev: Drop useless ChardevDummy type qapi: Avoid use of 'data' member of QAPI unions ui: Shorten references into InputEvent util: Shorten references into SocketAddress chardev: Shorten references into ChardevBackend qapi: Update docs to match recent generator changes qapi-visit: Expose visit_type_FOO_members() qapi: Rename 'fields' to 'members' in generated C code qapi: Rename 'fields' to 'members' in generator qapi-dealloc: Reduce use outside of generated code qmp-shell: fix pretty printing of JSON responses Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		| @@ -567,7 +567,7 @@ static CharDriverState *chr_baum_init(const char *id, | ||||
|                                       ChardevReturn *ret, | ||||
|                                       Error **errp) | ||||
| { | ||||
|     ChardevCommon *common = qapi_ChardevDummy_base(backend->u.braille); | ||||
|     ChardevCommon *common = backend->u.braille; | ||||
|     BaumDriverState *baum; | ||||
|     CharDriverState *chr; | ||||
|     brlapi_handle_t *handle; | ||||
|   | ||||
| @@ -68,7 +68,7 @@ static CharDriverState *qemu_chr_open_msmouse(const char *id, | ||||
|                                               ChardevReturn *ret, | ||||
|                                               Error **errp) | ||||
| { | ||||
|     ChardevCommon *common = qapi_ChardevDummy_base(backend->u.msmouse); | ||||
|     ChardevCommon *common = backend->u.msmouse; | ||||
|     CharDriverState *chr; | ||||
|  | ||||
|     chr = qemu_chr_alloc(common, errp); | ||||
|   | ||||
							
								
								
									
										14
									
								
								block/nbd.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								block/nbd.c
									
									
									
									
									
								
							| @@ -204,18 +204,20 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, char **export, | ||||
|     saddr = g_new0(SocketAddress, 1); | ||||
|  | ||||
|     if (qdict_haskey(options, "path")) { | ||||
|         UnixSocketAddress *q_unix; | ||||
|         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")); | ||||
|         q_unix = saddr->u.q_unix = g_new0(UnixSocketAddress, 1); | ||||
|         q_unix->path = g_strdup(qdict_get_str(options, "path")); | ||||
|         qdict_del(options, "path"); | ||||
|     } else { | ||||
|         InetSocketAddress *inet; | ||||
|         saddr->type = SOCKET_ADDRESS_KIND_INET; | ||||
|         saddr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|         saddr->u.inet->host = g_strdup(qdict_get_str(options, "host")); | ||||
|         inet = saddr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|         inet->host = g_strdup(qdict_get_str(options, "host")); | ||||
|         if (!qdict_get_try_str(options, "port")) { | ||||
|             saddr->u.inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT); | ||||
|             inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT); | ||||
|         } else { | ||||
|             saddr->u.inet->port = g_strdup(qdict_get_str(options, "port")); | ||||
|             inet->port = g_strdup(qdict_get_str(options, "port")); | ||||
|         } | ||||
|         qdict_del(options, "host"); | ||||
|         qdict_del(options, "port"); | ||||
|   | ||||
							
								
								
									
										31
									
								
								blockdev.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								blockdev.c
									
									
									
									
									
								
							| @@ -1202,15 +1202,11 @@ void hmp_commit(Monitor *mon, const QDict *qdict) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void blockdev_do_action(TransactionActionKind type, void *data, | ||||
|                                Error **errp) | ||||
| static void blockdev_do_action(TransactionAction *action, Error **errp) | ||||
| { | ||||
|     TransactionAction action; | ||||
|     TransactionActionList list; | ||||
|  | ||||
|     action.type = type; | ||||
|     action.u.data = data; | ||||
|     list.value = &action; | ||||
|     list.value = action; | ||||
|     list.next = NULL; | ||||
|     qmp_transaction(&list, false, NULL, errp); | ||||
| } | ||||
| @@ -1236,8 +1232,11 @@ void qmp_blockdev_snapshot_sync(bool has_device, const char *device, | ||||
|         .has_mode = has_mode, | ||||
|         .mode = mode, | ||||
|     }; | ||||
|     blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC, | ||||
|                        &snapshot, errp); | ||||
|     TransactionAction action = { | ||||
|         .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC, | ||||
|         .u.blockdev_snapshot_sync = &snapshot, | ||||
|     }; | ||||
|     blockdev_do_action(&action, errp); | ||||
| } | ||||
|  | ||||
| void qmp_blockdev_snapshot(const char *node, const char *overlay, | ||||
| @@ -1247,9 +1246,11 @@ void qmp_blockdev_snapshot(const char *node, const char *overlay, | ||||
|         .node = (char *) node, | ||||
|         .overlay = (char *) overlay | ||||
|     }; | ||||
|  | ||||
|     blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT, | ||||
|                        &snapshot_data, errp); | ||||
|     TransactionAction action = { | ||||
|         .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT, | ||||
|         .u.blockdev_snapshot = &snapshot_data, | ||||
|     }; | ||||
|     blockdev_do_action(&action, errp); | ||||
| } | ||||
|  | ||||
| void qmp_blockdev_snapshot_internal_sync(const char *device, | ||||
| @@ -1260,9 +1261,11 @@ void qmp_blockdev_snapshot_internal_sync(const char *device, | ||||
|         .device = (char *) device, | ||||
|         .name = (char *) name | ||||
|     }; | ||||
|  | ||||
|     blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC, | ||||
|                        &snapshot, errp); | ||||
|     TransactionAction action = { | ||||
|         .type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC, | ||||
|         .u.blockdev_snapshot_internal_sync = &snapshot, | ||||
|     }; | ||||
|     blockdev_do_action(&action, errp); | ||||
| } | ||||
|  | ||||
| SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device, | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| = How to use the QAPI code generator = | ||||
|  | ||||
| Copyright IBM Corp. 2011 | ||||
| Copyright (C) 2012-2015 Red Hat, Inc. | ||||
| Copyright (C) 2012-2016 Red Hat, Inc. | ||||
|  | ||||
| This work is licensed under the terms of the GNU GPL, version 2 or | ||||
| later. See the COPYING file in the top-level directory. | ||||
| @@ -52,7 +52,7 @@ schema.  The documentation is delimited between two lines of ##, then | ||||
| the first line names the expression, an optional overview is provided, | ||||
| then individual documentation about each member of 'data' is provided, | ||||
| and finally, a 'Since: x.y.z' tag lists the release that introduced | ||||
| the expression.  Optional fields are tagged with the phrase | ||||
| the expression.  Optional members are tagged with the phrase | ||||
| '#optional', often with their default value; and extensions added | ||||
| after the expression was first released are also given a '(since | ||||
| x.y.z)' comment.  For example: | ||||
| @@ -108,15 +108,15 @@ 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, 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 | ||||
| and member 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.  Field | ||||
| names should be ALL_CAPS with words separated by underscore.  Member | ||||
| names cannot start with 'has-' or 'has_', as this is reserved for | ||||
| tracking optional fields. | ||||
| tracking optional members. | ||||
|  | ||||
| Any name (command, event, type, field, or enum value) beginning with | ||||
| Any name (command, event, type, member, or enum value) beginning with | ||||
| "x-" is marked experimental, and may be withdrawn or changed | ||||
| incompatibly in a future release.  All names must begin with a letter, | ||||
| and contain only ASCII letters, digits, dash, and underscore.  There | ||||
| @@ -127,7 +127,7 @@ the vendor), even if the rest of the name uses dash (example: | ||||
| __com.redhat_drive-mirror).  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 | ||||
| example, a member named "default" in qapi becomes "q_default" in the | ||||
| generated C code. | ||||
|  | ||||
| In the rest of this document, usage lines are given for each | ||||
| @@ -217,17 +217,18 @@ and must continue to work). | ||||
|  | ||||
| On output structures (only mentioned in the 'returns' side of a command), | ||||
| changing from mandatory to optional is in general unsafe (older clients may be | ||||
| expecting the field, and could crash if it is missing), although it can be done | ||||
| if the only way that the optional argument will be omitted is when it is | ||||
| triggered by the presence of a new input flag to the command that older clients | ||||
| don't know to send.  Changing from optional to mandatory is safe. | ||||
| expecting the member, and could crash if it is missing), although it | ||||
| can be done if the only way that the optional argument will be omitted | ||||
| is when it is triggered by the presence of a new input flag to the | ||||
| command that older clients don't know to send.  Changing from optional | ||||
| to mandatory is safe. | ||||
|  | ||||
| A structure that is used in both input and output of various commands | ||||
| must consider the backwards compatibility constraints of both directions | ||||
| of use. | ||||
|  | ||||
| A struct definition can specify another struct as its base. | ||||
| In this case, the fields of the base type are included as top-level fields | ||||
| In this case, the members of the base type are included as top-level members | ||||
| of the new struct's dictionary in the Client JSON Protocol wire | ||||
| format. An example definition is: | ||||
|  | ||||
| @@ -237,7 +238,7 @@ format. An example definition is: | ||||
|    'data': { '*backing': 'str' } } | ||||
|  | ||||
| An example BlockdevOptionsGenericCOWFormat object on the wire could use | ||||
| both fields like this: | ||||
| both members like this: | ||||
|  | ||||
|  { "file": "/some/place/my-image", | ||||
|    "backing": "/some/place/my-backing-file" } | ||||
| @@ -262,7 +263,7 @@ The enum constants will be named by using a heuristic to turn the | ||||
| type name into a set of underscore separated words. For the example | ||||
| above, 'MyEnum' will turn into 'MY_ENUM' giving a constant name | ||||
| of 'MY_ENUM_VALUE1' for the first value. If the default heuristic | ||||
| does not result in a desirable name, the optional 'prefix' field | ||||
| does not result in a desirable name, the optional 'prefix' member | ||||
| can be used when defining the enum. | ||||
|  | ||||
| The enumeration values are passed as strings over the Client JSON | ||||
| @@ -275,9 +276,9 @@ converting between strings and enum values.  Since the wire format | ||||
| always passes by name, it is acceptable to reorder or add new | ||||
| enumeration members in any location without breaking clients of Client | ||||
| JSON Protocol; however, removing enum values would break | ||||
| compatibility.  For any struct that has a field that will only contain | ||||
| a finite set of string values, using an enum type for that field is | ||||
| better than open-coding the field to be type 'str'. | ||||
| compatibility.  For any struct that has a member that will only contain | ||||
| a finite set of string values, using an enum type for that member is | ||||
| better than open-coding the member to be type 'str'. | ||||
|  | ||||
|  | ||||
| === Union types === | ||||
| @@ -305,8 +306,8 @@ values to data types like in this example: | ||||
|              'qcow2': 'Qcow2Options' } } | ||||
|  | ||||
| In the Client JSON Protocol, a simple union is represented by a | ||||
| dictionary that contains the 'type' field as a discriminator, and a | ||||
| 'data' field that is of the specified data type corresponding to the | ||||
| dictionary that contains the 'type' member as a discriminator, and a | ||||
| 'data' member that is of the specified data type corresponding to the | ||||
| discriminator value, as in these examples: | ||||
|  | ||||
|  { "type": "file", "data" : { "filename": "/some/place/my-image" } } | ||||
| @@ -321,14 +322,14 @@ enum.  The value for each branch can be of any type. | ||||
|  | ||||
| A flat union definition specifies a struct as its base, and | ||||
| avoids nesting on the wire.  All branches of the union must be | ||||
| complex types, and the top-level fields of the union dictionary on | ||||
| the wire will be combination of fields from both the base type and the | ||||
| complex types, and the top-level members of the union dictionary on | ||||
| the wire will be combination of members from both the base type and the | ||||
| appropriate branch type (when merging two dictionaries, there must be | ||||
| no keys in common).  The 'discriminator' field must be the name of an | ||||
| no keys in common).  The 'discriminator' member must be the name of an | ||||
| enum-typed member of the base struct. | ||||
|  | ||||
| The following example enhances the above simple union example by | ||||
| adding a common field 'readonly', renaming the discriminator to | ||||
| adding a common member 'readonly', renaming the discriminator to | ||||
| something more applicable, and reducing the number of {} required on | ||||
| the wire: | ||||
|  | ||||
| @@ -353,8 +354,8 @@ the user, but because it must map to a base member with enum type, the | ||||
| code generator can ensure that branches exist for all values of the | ||||
| enum (although the order of the keys need not match the declaration of | ||||
| the enum).  In the resulting generated C data types, a flat union is | ||||
| represented as a struct with the base member fields included directly, | ||||
| and then a union of structures for each branch of the struct. | ||||
| represented as a struct with the base members included directly, and | ||||
| then a union of structures for each branch of the struct. | ||||
|  | ||||
| A simple union can always be re-written as a flat union where the base | ||||
| class has a single member named 'type', and where each branch of the | ||||
| @@ -424,10 +425,10 @@ string name of a complex type, or a dictionary that declares an | ||||
| anonymous type with the same semantics as a 'struct' expression, with | ||||
| one exception noted below when 'gen' is used. | ||||
|  | ||||
| The 'returns' member describes what will appear in the "return" field | ||||
| The 'returns' member describes what will appear in the "return" member | ||||
| of a Client JSON Protocol reply on successful completion of a command. | ||||
| The member is optional from the command declaration; if absent, the | ||||
| "return" field will be an empty dictionary.  If 'returns' is present, | ||||
| "return" member will be an empty dictionary.  If 'returns' is present, | ||||
| it must be the string name of a complex or built-in type, a | ||||
| one-element array containing the name of a complex or built-in type, | ||||
| with one exception noted below when 'gen' is used.  Although it is | ||||
| @@ -435,7 +436,7 @@ permitted to have the 'returns' member name a built-in type or an | ||||
| array of built-in types, any command that does this cannot be extended | ||||
| to return additional information in the future; thus, new commands | ||||
| should strongly consider returning a dictionary-based type or an array | ||||
| of dictionaries, even if the dictionary only contains one field at the | ||||
| of dictionaries, even if the dictionary only contains one member at the | ||||
| present. | ||||
|  | ||||
| All commands in Client JSON Protocol use a dictionary to report | ||||
| @@ -478,7 +479,7 @@ response is not possible (although the command will still return a | ||||
| normal dictionary error on failure).  When a successful reply is not | ||||
| possible, the command expression should include the optional key | ||||
| 'success-response' with boolean value false.  So far, only QGA makes | ||||
| use of this field. | ||||
| use of this member. | ||||
|  | ||||
|  | ||||
| === Events === | ||||
| @@ -656,7 +657,7 @@ Union types | ||||
|  | ||||
|     { "name": "BlockdevOptions", "meta-type": "object", | ||||
|       "members": [ | ||||
|           { "name": "kind", "type": "BlockdevOptionsKind" } ], | ||||
|           { "name": "type", "type": "BlockdevOptionsKind" } ], | ||||
|       "tag": "type", | ||||
|       "variants": [ | ||||
|           { "case": "file", "type": ":obj-FileOptions-wrapper" }, | ||||
| @@ -722,33 +723,38 @@ the names of built-in types.  Clients should examine member | ||||
|  | ||||
| == Code generation == | ||||
|  | ||||
| Schemas are fed into four scripts to generate all the code/files that, | ||||
| Schemas are fed into five scripts to generate all the code/files that, | ||||
| paired with the core QAPI libraries, comprise everything required to | ||||
| take JSON commands read in by a Client JSON Protocol server, unmarshal | ||||
| the arguments into the underlying C types, call into the corresponding | ||||
| C function, and map the response back to a Client JSON Protocol | ||||
| response to be returned to the user. | ||||
| C function, map the response back to a Client JSON Protocol response | ||||
| to be returned to the user, and introspect the commands. | ||||
|  | ||||
| As an example, we'll use the following schema, which describes a single | ||||
| complex user-defined type (which will produce a C struct, along with a list | ||||
| node structure that can be used to chain together a list of such types in | ||||
| case we want to accept/return a list of this type with a command), and a | ||||
| command which takes that type as a parameter and returns the same type: | ||||
| As an example, we'll use the following schema, which describes a | ||||
| single complex user-defined type, along with command which takes a | ||||
| list of that type as a parameter, and returns a single element of that | ||||
| type.  The user is responsible for writing the implementation of | ||||
| qmp_my_command(); everything else is produced by the generator. | ||||
|  | ||||
|     $ cat example-schema.json | ||||
|     { 'struct': 'UserDefOne', | ||||
|       'data': { 'integer': 'int', 'string': 'str' } } | ||||
|       'data': { 'integer': 'int', '*string': 'str' } } | ||||
|  | ||||
|     { 'command': 'my-command', | ||||
|       'data':    {'arg1': 'UserDefOne'}, | ||||
|       'data': { 'arg1': ['UserDefOne'] }, | ||||
|       'returns': 'UserDefOne' } | ||||
|  | ||||
|     { 'event': 'MY_EVENT' } | ||||
|  | ||||
| For a more thorough look at generated code, the testsuite includes | ||||
| tests/qapi-schema/qapi-schema-tests.json that covers more examples of | ||||
| what the generator will accept, and compiles the resulting C code as | ||||
| part of 'make check-unit'. | ||||
|  | ||||
| === scripts/qapi-types.py === | ||||
|  | ||||
| Used to generate the C types defined by a schema. The following files are | ||||
| created: | ||||
| Used to generate the C types defined by a schema, along with | ||||
| supporting code. The following files are created: | ||||
|  | ||||
| $(prefix)qapi-types.h - C types corresponding to types defined in | ||||
|                         the schema you pass in | ||||
| @@ -763,38 +769,6 @@ Example: | ||||
|  | ||||
|     $ python scripts/qapi-types.py --output-dir="qapi-generated" \ | ||||
|     --prefix="example-" example-schema.json | ||||
|     $ cat qapi-generated/example-qapi-types.c | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     void qapi_free_UserDefOne(UserDefOne *obj) | ||||
|     { | ||||
|         QapiDeallocVisitor *qdv; | ||||
|         Visitor *v; | ||||
|  | ||||
|         if (!obj) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         qdv = qapi_dealloc_visitor_new(); | ||||
|         v = qapi_dealloc_get_visitor(qdv); | ||||
|         visit_type_UserDefOne(v, &obj, NULL, NULL); | ||||
|         qapi_dealloc_visitor_cleanup(qdv); | ||||
|     } | ||||
|  | ||||
|     void qapi_free_UserDefOneList(UserDefOneList *obj) | ||||
|     { | ||||
|         QapiDeallocVisitor *qdv; | ||||
|         Visitor *v; | ||||
|  | ||||
|         if (!obj) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         qdv = qapi_dealloc_visitor_new(); | ||||
|         v = qapi_dealloc_get_visitor(qdv); | ||||
|         visit_type_UserDefOneList(v, &obj, NULL, NULL); | ||||
|         qapi_dealloc_visitor_cleanup(qdv); | ||||
|     } | ||||
|     $ cat qapi-generated/example-qapi-types.h | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
| @@ -809,29 +783,59 @@ Example: | ||||
|  | ||||
|     struct UserDefOne { | ||||
|         int64_t integer; | ||||
|         bool has_string; | ||||
|         char *string; | ||||
|     }; | ||||
|  | ||||
|     void qapi_free_UserDefOne(UserDefOne *obj); | ||||
|  | ||||
|     struct UserDefOneList { | ||||
|         union { | ||||
|             UserDefOne *value; | ||||
|             uint64_t padding; | ||||
|         }; | ||||
|         UserDefOneList *next; | ||||
|         UserDefOne *value; | ||||
|     }; | ||||
|  | ||||
|     void qapi_free_UserDefOneList(UserDefOneList *obj); | ||||
|  | ||||
|     #endif | ||||
|     $ cat qapi-generated/example-qapi-types.c | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     void qapi_free_UserDefOne(UserDefOne *obj) | ||||
|     { | ||||
|         QapiDeallocVisitor *qdv; | ||||
|         Visitor *v; | ||||
|  | ||||
|         if (!obj) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         qdv = qapi_dealloc_visitor_new(); | ||||
|         v = qapi_dealloc_get_visitor(qdv); | ||||
|         visit_type_UserDefOne(v, NULL, &obj, NULL); | ||||
|         qapi_dealloc_visitor_cleanup(qdv); | ||||
|     } | ||||
|  | ||||
|     void qapi_free_UserDefOneList(UserDefOneList *obj) | ||||
|     { | ||||
|         QapiDeallocVisitor *qdv; | ||||
|         Visitor *v; | ||||
|  | ||||
|         if (!obj) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         qdv = qapi_dealloc_visitor_new(); | ||||
|         v = qapi_dealloc_get_visitor(qdv); | ||||
|         visit_type_UserDefOneList(v, NULL, &obj, NULL); | ||||
|         qapi_dealloc_visitor_cleanup(qdv); | ||||
|     } | ||||
|  | ||||
| === scripts/qapi-visit.py === | ||||
|  | ||||
| Used to generate the visitor functions used to walk through and convert | ||||
| a QObject (as provided by QMP) to a native C data structure and | ||||
| vice-versa, as well as the visitor function used to dealloc a complex | ||||
| schema-defined C type. | ||||
| Used to generate the visitor functions used to walk through and | ||||
| convert between a native QAPI C data structure and some other format | ||||
| (such as QObject); the generated functions are named visit_type_FOO() | ||||
| and visit_type_FOO_members(). | ||||
|  | ||||
| The following files are generated: | ||||
|  | ||||
| @@ -848,41 +852,62 @@ Example: | ||||
|  | ||||
|     $ python scripts/qapi-visit.py --output-dir="qapi-generated" | ||||
|     --prefix="example-" example-schema.json | ||||
|     $ cat qapi-generated/example-qapi-visit.h | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     #ifndef EXAMPLE_QAPI_VISIT_H | ||||
|     #define EXAMPLE_QAPI_VISIT_H | ||||
|  | ||||
| [Visitors for built-in types omitted...] | ||||
|  | ||||
|     void visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error **errp); | ||||
|     void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, Error **errp); | ||||
|     void visit_type_UserDefOneList(Visitor *v, const char *name, UserDefOneList **obj, Error **errp); | ||||
|  | ||||
|     #endif | ||||
|     $ cat qapi-generated/example-qapi-visit.c | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     static void visit_type_UserDefOne_fields(Visitor *v, UserDefOne **obj, Error **errp) | ||||
|     void visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error **errp) | ||||
|     { | ||||
|         Error *err = NULL; | ||||
|  | ||||
|         visit_type_int(v, &(*obj)->integer, "integer", &err); | ||||
|         visit_type_int(v, "integer", &obj->integer, &err); | ||||
|         if (err) { | ||||
|             goto out; | ||||
|         } | ||||
|         visit_type_str(v, &(*obj)->string, "string", &err); | ||||
|         if (err) { | ||||
|             goto out; | ||||
|         if (visit_optional(v, "string", &obj->has_string)) { | ||||
|             visit_type_str(v, "string", &obj->string, &err); | ||||
|             if (err) { | ||||
|                 goto out; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     out: | ||||
|         error_propagate(errp, err); | ||||
|     } | ||||
|  | ||||
|     void visit_type_UserDefOne(Visitor *v, UserDefOne **obj, const char *name, Error **errp) | ||||
|     void visit_type_UserDefOne(Visitor *v, const char *name, UserDefOne **obj, Error **errp) | ||||
|     { | ||||
|         Error *err = NULL; | ||||
|  | ||||
|         visit_start_struct(v, (void **)obj, "UserDefOne", name, sizeof(UserDefOne), &err); | ||||
|         if (!err) { | ||||
|             if (*obj) { | ||||
|                 visit_type_UserDefOne_fields(v, obj, errp); | ||||
|             } | ||||
|             visit_end_struct(v, &err); | ||||
|         visit_start_struct(v, name, (void **)obj, sizeof(UserDefOne), &err); | ||||
|         if (err) { | ||||
|             goto out; | ||||
|         } | ||||
|         if (!*obj) { | ||||
|             goto out_obj; | ||||
|         } | ||||
|         visit_type_UserDefOne_members(v, *obj, &err); | ||||
|         error_propagate(errp, err); | ||||
|         err = NULL; | ||||
|     out_obj: | ||||
|         visit_end_struct(v, &err); | ||||
|     out: | ||||
|         error_propagate(errp, err); | ||||
|     } | ||||
|  | ||||
|     void visit_type_UserDefOneList(Visitor *v, UserDefOneList **obj, const char *name, Error **errp) | ||||
|     void visit_type_UserDefOneList(Visitor *v, const char *name, UserDefOneList **obj, Error **errp) | ||||
|     { | ||||
|         Error *err = NULL; | ||||
|         GenericList *i, **prev; | ||||
| @@ -893,35 +918,24 @@ Example: | ||||
|         } | ||||
|  | ||||
|         for (prev = (GenericList **)obj; | ||||
|              !err && (i = visit_next_list(v, prev, &err)) != NULL; | ||||
|              !err && (i = visit_next_list(v, prev, sizeof(**obj))) != NULL; | ||||
|              prev = &i) { | ||||
|             UserDefOneList *native_i = (UserDefOneList *)i; | ||||
|             visit_type_UserDefOne(v, &native_i->value, NULL, &err); | ||||
|             visit_type_UserDefOne(v, NULL, &native_i->value, &err); | ||||
|         } | ||||
|  | ||||
|         error_propagate(errp, err); | ||||
|         err = NULL; | ||||
|         visit_end_list(v, &err); | ||||
|         visit_end_list(v); | ||||
|     out: | ||||
|         error_propagate(errp, err); | ||||
|     } | ||||
|     $ cat qapi-generated/example-qapi-visit.h | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     #ifndef EXAMPLE_QAPI_VISIT_H | ||||
|     #define EXAMPLE_QAPI_VISIT_H | ||||
|  | ||||
| [Visitors for built-in types omitted...] | ||||
|  | ||||
|     void visit_type_UserDefOne(Visitor *v, UserDefOne **obj, const char *name, Error **errp); | ||||
|     void visit_type_UserDefOneList(Visitor *v, UserDefOneList **obj, const char *name, Error **errp); | ||||
|  | ||||
|     #endif | ||||
|  | ||||
| === scripts/qapi-commands.py === | ||||
|  | ||||
| Used to generate the marshaling/dispatch functions for the commands defined | ||||
| in the schema. The following files are generated: | ||||
| Used to generate the marshaling/dispatch functions for the commands | ||||
| defined in the schema. The generated code implements | ||||
| qmp_marshal_COMMAND() (mentioned in qmp-commands.hx, and registered | ||||
| automatically), and declares qmp_COMMAND() that the user must | ||||
| implement.  The following files are generated: | ||||
|  | ||||
| $(prefix)qmp-marshal.c: command marshal/dispatch functions for each | ||||
|                         QMP command defined in the schema. Functions | ||||
| @@ -939,6 +953,19 @@ Example: | ||||
|  | ||||
|     $ python scripts/qapi-commands.py --output-dir="qapi-generated" | ||||
|     --prefix="example-" example-schema.json | ||||
|     $ cat qapi-generated/example-qmp-commands.h | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     #ifndef EXAMPLE_QMP_COMMANDS_H | ||||
|     #define EXAMPLE_QMP_COMMANDS_H | ||||
|  | ||||
|     #include "example-qapi-types.h" | ||||
|     #include "qapi/qmp/qdict.h" | ||||
|     #include "qapi/error.h" | ||||
|  | ||||
|     UserDefOne *qmp_my_command(UserDefOneList *arg1, Error **errp); | ||||
|  | ||||
|     #endif | ||||
|     $ cat qapi-generated/example-qmp-marshal.c | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
| @@ -950,7 +977,7 @@ Example: | ||||
|         Visitor *v; | ||||
|  | ||||
|         v = qmp_output_get_visitor(qov); | ||||
|         visit_type_UserDefOne(v, &ret_in, "unused", &err); | ||||
|         visit_type_UserDefOne(v, "unused", &ret_in, &err); | ||||
|         if (err) { | ||||
|             goto out; | ||||
|         } | ||||
| @@ -961,7 +988,7 @@ Example: | ||||
|         qmp_output_visitor_cleanup(qov); | ||||
|         qdv = qapi_dealloc_visitor_new(); | ||||
|         v = qapi_dealloc_get_visitor(qdv); | ||||
|         visit_type_UserDefOne(v, &ret_in, "unused", NULL); | ||||
|         visit_type_UserDefOne(v, "unused", &ret_in, NULL); | ||||
|         qapi_dealloc_visitor_cleanup(qdv); | ||||
|     } | ||||
|  | ||||
| @@ -972,10 +999,10 @@ Example: | ||||
|         QmpInputVisitor *qiv = qmp_input_visitor_new_strict(QOBJECT(args)); | ||||
|         QapiDeallocVisitor *qdv; | ||||
|         Visitor *v; | ||||
|         UserDefOne *arg1 = NULL; | ||||
|         UserDefOneList *arg1 = NULL; | ||||
|  | ||||
|         v = qmp_input_get_visitor(qiv); | ||||
|         visit_type_UserDefOne(v, &arg1, "arg1", &err); | ||||
|         visit_type_UserDefOneList(v, "arg1", &arg1, &err); | ||||
|         if (err) { | ||||
|             goto out; | ||||
|         } | ||||
| @@ -992,7 +1019,7 @@ Example: | ||||
|         qmp_input_visitor_cleanup(qiv); | ||||
|         qdv = qapi_dealloc_visitor_new(); | ||||
|         v = qapi_dealloc_get_visitor(qdv); | ||||
|         visit_type_UserDefOne(v, &arg1, "arg1", NULL); | ||||
|         visit_type_UserDefOneList(v, "arg1", &arg1, NULL); | ||||
|         qapi_dealloc_visitor_cleanup(qdv); | ||||
|     } | ||||
|  | ||||
| @@ -1002,24 +1029,12 @@ Example: | ||||
|     } | ||||
|  | ||||
|     qapi_init(qmp_init_marshal); | ||||
|     $ cat qapi-generated/example-qmp-commands.h | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     #ifndef EXAMPLE_QMP_COMMANDS_H | ||||
|     #define EXAMPLE_QMP_COMMANDS_H | ||||
|  | ||||
|     #include "example-qapi-types.h" | ||||
|     #include "qapi/qmp/qdict.h" | ||||
|     #include "qapi/error.h" | ||||
|  | ||||
|     UserDefOne *qmp_my_command(UserDefOne *arg1, Error **errp); | ||||
|  | ||||
|     #endif | ||||
|  | ||||
| === scripts/qapi-event.py === | ||||
|  | ||||
| Used to generate the event-related C code defined by a schema. The | ||||
| following files are created: | ||||
| Used to generate the event-related C code defined by a schema, with | ||||
| implementations for qapi_event_send_FOO(). The following files are | ||||
| created: | ||||
|  | ||||
| $(prefix)qapi-event.h - Function prototypes for each event type, plus an | ||||
|                         enumeration of all event names | ||||
| @@ -1029,6 +1044,27 @@ Example: | ||||
|  | ||||
|     $ python scripts/qapi-event.py --output-dir="qapi-generated" | ||||
|     --prefix="example-" example-schema.json | ||||
|     $ cat qapi-generated/example-qapi-event.h | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     #ifndef EXAMPLE_QAPI_EVENT_H | ||||
|     #define EXAMPLE_QAPI_EVENT_H | ||||
|  | ||||
|     #include "qapi/error.h" | ||||
|     #include "qapi/qmp/qdict.h" | ||||
|     #include "example-qapi-types.h" | ||||
|  | ||||
|  | ||||
|     void qapi_event_send_my_event(Error **errp); | ||||
|  | ||||
|     typedef enum example_QAPIEvent { | ||||
|         EXAMPLE_QAPI_EVENT_MY_EVENT = 0, | ||||
|         EXAMPLE_QAPI_EVENT__MAX = 1, | ||||
|     } example_QAPIEvent; | ||||
|  | ||||
|     extern const char *const example_QAPIEvent_lookup[]; | ||||
|  | ||||
|     #endif | ||||
|     $ cat qapi-generated/example-qapi-event.c | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
| @@ -1054,27 +1090,6 @@ Example: | ||||
|         [EXAMPLE_QAPI_EVENT_MY_EVENT] = "MY_EVENT", | ||||
|         [EXAMPLE_QAPI_EVENT__MAX] = NULL, | ||||
|     }; | ||||
|     $ cat qapi-generated/example-qapi-event.h | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     #ifndef EXAMPLE_QAPI_EVENT_H | ||||
|     #define EXAMPLE_QAPI_EVENT_H | ||||
|  | ||||
|     #include "qapi/error.h" | ||||
|     #include "qapi/qmp/qdict.h" | ||||
|     #include "example-qapi-types.h" | ||||
|  | ||||
|  | ||||
|     void qapi_event_send_my_event(Error **errp); | ||||
|  | ||||
|     typedef enum example_QAPIEvent { | ||||
|         EXAMPLE_QAPI_EVENT_MY_EVENT = 0, | ||||
|         EXAMPLE_QAPI_EVENT__MAX = 1, | ||||
|     } example_QAPIEvent; | ||||
|  | ||||
|     extern const char *const example_QAPIEvent_lookup[]; | ||||
|  | ||||
|     #endif | ||||
|  | ||||
| === scripts/qapi-introspect.py === | ||||
|  | ||||
| @@ -1089,17 +1104,6 @@ Example: | ||||
|  | ||||
|     $ python scripts/qapi-introspect.py --output-dir="qapi-generated" | ||||
|     --prefix="example-" example-schema.json | ||||
|     $ cat qapi-generated/example-qmp-introspect.c | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     const char example_qmp_schema_json[] = "[" | ||||
|         "{\"arg-type\": \"0\", \"meta-type\": \"event\", \"name\": \"MY_EVENT\"}, " | ||||
|         "{\"arg-type\": \"1\", \"meta-type\": \"command\", \"name\": \"my-command\", \"ret-type\": \"2\"}, " | ||||
|         "{\"members\": [], \"meta-type\": \"object\", \"name\": \"0\"}, " | ||||
|         "{\"members\": [{\"name\": \"arg1\", \"type\": \"2\"}], \"meta-type\": \"object\", \"name\": \"1\"}, " | ||||
|         "{\"members\": [{\"name\": \"integer\", \"type\": \"int\"}, {\"name\": \"string\", \"type\": \"str\"}], \"meta-type\": \"object\", \"name\": \"2\"}, " | ||||
|         "{\"json-type\": \"int\", \"meta-type\": \"builtin\", \"name\": \"int\"}, " | ||||
|         "{\"json-type\": \"string\", \"meta-type\": \"builtin\", \"name\": \"str\"}]"; | ||||
|     $ cat qapi-generated/example-qmp-introspect.h | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
| @@ -1109,3 +1113,15 @@ Example: | ||||
|     extern const char example_qmp_schema_json[]; | ||||
|  | ||||
|     #endif | ||||
|     $ cat qapi-generated/example-qmp-introspect.c | ||||
| [Uninteresting stuff omitted...] | ||||
|  | ||||
|     const char example_qmp_schema_json[] = "[" | ||||
|         "{\"arg-type\": \"0\", \"meta-type\": \"event\", \"name\": \"MY_EVENT\"}, " | ||||
|         "{\"arg-type\": \"1\", \"meta-type\": \"command\", \"name\": \"my-command\", \"ret-type\": \"2\"}, " | ||||
|         "{\"members\": [], \"meta-type\": \"object\", \"name\": \"0\"}, " | ||||
|         "{\"members\": [{\"name\": \"arg1\", \"type\": \"[2]\"}], \"meta-type\": \"object\", \"name\": \"1\"}, " | ||||
|         "{\"members\": [{\"name\": \"integer\", \"type\": \"int\"}, {\"default\": null, \"name\": \"string\", \"type\": \"str\"}], \"meta-type\": \"object\", \"name\": \"2\"}, " | ||||
|         "{\"element-type\": \"2\", \"meta-type\": \"array\", \"name\": \"[2]\"}, " | ||||
|         "{\"json-type\": \"int\", \"meta-type\": \"builtin\", \"name\": \"int\"}, " | ||||
|         "{\"json-type\": \"string\", \"meta-type\": \"builtin\", \"name\": \"str\"}]"; | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| 0. About This Document | ||||
| ====================== | ||||
|  | ||||
| Copyright (C) 2009-2015 Red Hat, Inc. | ||||
| Copyright (C) 2009-2016 Red Hat, Inc. | ||||
|  | ||||
| This work is licensed under the terms of the GNU GPL, version 2 or | ||||
| later. See the COPYING file in the top-level directory. | ||||
| @@ -277,7 +277,7 @@ However, Clients must not assume any particular: | ||||
| - Amount of errors generated by a command, that is, new errors can be added | ||||
|   to any existing command in newer versions of the Server | ||||
|  | ||||
| Any command or field name beginning with "x-" is deemed experimental, | ||||
| Any command or member name beginning with "x-" is deemed experimental, | ||||
| and may be withdrawn or changed in an incompatible manner in a future | ||||
| release. | ||||
|  | ||||
|   | ||||
| @@ -26,7 +26,6 @@ | ||||
| #include "hw/nvram/fw_cfg.h" | ||||
| #include "qemu/config-file.h" | ||||
| #include "qapi/opts-visitor.h" | ||||
| #include "qapi/dealloc-visitor.h" | ||||
| #include "qapi-visit.h" | ||||
| #include "qapi-event.h" | ||||
|  | ||||
| @@ -297,15 +296,7 @@ void acpi_table_add(const QemuOpts *opts, Error **errp) | ||||
| out: | ||||
|     g_free(blob); | ||||
|     g_strfreev(pathnames); | ||||
|  | ||||
|     if (hdrs != NULL) { | ||||
|         QapiDeallocVisitor *dv; | ||||
|  | ||||
|         dv = qapi_dealloc_visitor_new(); | ||||
|         visit_type_AcpiTableOptions(qapi_dealloc_get_visitor(dv), NULL, &hdrs, | ||||
|                                     NULL); | ||||
|         qapi_dealloc_visitor_cleanup(dv); | ||||
|     } | ||||
|     qapi_free_AcpiTableOptions(hdrs); | ||||
|  | ||||
|     error_propagate(errp, err); | ||||
| } | ||||
|   | ||||
| @@ -842,14 +842,16 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src, | ||||
| { | ||||
|     ChannelState *s = (ChannelState *)dev; | ||||
|     int qcode, keycode; | ||||
|     InputKeyEvent *key; | ||||
|  | ||||
|     assert(evt->type == INPUT_EVENT_KIND_KEY); | ||||
|     qcode = qemu_input_key_value_to_qcode(evt->u.key->key); | ||||
|     key = evt->u.key; | ||||
|     qcode = qemu_input_key_value_to_qcode(key->key); | ||||
|     trace_escc_sunkbd_event_in(qcode, QKeyCode_lookup[qcode], | ||||
|                                evt->u.key->down); | ||||
|                                key->down); | ||||
|  | ||||
|     if (qcode == Q_KEY_CODE_CAPS_LOCK) { | ||||
|         if (evt->u.key->down) { | ||||
|         if (key->down) { | ||||
|             s->caps_lock_mode ^= 1; | ||||
|             if (s->caps_lock_mode == 2) { | ||||
|                 return; /* Drop second press */ | ||||
| @@ -863,7 +865,7 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src, | ||||
|     } | ||||
|  | ||||
|     if (qcode == Q_KEY_CODE_NUM_LOCK) { | ||||
|         if (evt->u.key->down) { | ||||
|         if (key->down) { | ||||
|             s->num_lock_mode ^= 1; | ||||
|             if (s->num_lock_mode == 2) { | ||||
|                 return; /* Drop second press */ | ||||
| @@ -877,7 +879,7 @@ static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src, | ||||
|     } | ||||
|  | ||||
|     keycode = qcode_to_keycode[qcode]; | ||||
|     if (!evt->u.key->down) { | ||||
|     if (!key->down) { | ||||
|         keycode |= 0x80; | ||||
|     } | ||||
|     trace_escc_sunkbd_event_out(keycode); | ||||
|   | ||||
| @@ -116,37 +116,42 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src, | ||||
|     }; | ||||
|     HIDState *hs = (HIDState *)dev; | ||||
|     HIDPointerEvent *e; | ||||
|     InputMoveEvent *move; | ||||
|     InputBtnEvent *btn; | ||||
|  | ||||
|     assert(hs->n < QUEUE_LENGTH); | ||||
|     e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK]; | ||||
|  | ||||
|     switch (evt->type) { | ||||
|     case INPUT_EVENT_KIND_REL: | ||||
|         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; | ||||
|         move = evt->u.rel; | ||||
|         if (move->axis == INPUT_AXIS_X) { | ||||
|             e->xdx += move->value; | ||||
|         } else if (move->axis == INPUT_AXIS_Y) { | ||||
|             e->ydy += move->value; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case INPUT_EVENT_KIND_ABS: | ||||
|         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; | ||||
|         move = evt->u.abs; | ||||
|         if (move->axis == INPUT_AXIS_X) { | ||||
|             e->xdx = move->value; | ||||
|         } else if (move->axis == INPUT_AXIS_Y) { | ||||
|             e->ydy = move->value; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case INPUT_EVENT_KIND_BTN: | ||||
|         if (evt->u.btn->down) { | ||||
|             e->buttons_state |= bmap[evt->u.btn->button]; | ||||
|             if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) { | ||||
|         btn = evt->u.btn; | ||||
|         if (btn->down) { | ||||
|             e->buttons_state |= bmap[btn->button]; | ||||
|             if (btn->button == INPUT_BUTTON_WHEEL_UP) { | ||||
|                 e->dz--; | ||||
|             } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) { | ||||
|             } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) { | ||||
|                 e->dz++; | ||||
|             } | ||||
|         } else { | ||||
|             e->buttons_state &= ~bmap[evt->u.btn->button]; | ||||
|             e->buttons_state &= ~bmap[btn->button]; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
| @@ -223,9 +228,10 @@ static void hid_keyboard_event(DeviceState *dev, QemuConsole *src, | ||||
|     HIDState *hs = (HIDState *)dev; | ||||
|     int scancodes[3], i, count; | ||||
|     int slot; | ||||
|     InputKeyEvent *key = evt->u.key; | ||||
|  | ||||
|     count = qemu_input_key_value_to_scancode(evt->u.key->key, | ||||
|                                              evt->u.key->down, | ||||
|     count = qemu_input_key_value_to_scancode(key->key, | ||||
|                                              key->down, | ||||
|                                              scancodes); | ||||
|     if (hs->n + count > QUEUE_LENGTH) { | ||||
|         fprintf(stderr, "usb-kbd: warning: key event queue full\n"); | ||||
|   | ||||
| @@ -182,10 +182,11 @@ static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src, | ||||
| { | ||||
|     PS2KbdState *s = (PS2KbdState *)dev; | ||||
|     int scancodes[3], i, count; | ||||
|     InputKeyEvent *key = evt->u.key; | ||||
|  | ||||
|     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); | ||||
|     count = qemu_input_key_value_to_scancode(evt->u.key->key, | ||||
|                                              evt->u.key->down, | ||||
|     count = qemu_input_key_value_to_scancode(key->key, | ||||
|                                              key->down, | ||||
|                                              scancodes); | ||||
|     for (i = 0; i < count; i++) { | ||||
|         ps2_put_keycode(s, scancodes[i]); | ||||
| @@ -389,6 +390,8 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, | ||||
|         [INPUT_BUTTON_RIGHT]  = MOUSE_EVENT_RBUTTON, | ||||
|     }; | ||||
|     PS2MouseState *s = (PS2MouseState *)dev; | ||||
|     InputMoveEvent *move; | ||||
|     InputBtnEvent *btn; | ||||
|  | ||||
|     /* check if deltas are recorded when disabled */ | ||||
|     if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) | ||||
| @@ -396,23 +399,25 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, | ||||
|  | ||||
|     switch (evt->type) { | ||||
|     case INPUT_EVENT_KIND_REL: | ||||
|         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; | ||||
|         move = evt->u.rel; | ||||
|         if (move->axis == INPUT_AXIS_X) { | ||||
|             s->mouse_dx += move->value; | ||||
|         } else if (move->axis == INPUT_AXIS_Y) { | ||||
|             s->mouse_dy -= move->value; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|     case INPUT_EVENT_KIND_BTN: | ||||
|         if (evt->u.btn->down) { | ||||
|             s->mouse_buttons |= bmap[evt->u.btn->button]; | ||||
|             if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) { | ||||
|         btn = evt->u.btn; | ||||
|         if (btn->down) { | ||||
|             s->mouse_buttons |= bmap[btn->button]; | ||||
|             if (btn->button == INPUT_BUTTON_WHEEL_UP) { | ||||
|                 s->mouse_dz--; | ||||
|             } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) { | ||||
|             } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) { | ||||
|                 s->mouse_dz++; | ||||
|             } | ||||
|         } else { | ||||
|             s->mouse_buttons &= ~bmap[evt->u.btn->button]; | ||||
|             s->mouse_buttons &= ~bmap[btn->button]; | ||||
|         } | ||||
|         break; | ||||
|  | ||||
|   | ||||
| @@ -191,46 +191,53 @@ static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src, | ||||
|     VirtIOInput *vinput = VIRTIO_INPUT(dev); | ||||
|     virtio_input_event event; | ||||
|     int qcode; | ||||
|     InputKeyEvent *key; | ||||
|     InputMoveEvent *move; | ||||
|     InputBtnEvent *btn; | ||||
|  | ||||
|     switch (evt->type) { | ||||
|     case INPUT_EVENT_KIND_KEY: | ||||
|         qcode = qemu_input_key_value_to_qcode(evt->u.key->key); | ||||
|         key = evt->u.key; | ||||
|         qcode = qemu_input_key_value_to_qcode(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->u.key->down ? 1 : 0); | ||||
|             event.value = cpu_to_le32(key->down ? 1 : 0); | ||||
|             virtio_input_send(vinput, &event); | ||||
|         } else { | ||||
|             if (evt->u.key->down) { | ||||
|             if (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->u.btn->button]) { | ||||
|         btn = evt->u.btn; | ||||
|         if (keymap_button[btn->button]) { | ||||
|             event.type  = cpu_to_le16(EV_KEY); | ||||
|             event.code  = cpu_to_le16(keymap_button[evt->u.btn->button]); | ||||
|             event.value = cpu_to_le32(evt->u.btn->down ? 1 : 0); | ||||
|             event.code  = cpu_to_le16(keymap_button[btn->button]); | ||||
|             event.value = cpu_to_le32(btn->down ? 1 : 0); | ||||
|             virtio_input_send(vinput, &event); | ||||
|         } else { | ||||
|             if (evt->u.btn->down) { | ||||
|             if (btn->down) { | ||||
|                 fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__, | ||||
|                         evt->u.btn->button, | ||||
|                         InputButton_lookup[evt->u.btn->button]); | ||||
|                         btn->button, | ||||
|                         InputButton_lookup[btn->button]); | ||||
|             } | ||||
|         } | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND_REL: | ||||
|         move = evt->u.rel; | ||||
|         event.type  = cpu_to_le16(EV_REL); | ||||
|         event.code  = cpu_to_le16(axismap_rel[evt->u.rel->axis]); | ||||
|         event.value = cpu_to_le32(evt->u.rel->value); | ||||
|         event.code  = cpu_to_le16(axismap_rel[move->axis]); | ||||
|         event.value = cpu_to_le32(move->value); | ||||
|         virtio_input_send(vinput, &event); | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND_ABS: | ||||
|         move = evt->u.abs; | ||||
|         event.type  = cpu_to_le16(EV_ABS); | ||||
|         event.code  = cpu_to_le16(axismap_abs[evt->u.abs->axis]); | ||||
|         event.value = cpu_to_le32(evt->u.abs->value); | ||||
|         event.code  = cpu_to_le16(axismap_abs[move->axis]); | ||||
|         event.value = cpu_to_le32(move->value); | ||||
|         virtio_input_send(vinput, &event); | ||||
|         break; | ||||
|     default: | ||||
|   | ||||
							
								
								
									
										31
									
								
								net/net.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								net/net.c
									
									
									
									
									
								
							| @@ -42,7 +42,6 @@ | ||||
| #include "qemu/main-loop.h" | ||||
| #include "qapi-visit.h" | ||||
| #include "qapi/opts-visitor.h" | ||||
| #include "qapi/dealloc-visitor.h" | ||||
| #include "sysemu/sysemu.h" | ||||
| #include "net/filter.h" | ||||
| #include "qapi/string-output-visitor.h" | ||||
| @@ -1043,38 +1042,28 @@ static int net_client_init1(const void *object, int is_netdev, Error **errp) | ||||
| } | ||||
|  | ||||
|  | ||||
| static void net_visit(Visitor *v, int is_netdev, void **object, Error **errp) | ||||
| { | ||||
|     if (is_netdev) { | ||||
|         visit_type_Netdev(v, NULL, (Netdev **)object, errp); | ||||
|     } else { | ||||
|         visit_type_NetLegacy(v, NULL, (NetLegacy **)object, errp); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| int net_client_init(QemuOpts *opts, int is_netdev, Error **errp) | ||||
| { | ||||
|     void *object = NULL; | ||||
|     Error *err = NULL; | ||||
|     int ret = -1; | ||||
|     OptsVisitor *ov = opts_visitor_new(opts); | ||||
|     Visitor *v = opts_get_visitor(ov); | ||||
|  | ||||
|     { | ||||
|         OptsVisitor *ov = opts_visitor_new(opts); | ||||
|  | ||||
|         net_visit(opts_get_visitor(ov), is_netdev, &object, &err); | ||||
|         opts_visitor_cleanup(ov); | ||||
|     if (is_netdev) { | ||||
|         visit_type_Netdev(v, NULL, (Netdev **)&object, &err); | ||||
|     } else { | ||||
|         visit_type_NetLegacy(v, NULL, (NetLegacy **)&object, &err); | ||||
|     } | ||||
|  | ||||
|     if (!err) { | ||||
|         ret = net_client_init1(object, is_netdev, &err); | ||||
|     } | ||||
|  | ||||
|     if (object) { | ||||
|         QapiDeallocVisitor *dv = qapi_dealloc_visitor_new(); | ||||
|  | ||||
|         net_visit(qapi_dealloc_get_visitor(dv), is_netdev, &object, NULL); | ||||
|         qapi_dealloc_visitor_cleanup(dv); | ||||
|     if (is_netdev) { | ||||
|         qapi_free_Netdev(object); | ||||
|     } else { | ||||
|         qapi_free_NetLegacy(object); | ||||
|     } | ||||
|  | ||||
|     error_propagate(errp, err); | ||||
|   | ||||
							
								
								
									
										9
									
								
								numa.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								numa.c
									
									
									
									
									
								
							| @@ -31,7 +31,6 @@ | ||||
| #include "include/exec/cpu-common.h" /* for RAM_ADDR_FMT */ | ||||
| #include "qapi-visit.h" | ||||
| #include "qapi/opts-visitor.h" | ||||
| #include "qapi/dealloc-visitor.h" | ||||
| #include "hw/boards.h" | ||||
| #include "sysemu/hostmem.h" | ||||
| #include "qmp-commands.h" | ||||
| @@ -243,13 +242,7 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) | ||||
|  | ||||
| error: | ||||
|     error_report_err(err); | ||||
|  | ||||
|     if (object) { | ||||
|         QapiDeallocVisitor *dv = qapi_dealloc_visitor_new(); | ||||
|         visit_type_NumaOptions(qapi_dealloc_get_visitor(dv), NULL, &object, | ||||
|                                NULL); | ||||
|         qapi_dealloc_visitor_cleanup(dv); | ||||
|     } | ||||
|     qapi_free_NumaOptions(object); | ||||
|  | ||||
|     return -1; | ||||
| } | ||||
|   | ||||
| @@ -3323,23 +3323,20 @@ | ||||
| # | ||||
| # Since: 1.4 (testdev since 2.2) | ||||
| ## | ||||
| { 'struct': 'ChardevDummy', 'data': { }, | ||||
|   'base': 'ChardevCommon' } | ||||
|  | ||||
| { 'union': 'ChardevBackend', 'data': { 'file'   : 'ChardevFile', | ||||
|                                        'serial' : 'ChardevHostdev', | ||||
|                                        'parallel': 'ChardevHostdev', | ||||
|                                        'pipe'   : 'ChardevHostdev', | ||||
|                                        'socket' : 'ChardevSocket', | ||||
|                                        'udp'    : 'ChardevUdp', | ||||
|                                        'pty'    : 'ChardevDummy', | ||||
|                                        'null'   : 'ChardevDummy', | ||||
|                                        'pty'    : 'ChardevCommon', | ||||
|                                        'null'   : 'ChardevCommon', | ||||
|                                        'mux'    : 'ChardevMux', | ||||
|                                        'msmouse': 'ChardevDummy', | ||||
|                                        'braille': 'ChardevDummy', | ||||
|                                        'testdev': 'ChardevDummy', | ||||
|                                        'msmouse': 'ChardevCommon', | ||||
|                                        'braille': 'ChardevCommon', | ||||
|                                        'testdev': 'ChardevCommon', | ||||
|                                        'stdio'  : 'ChardevStdio', | ||||
|                                        'console': 'ChardevDummy', | ||||
|                                        'console': 'ChardevCommon', | ||||
|                                        'spicevmc' : 'ChardevSpiceChannel', | ||||
|                                        'spiceport' : 'ChardevSpicePort', | ||||
|                                        'vc'     : 'ChardevVC', | ||||
|   | ||||
							
								
								
									
										179
									
								
								qemu-char.c
									
									
									
									
									
								
							
							
						
						
									
										179
									
								
								qemu-char.c
									
									
									
									
									
								
							| @@ -420,7 +420,7 @@ static CharDriverState *qemu_chr_open_null(const char *id, | ||||
|                                            Error **errp) | ||||
| { | ||||
|     CharDriverState *chr; | ||||
|     ChardevCommon *common = qapi_ChardevDummy_base(backend->u.null); | ||||
|     ChardevCommon *common = backend->u.null; | ||||
|  | ||||
|     chr = qemu_chr_alloc(common, errp); | ||||
|     if (!chr) { | ||||
| @@ -724,7 +724,7 @@ static CharDriverState *qemu_chr_open_mux(const char *id, | ||||
|     ChardevMux *mux = backend->u.mux; | ||||
|     CharDriverState *chr, *drv; | ||||
|     MuxDriver *d; | ||||
|     ChardevCommon *common = qapi_ChardevMux_base(backend->u.mux); | ||||
|     ChardevCommon *common = qapi_ChardevMux_base(mux); | ||||
|  | ||||
|     drv = qemu_chr_find(mux->chardev); | ||||
|     if (drv == NULL) { | ||||
| @@ -1043,7 +1043,7 @@ static CharDriverState *qemu_chr_open_pipe(const char *id, | ||||
|     char *filename_in; | ||||
|     char *filename_out; | ||||
|     const char *filename = opts->device; | ||||
|     ChardevCommon *common = qapi_ChardevHostdev_base(backend->u.pipe); | ||||
|     ChardevCommon *common = qapi_ChardevHostdev_base(opts); | ||||
|  | ||||
|  | ||||
|     filename_in = g_strdup_printf("%s.in", filename); | ||||
| @@ -1123,7 +1123,7 @@ static CharDriverState *qemu_chr_open_stdio(const char *id, | ||||
|     ChardevStdio *opts = backend->u.stdio; | ||||
|     CharDriverState *chr; | ||||
|     struct sigaction act; | ||||
|     ChardevCommon *common = qapi_ChardevStdio_base(backend->u.stdio); | ||||
|     ChardevCommon *common = qapi_ChardevStdio_base(opts); | ||||
|  | ||||
|     if (is_daemonized()) { | ||||
|         error_setg(errp, "cannot use stdio with -daemonize"); | ||||
| @@ -1366,7 +1366,7 @@ static CharDriverState *qemu_chr_open_pty(const char *id, | ||||
|     PtyCharDriver *s; | ||||
|     int master_fd, slave_fd; | ||||
|     char pty_name[PATH_MAX]; | ||||
|     ChardevCommon *common = qapi_ChardevDummy_base(backend->u.pty); | ||||
|     ChardevCommon *common = backend->u.pty; | ||||
|  | ||||
|     master_fd = qemu_openpty_raw(&slave_fd, pty_name); | ||||
|     if (master_fd < 0) { | ||||
| @@ -2141,7 +2141,7 @@ static CharDriverState *qemu_chr_open_pipe(const char *id, | ||||
|     const char *filename = opts->device; | ||||
|     CharDriverState *chr; | ||||
|     WinCharState *s; | ||||
|     ChardevCommon *common = qapi_ChardevHostdev_base(backend->u.pipe); | ||||
|     ChardevCommon *common = qapi_ChardevHostdev_base(opts); | ||||
|  | ||||
|     chr = qemu_chr_alloc(common, errp); | ||||
|     if (!chr) { | ||||
| @@ -2183,7 +2183,7 @@ static CharDriverState *qemu_chr_open_win_con(const char *id, | ||||
|                                               ChardevReturn *ret, | ||||
|                                               Error **errp) | ||||
| { | ||||
|     ChardevCommon *common = qapi_ChardevDummy_base(backend->u.console); | ||||
|     ChardevCommon *common = backend->u.console; | ||||
|     return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE), | ||||
|                                   common, errp); | ||||
| } | ||||
| @@ -3216,7 +3216,7 @@ static CharDriverState *qemu_chr_open_ringbuf(const char *id, | ||||
|                                               Error **errp) | ||||
| { | ||||
|     ChardevRingbuf *opts = backend->u.ringbuf; | ||||
|     ChardevCommon *common = qapi_ChardevRingbuf_base(backend->u.ringbuf); | ||||
|     ChardevCommon *common = qapi_ChardevRingbuf_base(opts); | ||||
|     CharDriverState *chr; | ||||
|     RingBufCharDriver *d; | ||||
|  | ||||
| @@ -3506,26 +3506,29 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend, | ||||
|                                     Error **errp) | ||||
| { | ||||
|     const char *path = qemu_opt_get(opts, "path"); | ||||
|     ChardevFile *file; | ||||
|  | ||||
|     if (path == NULL) { | ||||
|         error_setg(errp, "chardev: file: no filename given"); | ||||
|         return; | ||||
|     } | ||||
|     backend->u.file = g_new0(ChardevFile, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevFile_base(backend->u.file)); | ||||
|     backend->u.file->out = g_strdup(path); | ||||
|     file = backend->u.file = g_new0(ChardevFile, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevFile_base(file)); | ||||
|     file->out = g_strdup(path); | ||||
|  | ||||
|     backend->u.file->has_append = true; | ||||
|     backend->u.file->append = qemu_opt_get_bool(opts, "append", false); | ||||
|     file->has_append = true; | ||||
|     file->append = qemu_opt_get_bool(opts, "append", false); | ||||
| } | ||||
|  | ||||
| static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend, | ||||
|                                  Error **errp) | ||||
| { | ||||
|     backend->u.stdio = g_new0(ChardevStdio, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevStdio_base(backend->u.stdio)); | ||||
|     backend->u.stdio->has_signal = true; | ||||
|     backend->u.stdio->signal = qemu_opt_get_bool(opts, "signal", true); | ||||
|     ChardevStdio *stdio; | ||||
|  | ||||
|     stdio = backend->u.stdio = g_new0(ChardevStdio, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevStdio_base(stdio)); | ||||
|     stdio->has_signal = true; | ||||
|     stdio->signal = qemu_opt_get_bool(opts, "signal", true); | ||||
| } | ||||
|  | ||||
| #ifdef HAVE_CHARDEV_SERIAL | ||||
| @@ -3533,14 +3536,15 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, | ||||
|                                   Error **errp) | ||||
| { | ||||
|     const char *device = qemu_opt_get(opts, "path"); | ||||
|     ChardevHostdev *serial; | ||||
|  | ||||
|     if (device == NULL) { | ||||
|         error_setg(errp, "chardev: serial/tty: no device path given"); | ||||
|         return; | ||||
|     } | ||||
|     backend->u.serial = g_new0(ChardevHostdev, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(backend->u.serial)); | ||||
|     backend->u.serial->device = g_strdup(device); | ||||
|     serial = backend->u.serial = g_new0(ChardevHostdev, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(serial)); | ||||
|     serial->device = g_strdup(device); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @@ -3549,14 +3553,15 @@ static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, | ||||
|                                     Error **errp) | ||||
| { | ||||
|     const char *device = qemu_opt_get(opts, "path"); | ||||
|     ChardevHostdev *parallel; | ||||
|  | ||||
|     if (device == NULL) { | ||||
|         error_setg(errp, "chardev: parallel: no device path given"); | ||||
|         return; | ||||
|     } | ||||
|     backend->u.parallel = g_new0(ChardevHostdev, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(backend->u.parallel)); | ||||
|     backend->u.parallel->device = g_strdup(device); | ||||
|     parallel = backend->u.parallel = g_new0(ChardevHostdev, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(parallel)); | ||||
|     parallel->device = g_strdup(device); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @@ -3564,28 +3569,30 @@ static void qemu_chr_parse_pipe(QemuOpts *opts, ChardevBackend *backend, | ||||
|                                 Error **errp) | ||||
| { | ||||
|     const char *device = qemu_opt_get(opts, "path"); | ||||
|     ChardevHostdev *dev; | ||||
|  | ||||
|     if (device == NULL) { | ||||
|         error_setg(errp, "chardev: pipe: no device path given"); | ||||
|         return; | ||||
|     } | ||||
|     backend->u.pipe = g_new0(ChardevHostdev, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(backend->u.pipe)); | ||||
|     backend->u.pipe->device = g_strdup(device); | ||||
|     dev = backend->u.pipe = g_new0(ChardevHostdev, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(dev)); | ||||
|     dev->device = g_strdup(device); | ||||
| } | ||||
|  | ||||
| static void qemu_chr_parse_ringbuf(QemuOpts *opts, ChardevBackend *backend, | ||||
|                                    Error **errp) | ||||
| { | ||||
|     int val; | ||||
|     ChardevRingbuf *ringbuf; | ||||
|  | ||||
|     backend->u.ringbuf = g_new0(ChardevRingbuf, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevRingbuf_base(backend->u.ringbuf)); | ||||
|     ringbuf = backend->u.ringbuf = g_new0(ChardevRingbuf, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevRingbuf_base(ringbuf)); | ||||
|  | ||||
|     val = qemu_opt_get_size(opts, "size", 0); | ||||
|     if (val != 0) { | ||||
|         backend->u.ringbuf->has_size = true; | ||||
|         backend->u.ringbuf->size = val; | ||||
|         ringbuf->has_size = true; | ||||
|         ringbuf->size = val; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -3593,14 +3600,15 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend, | ||||
|                                Error **errp) | ||||
| { | ||||
|     const char *chardev = qemu_opt_get(opts, "chardev"); | ||||
|     ChardevMux *mux; | ||||
|  | ||||
|     if (chardev == NULL) { | ||||
|         error_setg(errp, "chardev: mux: no chardev given"); | ||||
|         return; | ||||
|     } | ||||
|     backend->u.mux = g_new0(ChardevMux, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevMux_base(backend->u.mux)); | ||||
|     backend->u.mux->chardev = g_strdup(chardev); | ||||
|     mux = backend->u.mux = g_new0(ChardevMux, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevMux_base(mux)); | ||||
|     mux->chardev = g_strdup(chardev); | ||||
| } | ||||
|  | ||||
| static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, | ||||
| @@ -3616,6 +3624,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, | ||||
|     const char *port = qemu_opt_get(opts, "port"); | ||||
|     const char *tls_creds = qemu_opt_get(opts, "tls-creds"); | ||||
|     SocketAddress *addr; | ||||
|     ChardevSocket *sock; | ||||
|  | ||||
|     if (!path) { | ||||
|         if (!host) { | ||||
| @@ -3633,39 +3642,42 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     backend->u.socket = g_new0(ChardevSocket, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevSocket_base(backend->u.socket)); | ||||
|     sock = backend->u.socket = g_new0(ChardevSocket, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevSocket_base(sock)); | ||||
|  | ||||
|     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; | ||||
|     backend->u.socket->tls_creds = g_strdup(tls_creds); | ||||
|     sock->has_nodelay = true; | ||||
|     sock->nodelay = do_nodelay; | ||||
|     sock->has_server = true; | ||||
|     sock->server = is_listen; | ||||
|     sock->has_telnet = true; | ||||
|     sock->telnet = is_telnet; | ||||
|     sock->has_wait = true; | ||||
|     sock->wait = is_waitconnect; | ||||
|     sock->has_reconnect = true; | ||||
|     sock->reconnect = reconnect; | ||||
|     sock->tls_creds = g_strdup(tls_creds); | ||||
|  | ||||
|     addr = g_new0(SocketAddress, 1); | ||||
|     if (path) { | ||||
|         UnixSocketAddress *q_unix; | ||||
|         addr->type = SOCKET_ADDRESS_KIND_UNIX; | ||||
|         addr->u.q_unix = g_new0(UnixSocketAddress, 1); | ||||
|         addr->u.q_unix->path = g_strdup(path); | ||||
|         q_unix = addr->u.q_unix = g_new0(UnixSocketAddress, 1); | ||||
|         q_unix->path = g_strdup(path); | ||||
|     } else { | ||||
|         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); | ||||
|         addr->u.inet = g_new(InetSocketAddress, 1); | ||||
|         *addr->u.inet = (InetSocketAddress) { | ||||
|             .host = g_strdup(host), | ||||
|             .port = g_strdup(port), | ||||
|             .has_to = qemu_opt_get(opts, "to"), | ||||
|             .to = qemu_opt_get_number(opts, "to", 0), | ||||
|             .has_ipv4 = qemu_opt_get(opts, "ipv4"), | ||||
|             .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0), | ||||
|             .has_ipv6 = qemu_opt_get(opts, "ipv6"), | ||||
|             .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0), | ||||
|         }; | ||||
|     } | ||||
|     backend->u.socket->addr = addr; | ||||
|     sock->addr = addr; | ||||
| } | ||||
|  | ||||
| static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend, | ||||
| @@ -3677,6 +3689,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend, | ||||
|     const char *localport = qemu_opt_get(opts, "localport"); | ||||
|     bool has_local = false; | ||||
|     SocketAddress *addr; | ||||
|     ChardevUdp *udp; | ||||
|  | ||||
|     if (host == NULL || strlen(host) == 0) { | ||||
|         host = "localhost"; | ||||
| @@ -3696,28 +3709,32 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend, | ||||
|         has_local = true; | ||||
|     } | ||||
|  | ||||
|     backend->u.udp = g_new0(ChardevUdp, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevUdp_base(backend->u.udp)); | ||||
|     udp = backend->u.udp = g_new0(ChardevUdp, 1); | ||||
|     qemu_chr_parse_common(opts, qapi_ChardevUdp_base(udp)); | ||||
|  | ||||
|     addr = g_new0(SocketAddress, 1); | ||||
|     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; | ||||
|     addr->u.inet = g_new(InetSocketAddress, 1); | ||||
|     *addr->u.inet = (InetSocketAddress) { | ||||
|         .host = g_strdup(host), | ||||
|         .port = g_strdup(port), | ||||
|         .has_ipv4 = qemu_opt_get(opts, "ipv4"), | ||||
|         .ipv4 = qemu_opt_get_bool(opts, "ipv4", 0), | ||||
|         .has_ipv6 = qemu_opt_get(opts, "ipv6"), | ||||
|         .ipv6 = qemu_opt_get_bool(opts, "ipv6", 0), | ||||
|     }; | ||||
|     udp->remote = addr; | ||||
|  | ||||
|     if (has_local) { | ||||
|         backend->u.udp->has_local = true; | ||||
|         udp->has_local = true; | ||||
|         addr = g_new0(SocketAddress, 1); | ||||
|         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; | ||||
|         addr->u.inet = g_new(InetSocketAddress, 1); | ||||
|         *addr->u.inet = (InetSocketAddress) { | ||||
|             .host = g_strdup(localaddr), | ||||
|             .port = g_strdup(localport), | ||||
|         }; | ||||
|         udp->local = addr; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -3800,7 +3817,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts, | ||||
|     } else { | ||||
|         ChardevCommon *cc = g_new0(ChardevCommon, 1); | ||||
|         qemu_chr_parse_common(opts, cc); | ||||
|         backend->u.data = cc; | ||||
|         backend->u.null = cc; /* Any ChardevCommon member would work */ | ||||
|     } | ||||
|  | ||||
|     ret = qmp_chardev_add(bid ? bid : id, backend, errp); | ||||
| @@ -4128,7 +4145,7 @@ static CharDriverState *qmp_chardev_open_file(const char *id, | ||||
|                                               Error **errp) | ||||
| { | ||||
|     ChardevFile *file = backend->u.file; | ||||
|     ChardevCommon *common = qapi_ChardevFile_base(backend->u.file); | ||||
|     ChardevCommon *common = qapi_ChardevFile_base(file); | ||||
|     HANDLE out; | ||||
|  | ||||
|     if (file->has_in) { | ||||
| @@ -4151,7 +4168,7 @@ static CharDriverState *qmp_chardev_open_serial(const char *id, | ||||
|                                                 Error **errp) | ||||
| { | ||||
|     ChardevHostdev *serial = backend->u.serial; | ||||
|     ChardevCommon *common = qapi_ChardevHostdev_base(backend->u.serial); | ||||
|     ChardevCommon *common = qapi_ChardevHostdev_base(serial); | ||||
|     return qemu_chr_open_win_path(serial->device, common, errp); | ||||
| } | ||||
|  | ||||
| @@ -4175,7 +4192,7 @@ static CharDriverState *qmp_chardev_open_file(const char *id, | ||||
|                                               Error **errp) | ||||
| { | ||||
|     ChardevFile *file = backend->u.file; | ||||
|     ChardevCommon *common = qapi_ChardevFile_base(backend->u.file); | ||||
|     ChardevCommon *common = qapi_ChardevFile_base(file); | ||||
|     int flags, in = -1, out; | ||||
|  | ||||
|     flags = O_WRONLY | O_CREAT | O_BINARY; | ||||
| @@ -4209,7 +4226,7 @@ static CharDriverState *qmp_chardev_open_serial(const char *id, | ||||
|                                                 Error **errp) | ||||
| { | ||||
|     ChardevHostdev *serial = backend->u.serial; | ||||
|     ChardevCommon *common = qapi_ChardevHostdev_base(backend->u.serial); | ||||
|     ChardevCommon *common = qapi_ChardevHostdev_base(serial); | ||||
|     int fd; | ||||
|  | ||||
|     fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); | ||||
| @@ -4228,7 +4245,7 @@ static CharDriverState *qmp_chardev_open_parallel(const char *id, | ||||
|                                                   Error **errp) | ||||
| { | ||||
|     ChardevHostdev *parallel = backend->u.parallel; | ||||
|     ChardevCommon *common = qapi_ChardevHostdev_base(backend->u.parallel); | ||||
|     ChardevCommon *common = qapi_ChardevHostdev_base(parallel); | ||||
|     int fd; | ||||
|  | ||||
|     fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp); | ||||
| @@ -4280,7 +4297,7 @@ static CharDriverState *qmp_chardev_open_socket(const char *id, | ||||
|     bool is_telnet      = sock->has_telnet  ? sock->telnet  : false; | ||||
|     bool is_waitconnect = sock->has_wait    ? sock->wait    : false; | ||||
|     int64_t reconnect   = sock->has_reconnect ? sock->reconnect : 0; | ||||
|     ChardevCommon *common = qapi_ChardevSocket_base(backend->u.socket); | ||||
|     ChardevCommon *common = qapi_ChardevSocket_base(sock); | ||||
|  | ||||
|     chr = qemu_chr_alloc(common, errp); | ||||
|     if (!chr) { | ||||
| @@ -4380,7 +4397,7 @@ static CharDriverState *qmp_chardev_open_udp(const char *id, | ||||
|                                              Error **errp) | ||||
| { | ||||
|     ChardevUdp *udp = backend->u.udp; | ||||
|     ChardevCommon *common = qapi_ChardevUdp_base(backend->u.udp); | ||||
|     ChardevCommon *common = qapi_ChardevUdp_base(udp); | ||||
|     QIOChannelSocket *sioc = qio_channel_socket_new(); | ||||
|  | ||||
|     if (qio_channel_socket_dgram_sync(sioc, | ||||
|   | ||||
| @@ -380,13 +380,14 @@ static SocketAddress *nbd_build_socket_address(const char *sockpath, | ||||
|         saddr->u.q_unix = g_new0(UnixSocketAddress, 1); | ||||
|         saddr->u.q_unix->path = g_strdup(sockpath); | ||||
|     } else { | ||||
|         InetSocketAddress *inet; | ||||
|         saddr->type = SOCKET_ADDRESS_KIND_INET; | ||||
|         saddr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|         saddr->u.inet->host = g_strdup(bindto); | ||||
|         inet = saddr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|         inet->host = g_strdup(bindto); | ||||
|         if (port) { | ||||
|             saddr->u.inet->port = g_strdup(port); | ||||
|             inet->port = g_strdup(port); | ||||
|         } else  { | ||||
|             saddr->u.inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT); | ||||
|             inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -47,20 +47,24 @@ static InputEvent *qapi_clone_InputEvent(InputEvent *src) | ||||
|  | ||||
| void replay_save_input_event(InputEvent *evt) | ||||
| { | ||||
|     InputKeyEvent *key; | ||||
|     InputBtnEvent *btn; | ||||
|     InputMoveEvent *move; | ||||
|     replay_put_dword(evt->type); | ||||
|  | ||||
|     switch (evt->type) { | ||||
|     case INPUT_EVENT_KIND_KEY: | ||||
|         replay_put_dword(evt->u.key->key->type); | ||||
|         key = evt->u.key; | ||||
|         replay_put_dword(key->key->type); | ||||
|  | ||||
|         switch (evt->u.key->key->type) { | ||||
|         switch (key->key->type) { | ||||
|         case KEY_VALUE_KIND_NUMBER: | ||||
|             replay_put_qword(evt->u.key->key->u.number); | ||||
|             replay_put_byte(evt->u.key->down); | ||||
|             replay_put_qword(key->key->u.number); | ||||
|             replay_put_byte(key->down); | ||||
|             break; | ||||
|         case KEY_VALUE_KIND_QCODE: | ||||
|             replay_put_dword(evt->u.key->key->u.qcode); | ||||
|             replay_put_byte(evt->u.key->down); | ||||
|             replay_put_dword(key->key->u.qcode); | ||||
|             replay_put_byte(key->down); | ||||
|             break; | ||||
|         case KEY_VALUE_KIND__MAX: | ||||
|             /* keep gcc happy */ | ||||
| @@ -68,16 +72,19 @@ void replay_save_input_event(InputEvent *evt) | ||||
|         } | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND_BTN: | ||||
|         replay_put_dword(evt->u.btn->button); | ||||
|         replay_put_byte(evt->u.btn->down); | ||||
|         btn = evt->u.btn; | ||||
|         replay_put_dword(btn->button); | ||||
|         replay_put_byte(btn->down); | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND_REL: | ||||
|         replay_put_dword(evt->u.rel->axis); | ||||
|         replay_put_qword(evt->u.rel->value); | ||||
|         move = evt->u.rel; | ||||
|         replay_put_dword(move->axis); | ||||
|         replay_put_qword(move->value); | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND_ABS: | ||||
|         replay_put_dword(evt->u.abs->axis); | ||||
|         replay_put_qword(evt->u.abs->value); | ||||
|         move = evt->u.abs; | ||||
|         replay_put_dword(move->axis); | ||||
|         replay_put_qword(move->value); | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND__MAX: | ||||
|         /* keep gcc happy */ | ||||
|   | ||||
| @@ -111,7 +111,7 @@ def gen_marshal_input_visit(arg_type, dealloc=False): | ||||
|     v = qmp_input_get_visitor(qiv); | ||||
| ''') | ||||
|  | ||||
|     ret += gen_visit_fields(arg_type.members, skiperr=dealloc) | ||||
|     ret += gen_visit_members(arg_type.members, skiperr=dealloc) | ||||
|  | ||||
|     if dealloc: | ||||
|         ret += mcgen(''' | ||||
| @@ -175,7 +175,7 @@ def gen_marshal(name, arg_type, ret_type): | ||||
|     ret += gen_marshal_input_visit(arg_type) | ||||
|     ret += gen_call(name, arg_type, ret_type) | ||||
|  | ||||
|     # 'goto out' produced by gen_marshal_input_visit->gen_visit_fields() | ||||
|     # 'goto out' produced by gen_marshal_input_visit->gen_visit_members() | ||||
|     # for each arg_type member, and by gen_call() for ret_type | ||||
|     if (arg_type and arg_type.members) or ret_type: | ||||
|         ret += mcgen(''' | ||||
|   | ||||
| @@ -67,8 +67,8 @@ def gen_event_send(name, arg_type): | ||||
| ''', | ||||
|                      name=name) | ||||
|         ret += gen_err_check() | ||||
|         ret += gen_visit_fields(arg_type.members, need_cast=True, | ||||
|                                 label='out_obj') | ||||
|         ret += gen_visit_members(arg_type.members, need_cast=True, | ||||
|                                  label='out_obj') | ||||
|         ret += mcgen(''' | ||||
| out_obj: | ||||
|     visit_end_struct(v, err ? NULL : &err); | ||||
|   | ||||
| @@ -38,7 +38,7 @@ struct %(c_name)s { | ||||
|                  c_name=c_name(name), c_type=element_type.c_type()) | ||||
|  | ||||
|  | ||||
| def gen_struct_fields(members): | ||||
| def gen_struct_members(members): | ||||
|     ret = '' | ||||
|     for memb in members: | ||||
|         if memb.optional: | ||||
| @@ -77,22 +77,22 @@ struct %(c_name)s { | ||||
|     /* Members inherited from %(c_name)s: */ | ||||
| ''', | ||||
|                      c_name=base.c_name()) | ||||
|         ret += gen_struct_fields(base.members) | ||||
|         ret += gen_struct_members(base.members) | ||||
|         ret += mcgen(''' | ||||
|     /* Own members: */ | ||||
| ''') | ||||
|     ret += gen_struct_fields(members) | ||||
|     ret += gen_struct_members(members) | ||||
|  | ||||
|     if variants: | ||||
|         ret += gen_variants(variants) | ||||
|  | ||||
|     # Make sure that all structs have at least one field; this avoids | ||||
|     # Make sure that all structs have at least one member; 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 base.members) and not members and not variants: | ||||
|         ret += mcgen(''' | ||||
|     char qapi_dummy_field_for_empty_struct; | ||||
|     char qapi_dummy_for_empty_struct; | ||||
| ''') | ||||
|  | ||||
|     ret += mcgen(''' | ||||
| @@ -116,17 +116,8 @@ static inline %(base)s *qapi_%(c_name)s_base(const %(c_name)s *obj) | ||||
|  | ||||
|  | ||||
| def gen_variants(variants): | ||||
|     # 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 | ||||
|     # whether to bypass the switch statement if visiting the discriminator | ||||
|     # failed; but since we 0-initialize structs, and cannot tell what | ||||
|     # branch of the union is in use if the discriminator is invalid, there | ||||
|     # should not be any data leaks even without a data pointer.  Or, if | ||||
|     # 'data' is merely added to guarantee we don't have an empty union, | ||||
|     # shouldn't we enforce that at .json parse time? | ||||
|     ret = mcgen(''' | ||||
|     union { /* union tag is @%(c_name)s */ | ||||
|         void *data; | ||||
| ''', | ||||
|                 c_name=c_name(variants.tag_member.name)) | ||||
|  | ||||
|   | ||||
| @@ -15,10 +15,6 @@ | ||||
| from qapi import * | ||||
| import re | ||||
|  | ||||
| # visit_type_FOO_fields() is always emitted; track if a forward declaration | ||||
| # or implementation has already been output. | ||||
| struct_fields_seen = set() | ||||
|  | ||||
|  | ||||
| def gen_visit_decl(name, scalar=False): | ||||
|     c_type = c_name(name) + ' *' | ||||
| @@ -30,46 +26,32 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_type)sobj, Error ** | ||||
|                  c_name=c_name(name), c_type=c_type) | ||||
|  | ||||
|  | ||||
| def gen_visit_fields_decl(typ): | ||||
|     if typ.name in struct_fields_seen: | ||||
|         return '' | ||||
|     struct_fields_seen.add(typ.name) | ||||
| def gen_visit_members_decl(name): | ||||
|     return mcgen(''' | ||||
|  | ||||
| static void visit_type_%(c_type)s_fields(Visitor *v, %(c_type)s *obj, Error **errp); | ||||
| void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp); | ||||
| ''', | ||||
|                  c_type=typ.c_name()) | ||||
|                  c_name=c_name(name)) | ||||
|  | ||||
|  | ||||
| def gen_visit_struct_fields(name, base, members, variants): | ||||
|     ret = '' | ||||
| def gen_visit_object_members(name, base, members, variants): | ||||
|     ret = mcgen(''' | ||||
|  | ||||
|     if base: | ||||
|         ret += gen_visit_fields_decl(base) | ||||
|     if variants: | ||||
|         for var in variants.variants: | ||||
|             # Ugly special case for simple union TODO get rid of it | ||||
|             if not var.simple_union_type(): | ||||
|                 ret += gen_visit_fields_decl(var.type) | ||||
|  | ||||
|     struct_fields_seen.add(name) | ||||
|     ret += mcgen(''' | ||||
|  | ||||
| static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s *obj, Error **errp) | ||||
| void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) | ||||
| { | ||||
|     Error *err = NULL; | ||||
|  | ||||
| ''', | ||||
|                  c_name=c_name(name)) | ||||
|                 c_name=c_name(name)) | ||||
|  | ||||
|     if base: | ||||
|         ret += mcgen(''' | ||||
|     visit_type_%(c_type)s_fields(v, (%(c_type)s *)obj, &err); | ||||
|     visit_type_%(c_type)s_members(v, (%(c_type)s *)obj, &err); | ||||
| ''', | ||||
|                      c_type=base.c_name()) | ||||
|         ret += gen_err_check() | ||||
|  | ||||
|     ret += gen_visit_fields(members, prefix='obj->') | ||||
|     ret += gen_visit_members(members, prefix='obj->') | ||||
|  | ||||
|     if variants: | ||||
|         ret += mcgen(''' | ||||
| @@ -94,7 +76,7 @@ static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s *obj, Error **er | ||||
|                              c_name=c_name(var.name)) | ||||
|             else: | ||||
|                 ret += mcgen(''' | ||||
|         visit_type_%(c_type)s_fields(v, &obj->u.%(c_name)s, &err); | ||||
|         visit_type_%(c_type)s_members(v, &obj->u.%(c_name)s, &err); | ||||
| ''', | ||||
|                              c_type=var.type.c_name(), | ||||
|                              c_name=c_name(var.name)) | ||||
| @@ -108,7 +90,7 @@ static void visit_type_%(c_name)s_fields(Visitor *v, %(c_name)s *obj, Error **er | ||||
|     } | ||||
| ''') | ||||
|  | ||||
|     # 'goto out' produced for base, by gen_visit_fields() for each member, | ||||
|     # 'goto out' produced for base, by gen_visit_members() for each member, | ||||
|     # and if variants were present | ||||
|     if base or members or variants: | ||||
|         ret += mcgen(''' | ||||
| @@ -173,8 +155,6 @@ def gen_visit_alternate(name, variants): | ||||
|     for var in variants.variants: | ||||
|         if var.type.alternate_qtype() == 'QTYPE_QINT': | ||||
|             promote_int = 'false' | ||||
|         if isinstance(var.type, QAPISchemaObjectType): | ||||
|             ret += gen_visit_fields_decl(var.type) | ||||
|  | ||||
|     ret += mcgen(''' | ||||
|  | ||||
| @@ -202,7 +182,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error | ||||
|         if (err) { | ||||
|             break; | ||||
|         } | ||||
|         visit_type_%(c_type)s_fields(v, &(*obj)->u.%(c_name)s, &err); | ||||
|         visit_type_%(c_type)s_members(v, &(*obj)->u.%(c_name)s, &err); | ||||
|         error_propagate(errp, err); | ||||
|         err = NULL; | ||||
|         visit_end_struct(v, &err); | ||||
| @@ -235,10 +215,10 @@ out: | ||||
|  | ||||
|  | ||||
| def gen_visit_object(name, base, members, variants): | ||||
|     ret = gen_visit_struct_fields(name, base, members, variants) | ||||
|     ret = gen_visit_object_members(name, base, members, variants) | ||||
|  | ||||
|     # FIXME: if *obj is NULL on entry, and visit_start_struct() assigns to | ||||
|     # *obj, but then visit_type_FOO_fields() fails, we should clean up *obj | ||||
|     # *obj, but then visit_type_FOO_members() fails, we should clean up *obj | ||||
|     # rather than leaving it non-NULL. As currently written, the caller must | ||||
|     # call qapi_free_FOO() to avoid a memory leak of the partial FOO. | ||||
|     ret += mcgen(''' | ||||
| @@ -254,7 +234,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error | ||||
|     if (!*obj) { | ||||
|         goto out_obj; | ||||
|     } | ||||
|     visit_type_%(c_name)s_fields(v, *obj, &err); | ||||
|     visit_type_%(c_name)s_members(v, *obj, &err); | ||||
|     error_propagate(errp, err); | ||||
|     err = NULL; | ||||
| out_obj: | ||||
| @@ -316,6 +296,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor): | ||||
|             self.defn += defn | ||||
|  | ||||
|     def visit_object_type(self, name, info, base, members, variants): | ||||
|         self.decl += gen_visit_members_decl(name) | ||||
|         self.decl += gen_visit_decl(name) | ||||
|         self.defn += gen_visit_object(name, base, members, variants) | ||||
|  | ||||
|   | ||||
| @@ -326,7 +326,7 @@ class QAPISchemaParser(object): | ||||
| # | ||||
|  | ||||
|  | ||||
| def find_base_fields(base): | ||||
| def find_base_members(base): | ||||
|     base_struct_define = find_struct(base) | ||||
|     if not base_struct_define: | ||||
|         return None | ||||
| @@ -355,11 +355,11 @@ def discriminator_find_enum_define(expr): | ||||
|     if not (discriminator and base): | ||||
|         return None | ||||
|  | ||||
|     base_fields = find_base_fields(base) | ||||
|     if not base_fields: | ||||
|     base_members = find_base_members(base) | ||||
|     if not base_members: | ||||
|         return None | ||||
|  | ||||
|     discriminator_type = base_fields.get(discriminator) | ||||
|     discriminator_type = base_members.get(discriminator) | ||||
|     if not discriminator_type: | ||||
|         return None | ||||
|  | ||||
| @@ -567,14 +567,14 @@ def check_union(expr, expr_info): | ||||
|             raise QAPIExprError(expr_info, | ||||
|                                 "Flat union '%s' must have a base" | ||||
|                                 % name) | ||||
|         base_fields = find_base_fields(base) | ||||
|         assert base_fields | ||||
|         base_members = find_base_members(base) | ||||
|         assert base_members | ||||
|  | ||||
|         # The value of member 'discriminator' must name a non-optional | ||||
|         # member of the base struct. | ||||
|         check_name(expr_info, "Discriminator of flat union '%s'" % name, | ||||
|                    discriminator) | ||||
|         discriminator_type = base_fields.get(discriminator) | ||||
|         discriminator_type = base_members.get(discriminator) | ||||
|         if not discriminator_type: | ||||
|             raise QAPIExprError(expr_info, | ||||
|                                 "Discriminator '%s' is not a member of base " | ||||
| @@ -969,7 +969,7 @@ class QAPISchemaObjectType(QAPISchemaType): | ||||
|             assert self.variants.tag_member in self.members | ||||
|             self.variants.check_clash(schema, self.info, seen) | ||||
|  | ||||
|     # Check that the members of this type do not cause duplicate JSON fields, | ||||
|     # Check that the members of this type do not cause duplicate JSON members, | ||||
|     # and update seen to track the members seen so far. Report any errors | ||||
|     # on behalf of info, which is not necessarily self.info | ||||
|     def check_clash(self, schema, info, seen): | ||||
| @@ -1647,8 +1647,8 @@ def gen_err_check(label='out', skiperr=False): | ||||
|                  label=label) | ||||
|  | ||||
|  | ||||
| def gen_visit_fields(members, prefix='', need_cast=False, skiperr=False, | ||||
|                      label='out'): | ||||
| def gen_visit_members(members, prefix='', need_cast=False, skiperr=False, | ||||
|                       label='out'): | ||||
|     ret = '' | ||||
|     if skiperr: | ||||
|         errparg = 'NULL' | ||||
|   | ||||
| @@ -70,7 +70,6 @@ import json | ||||
| import ast | ||||
| import readline | ||||
| import sys | ||||
| import pprint | ||||
|  | ||||
| class QMPCompleter(list): | ||||
|     def complete(self, text, state): | ||||
| @@ -103,11 +102,11 @@ class FuzzyJSON(ast.NodeTransformer): | ||||
| # TODO: QMPShell's interface is a bit ugly (eg. _fill_completion() and | ||||
| #       _execute_cmd()). Let's design a better one. | ||||
| class QMPShell(qmp.QEMUMonitorProtocol): | ||||
|     def __init__(self, address, pp=None): | ||||
|     def __init__(self, address, pretty=False): | ||||
|         qmp.QEMUMonitorProtocol.__init__(self, self.__get_address(address)) | ||||
|         self._greeting = None | ||||
|         self._completer = None | ||||
|         self._pp = pp | ||||
|         self._pretty = pretty | ||||
|         self._transmode = False | ||||
|         self._actions = list() | ||||
|  | ||||
| @@ -231,11 +230,11 @@ class QMPShell(qmp.QEMUMonitorProtocol): | ||||
|         return qmpcmd | ||||
|  | ||||
|     def _print(self, qmp): | ||||
|         jsobj = json.dumps(qmp) | ||||
|         if self._pp is not None: | ||||
|             self._pp.pprint(jsobj) | ||||
|         else: | ||||
|             print str(jsobj) | ||||
|         indent = None | ||||
|         if self._pretty: | ||||
|             indent = 4 | ||||
|         jsobj = json.dumps(qmp, indent=indent) | ||||
|         print str(jsobj) | ||||
|  | ||||
|     def _execute_cmd(self, cmdline): | ||||
|         try: | ||||
| @@ -377,7 +376,7 @@ def main(): | ||||
|     addr = '' | ||||
|     qemu = None | ||||
|     hmp = False | ||||
|     pp = None | ||||
|     pretty = False | ||||
|     verbose = False | ||||
|  | ||||
|     try: | ||||
| @@ -387,9 +386,7 @@ def main(): | ||||
|                     fail_cmdline(arg) | ||||
|                 hmp = True | ||||
|             elif arg == "-p": | ||||
|                 if pp is not None: | ||||
|                     fail_cmdline(arg) | ||||
|                 pp = pprint.PrettyPrinter(indent=4) | ||||
|                 pretty = True | ||||
|             elif arg == "-v": | ||||
|                 verbose = True | ||||
|             else: | ||||
| @@ -398,7 +395,7 @@ def main(): | ||||
|                 if hmp: | ||||
|                     qemu = HMPShell(arg) | ||||
|                 else: | ||||
|                     qemu = QMPShell(arg, pp) | ||||
|                     qemu = QMPShell(arg, pretty) | ||||
|                 addr = arg | ||||
|  | ||||
|         if qemu is None: | ||||
|   | ||||
| @@ -358,7 +358,6 @@ qapi-schema += unicode-str.json | ||||
| qapi-schema += union-base-no-discriminator.json | ||||
| qapi-schema += union-branch-case.json | ||||
| qapi-schema += union-clash-branches.json | ||||
| qapi-schema += union-clash-data.json | ||||
| qapi-schema += union-empty.json | ||||
| qapi-schema += union-invalid-base.json | ||||
| qapi-schema += union-optional-branch.json | ||||
|   | ||||
| @@ -77,7 +77,7 @@ | ||||
|   'base': 'UserDefZero', | ||||
|   'data': { 'string': 'str', 'enum1': 'QEnumTwo' } } | ||||
|  | ||||
| # this variant of UserDefFlatUnion defaults to a union that uses fields with | ||||
| # this variant of UserDefFlatUnion defaults to a union that uses members with | ||||
| # allocated types to test corner cases in the cleanup/dealloc visitor | ||||
| { 'union': 'UserDefFlatUnion2', | ||||
|   'base': 'UserDefUnionBase2', | ||||
|   | ||||
| @@ -1 +0,0 @@ | ||||
| 0 | ||||
| @@ -1,7 +0,0 @@ | ||||
| # Union branch 'data' | ||||
| # FIXME: this parses, but then fails to compile due to a duplicate 'data' | ||||
| # (one from the branch name, another as a filler to avoid an empty union). | ||||
| # we should either detect the collision at parse time, or change the | ||||
| # generated struct to allow this to compile. | ||||
| { 'union': 'TestUnion', | ||||
|   'data': { 'data': 'int' } } | ||||
| @@ -1,9 +0,0 @@ | ||||
| object :empty | ||||
| object :obj-int-wrapper | ||||
|     member data: int optional=False | ||||
| enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] | ||||
|     prefix QTYPE | ||||
| object TestUnion | ||||
|     member type: TestUnionKind optional=False | ||||
|     case data: :obj-int-wrapper | ||||
| enum TestUnionKind ['data'] | ||||
| @@ -1,7 +1,7 @@ | ||||
| /* | ||||
|  * QEMU I/O channel sockets test | ||||
|  * | ||||
|  * Copyright (c) 2015 Red Hat, Inc. | ||||
|  * Copyright (c) 2015-2016 Red Hat, Inc. | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
| @@ -283,14 +283,18 @@ static void test_io_channel_ipv4(bool async) | ||||
|     SocketAddress *connect_addr = g_new0(SocketAddress, 1); | ||||
|  | ||||
|     listen_addr->type = SOCKET_ADDRESS_KIND_INET; | ||||
|     listen_addr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|     listen_addr->u.inet->host = g_strdup("127.0.0.1"); | ||||
|     listen_addr->u.inet->port = NULL; /* Auto-select */ | ||||
|     listen_addr->u.inet = g_new(InetSocketAddress, 1); | ||||
|     *listen_addr->u.inet = (InetSocketAddress) { | ||||
|         .host = g_strdup("127.0.0.1"), | ||||
|         .port = NULL, /* Auto-select */ | ||||
|     }; | ||||
|  | ||||
|     connect_addr->type = SOCKET_ADDRESS_KIND_INET; | ||||
|     connect_addr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|     connect_addr->u.inet->host = g_strdup("127.0.0.1"); | ||||
|     connect_addr->u.inet->port = NULL; /* Filled in later */ | ||||
|     connect_addr->u.inet = g_new(InetSocketAddress, 1); | ||||
|     *connect_addr->u.inet = (InetSocketAddress) { | ||||
|         .host = g_strdup("127.0.0.1"), | ||||
|         .port = NULL, /* Filled in later */ | ||||
|     }; | ||||
|  | ||||
|     test_io_channel(async, listen_addr, connect_addr, false); | ||||
|  | ||||
| @@ -317,14 +321,18 @@ static void test_io_channel_ipv6(bool async) | ||||
|     SocketAddress *connect_addr = g_new0(SocketAddress, 1); | ||||
|  | ||||
|     listen_addr->type = SOCKET_ADDRESS_KIND_INET; | ||||
|     listen_addr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|     listen_addr->u.inet->host = g_strdup("::1"); | ||||
|     listen_addr->u.inet->port = NULL; /* Auto-select */ | ||||
|     listen_addr->u.inet = g_new(InetSocketAddress, 1); | ||||
|     *listen_addr->u.inet = (InetSocketAddress) { | ||||
|         .host = g_strdup("::1"), | ||||
|         .port = NULL, /* Auto-select */ | ||||
|     }; | ||||
|  | ||||
|     connect_addr->type = SOCKET_ADDRESS_KIND_INET; | ||||
|     connect_addr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|     connect_addr->u.inet->host = g_strdup("::1"); | ||||
|     connect_addr->u.inet->port = NULL; /* Filled in later */ | ||||
|     connect_addr->u.inet = g_new(InetSocketAddress, 1); | ||||
|     *connect_addr->u.inet = (InetSocketAddress) { | ||||
|         .host = g_strdup("::1"), | ||||
|         .port = NULL, /* Filled in later */ | ||||
|     }; | ||||
|  | ||||
|     test_io_channel(async, listen_addr, connect_addr, false); | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,6 @@ | ||||
| #include "qemu/option.h"          /* qemu_opts_parse() */ | ||||
| #include "qapi/opts-visitor.h"    /* opts_visitor_new() */ | ||||
| #include "test-qapi-visit.h"      /* visit_type_UserDefOptions() */ | ||||
| #include "qapi/dealloc-visitor.h" /* qapi_dealloc_visitor_new() */ | ||||
|  | ||||
| static QemuOptsList userdef_opts = { | ||||
|     .name = "userdef", | ||||
| @@ -55,14 +54,7 @@ setup_fixture(OptsVisitorFixture *f, gconstpointer test_data) | ||||
| static void | ||||
| teardown_fixture(OptsVisitorFixture *f, gconstpointer test_data) | ||||
| { | ||||
|     if (f->userdef != NULL) { | ||||
|         QapiDeallocVisitor *dv; | ||||
|  | ||||
|         dv = qapi_dealloc_visitor_new(); | ||||
|         visit_type_UserDefOptions(qapi_dealloc_get_visitor(dv), NULL, | ||||
|                                   &f->userdef, NULL); | ||||
|         qapi_dealloc_visitor_cleanup(dv); | ||||
|     } | ||||
|     qapi_free_UserDefOptions(f->userdef); | ||||
|     error_free(f->err); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -110,12 +110,13 @@ static void legacy_kbd_event(DeviceState *dev, QemuConsole *src, | ||||
| { | ||||
|     QEMUPutKbdEntry *entry = (QEMUPutKbdEntry *)dev; | ||||
|     int scancodes[3], i, count; | ||||
|     InputKeyEvent *key = evt->u.key; | ||||
|  | ||||
|     if (!entry || !entry->put_kbd) { | ||||
|         return; | ||||
|     } | ||||
|     count = qemu_input_key_value_to_scancode(evt->u.key->key, | ||||
|                                              evt->u.key->down, | ||||
|     count = qemu_input_key_value_to_scancode(key->key, | ||||
|                                              key->down, | ||||
|                                              scancodes); | ||||
|     for (i = 0; i < count; i++) { | ||||
|         entry->put_kbd(entry->opaque, scancodes[i]); | ||||
| @@ -150,23 +151,25 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, | ||||
|         [INPUT_BUTTON_RIGHT]  = MOUSE_EVENT_RBUTTON, | ||||
|     }; | ||||
|     QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev; | ||||
|     InputBtnEvent *btn; | ||||
|     InputMoveEvent *move; | ||||
|  | ||||
|     switch (evt->type) { | ||||
|     case INPUT_EVENT_KIND_BTN: | ||||
|         if (evt->u.btn->down) { | ||||
|             s->buttons |= bmap[evt->u.btn->button]; | ||||
|         btn = evt->u.btn; | ||||
|         if (btn->down) { | ||||
|             s->buttons |= bmap[btn->button]; | ||||
|         } else { | ||||
|             s->buttons &= ~bmap[evt->u.btn->button]; | ||||
|             s->buttons &= ~bmap[btn->button]; | ||||
|         } | ||||
|         if (evt->u.btn->down && evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) { | ||||
|         if (btn->down && 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->u.btn->down && | ||||
|             evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) { | ||||
|         if (btn->down && 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], | ||||
| @@ -175,10 +178,12 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, | ||||
|         } | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND_ABS: | ||||
|         s->axis[evt->u.abs->axis] = evt->u.abs->value; | ||||
|         move = evt->u.abs; | ||||
|         s->axis[move->axis] = move->value; | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND_REL: | ||||
|         s->axis[evt->u.rel->axis] += evt->u.rel->value; | ||||
|         move = evt->u.rel; | ||||
|         s->axis[move->axis] += move->value; | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|   | ||||
							
								
								
									
										56
									
								
								ui/input.c
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								ui/input.c
									
									
									
									
									
								
							| @@ -166,24 +166,25 @@ void qmp_input_send_event(bool has_device, const char *device, | ||||
|  | ||||
| static void qemu_input_transform_abs_rotate(InputEvent *evt) | ||||
| { | ||||
|     InputMoveEvent *move = evt->u.abs; | ||||
|     switch (graphic_rotate) { | ||||
|     case 90: | ||||
|         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; | ||||
|         if (move->axis == INPUT_AXIS_X) { | ||||
|             move->axis = INPUT_AXIS_Y; | ||||
|         } else if (move->axis == INPUT_AXIS_Y) { | ||||
|             move->axis = INPUT_AXIS_X; | ||||
|             move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value; | ||||
|         } | ||||
|         break; | ||||
|     case 180: | ||||
|         evt->u.abs->value = INPUT_EVENT_ABS_SIZE - 1 - evt->u.abs->value; | ||||
|         move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value; | ||||
|         break; | ||||
|     case 270: | ||||
|         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; | ||||
|         if (move->axis == INPUT_AXIS_X) { | ||||
|             move->axis = INPUT_AXIS_Y; | ||||
|             move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value; | ||||
|         } else if (move->axis == INPUT_AXIS_Y) { | ||||
|             move->axis = INPUT_AXIS_X; | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
| @@ -193,22 +194,26 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt) | ||||
| { | ||||
|     const char *name; | ||||
|     int qcode, idx = -1; | ||||
|     InputKeyEvent *key; | ||||
|     InputBtnEvent *btn; | ||||
|     InputMoveEvent *move; | ||||
|  | ||||
|     if (src) { | ||||
|         idx = qemu_console_get_index(src); | ||||
|     } | ||||
|     switch (evt->type) { | ||||
|     case INPUT_EVENT_KIND_KEY: | ||||
|         switch (evt->u.key->key->type) { | ||||
|         key = evt->u.key; | ||||
|         switch (key->key->type) { | ||||
|         case KEY_VALUE_KIND_NUMBER: | ||||
|             qcode = qemu_input_key_number_to_qcode(evt->u.key->key->u.number); | ||||
|             qcode = qemu_input_key_number_to_qcode(key->key->u.number); | ||||
|             name = QKeyCode_lookup[qcode]; | ||||
|             trace_input_event_key_number(idx, evt->u.key->key->u.number, | ||||
|                                          name, evt->u.key->down); | ||||
|             trace_input_event_key_number(idx, key->key->u.number, | ||||
|                                          name, key->down); | ||||
|             break; | ||||
|         case KEY_VALUE_KIND_QCODE: | ||||
|             name = QKeyCode_lookup[evt->u.key->key->u.qcode]; | ||||
|             trace_input_event_key_qcode(idx, name, evt->u.key->down); | ||||
|             name = QKeyCode_lookup[key->key->u.qcode]; | ||||
|             trace_input_event_key_qcode(idx, name, key->down); | ||||
|             break; | ||||
|         case KEY_VALUE_KIND__MAX: | ||||
|             /* keep gcc happy */ | ||||
| @@ -216,16 +221,19 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt) | ||||
|         } | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND_BTN: | ||||
|         name = InputButton_lookup[evt->u.btn->button]; | ||||
|         trace_input_event_btn(idx, name, evt->u.btn->down); | ||||
|         btn = evt->u.btn; | ||||
|         name = InputButton_lookup[btn->button]; | ||||
|         trace_input_event_btn(idx, name, btn->down); | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND_REL: | ||||
|         name = InputAxis_lookup[evt->u.rel->axis]; | ||||
|         trace_input_event_rel(idx, name, evt->u.rel->value); | ||||
|         move = evt->u.rel; | ||||
|         name = InputAxis_lookup[move->axis]; | ||||
|         trace_input_event_rel(idx, name, move->value); | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND_ABS: | ||||
|         name = InputAxis_lookup[evt->u.abs->axis]; | ||||
|         trace_input_event_abs(idx, name, evt->u.abs->value); | ||||
|         move = evt->u.abs; | ||||
|         name = InputAxis_lookup[move->axis]; | ||||
|         trace_input_event_abs(idx, name, move->value); | ||||
|         break; | ||||
|     case INPUT_EVENT_KIND__MAX: | ||||
|         /* keep gcc happy */ | ||||
| @@ -462,7 +470,7 @@ InputEvent *qemu_input_event_new_move(InputEventKind kind, | ||||
|     InputMoveEvent *move = g_new0(InputMoveEvent, 1); | ||||
|  | ||||
|     evt->type = kind; | ||||
|     evt->u.data = move; | ||||
|     evt->u.rel = move; /* evt->u.rel is the same as evt->u.abs */ | ||||
|     move->axis = axis; | ||||
|     move->value = value; | ||||
|     return evt; | ||||
|   | ||||
							
								
								
									
										39
									
								
								ui/vnc.c
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								ui/vnc.c
									
									
									
									
									
								
							| @@ -3530,12 +3530,13 @@ void vnc_display_open(const char *id, Error **errp) | ||||
|             } | ||||
|         } else { | ||||
|             unsigned long long baseport; | ||||
|             InetSocketAddress *inet; | ||||
|             saddr->type = SOCKET_ADDRESS_KIND_INET; | ||||
|             saddr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|             inet = saddr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|             if (vnc[0] == '[' && vnc[hlen - 1] == ']') { | ||||
|                 saddr->u.inet->host = g_strndup(vnc + 1, hlen - 2); | ||||
|                 inet->host = g_strndup(vnc + 1, hlen - 2); | ||||
|             } else { | ||||
|                 saddr->u.inet->host = g_strndup(vnc, hlen); | ||||
|                 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); | ||||
| @@ -3546,32 +3547,32 @@ void vnc_display_open(const char *id, Error **errp) | ||||
|                 error_setg(errp, "port %s out of range", h + 1); | ||||
|                 goto fail; | ||||
|             } | ||||
|             saddr->u.inet->port = g_strdup_printf( | ||||
|             inet->port = g_strdup_printf( | ||||
|                 "%d", (int)baseport + 5900); | ||||
|  | ||||
|             if (to) { | ||||
|                 saddr->u.inet->has_to = true; | ||||
|                 saddr->u.inet->to = to + 5900; | ||||
|                 inet->has_to = true; | ||||
|                 inet->to = to + 5900; | ||||
|             } | ||||
|             saddr->u.inet->ipv4 = ipv4; | ||||
|             saddr->u.inet->has_ipv4 = has_ipv4; | ||||
|             saddr->u.inet->ipv6 = ipv6; | ||||
|             saddr->u.inet->has_ipv6 = has_ipv6; | ||||
|             inet->ipv4 = ipv4; | ||||
|             inet->has_ipv4 = has_ipv4; | ||||
|             inet->ipv6 = ipv6; | ||||
|             inet->has_ipv6 = has_ipv6; | ||||
|  | ||||
|             if (vs->ws_enabled) { | ||||
|                 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); | ||||
|                 inet = wsaddr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|                 inet->host = g_strdup(saddr->u.inet->host); | ||||
|                 inet->port = g_strdup(websocket); | ||||
|  | ||||
|                 if (to) { | ||||
|                     wsaddr->u.inet->has_to = true; | ||||
|                     wsaddr->u.inet->to = to; | ||||
|                     inet->has_to = true; | ||||
|                     inet->to = to; | ||||
|                 } | ||||
|                 wsaddr->u.inet->ipv4 = ipv4; | ||||
|                 wsaddr->u.inet->has_ipv4 = has_ipv4; | ||||
|                 wsaddr->u.inet->ipv6 = ipv6; | ||||
|                 wsaddr->u.inet->has_ipv6 = has_ipv6; | ||||
|                 inet->ipv4 = ipv4; | ||||
|                 inet->has_ipv4 = has_ipv4; | ||||
|                 inet->ipv6 = ipv6; | ||||
|                 inet->has_ipv6 = has_ipv6; | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|   | ||||
| @@ -1003,6 +1003,7 @@ socket_sockaddr_to_address_inet(struct sockaddr_storage *sa, | ||||
|     char host[NI_MAXHOST]; | ||||
|     char serv[NI_MAXSERV]; | ||||
|     SocketAddress *addr; | ||||
|     InetSocketAddress *inet; | ||||
|     int ret; | ||||
|  | ||||
|     ret = getnameinfo((struct sockaddr *)sa, salen, | ||||
| @@ -1017,13 +1018,13 @@ socket_sockaddr_to_address_inet(struct sockaddr_storage *sa, | ||||
|  | ||||
|     addr = g_new0(SocketAddress, 1); | ||||
|     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); | ||||
|     inet = addr->u.inet = g_new0(InetSocketAddress, 1); | ||||
|     inet->host = g_strdup(host); | ||||
|     inet->port = g_strdup(serv); | ||||
|     if (sa->ss_family == AF_INET) { | ||||
|         addr->u.inet->has_ipv4 = addr->u.inet->ipv4 = true; | ||||
|         inet->has_ipv4 = inet->ipv4 = true; | ||||
|     } else { | ||||
|         addr->u.inet->has_ipv6 = addr->u.inet->ipv6 = true; | ||||
|         inet->has_ipv6 = inet->ipv6 = true; | ||||
|     } | ||||
|  | ||||
|     return addr; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user