diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 0600c9a1fa..f2b77fa118 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -831,49 +831,12 @@ static const MemoryRegionOps cmos_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; -static void rtc_get_date(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) +static void rtc_get_date(Object *obj, struct tm *current_tm, Error **errp) { - Error *err = NULL; RTCState *s = MC146818_RTC(obj); - struct tm current_tm; rtc_update_time(s); - rtc_get_time(s, ¤t_tm); - visit_start_struct(v, NULL, "struct tm", name, 0, &err); - if (err) { - goto out; - } - visit_type_int32(v, ¤t_tm.tm_year, "tm_year", &err); - if (err) { - goto out_end; - } - visit_type_int32(v, ¤t_tm.tm_mon, "tm_mon", &err); - if (err) { - goto out_end; - } - visit_type_int32(v, ¤t_tm.tm_mday, "tm_mday", &err); - if (err) { - goto out_end; - } - visit_type_int32(v, ¤t_tm.tm_hour, "tm_hour", &err); - if (err) { - goto out_end; - } - visit_type_int32(v, ¤t_tm.tm_min, "tm_min", &err); - if (err) { - goto out_end; - } - visit_type_int32(v, ¤t_tm.tm_sec, "tm_sec", &err); - if (err) { - goto out_end; - } -out_end: - error_propagate(errp, err); - err = NULL; - visit_end_struct(v, errp); -out: - error_propagate(errp, err); + rtc_get_time(s, current_tm); } static void rtc_realizefn(DeviceState *dev, Error **errp) @@ -932,8 +895,7 @@ static void rtc_realizefn(DeviceState *dev, Error **errp) qdev_set_legacy_instance_id(dev, base, 3); qemu_register_reset(rtc_reset, s); - object_property_add(OBJECT(s), "date", "struct tm", - rtc_get_date, NULL, NULL, s, NULL); + object_property_add_tm(OBJECT(s), "date", rtc_get_date, NULL); object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(s), "date", NULL); diff --git a/include/qom/object.h b/include/qom/object.h index 87575735fe..d2d7748f62 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1203,6 +1203,20 @@ void object_property_add_bool(Object *obj, const char *name, void (*set)(Object *, bool, Error **), Error **errp); +/** + * object_property_add_tm: + * @obj: the object to add a property to + * @name: the name of the property + * @get: the getter or NULL if the property is write-only. + * @errp: if an error occurs, a pointer to an area to store the error + * + * Add a read-only struct tm valued property using a getter function. + * This function will add a property of type 'struct tm'. + */ +void object_property_add_tm(Object *obj, const char *name, + void (*get)(Object *, struct tm *, Error **), + Error **errp); + /** * object_property_add_uint8_ptr: * @obj: the object to add a property to diff --git a/qom/object.c b/qom/object.c index 1812c73327..d1670387b4 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1543,6 +1543,85 @@ void object_property_add_bool(Object *obj, const char *name, } } +typedef struct TMProperty { + void (*get)(Object *, struct tm *, Error **); +} TMProperty; + +static void property_get_tm(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + TMProperty *prop = opaque; + Error *err = NULL; + struct tm value; + + prop->get(obj, &value, &err); + if (err) { + goto out; + } + + visit_start_struct(v, NULL, "struct tm", name, 0, &err); + if (err) { + goto out; + } + visit_type_int32(v, &value.tm_year, "tm_year", &err); + if (err) { + goto out_end; + } + visit_type_int32(v, &value.tm_mon, "tm_mon", &err); + if (err) { + goto out_end; + } + visit_type_int32(v, &value.tm_mday, "tm_mday", &err); + if (err) { + goto out_end; + } + visit_type_int32(v, &value.tm_hour, "tm_hour", &err); + if (err) { + goto out_end; + } + visit_type_int32(v, &value.tm_min, "tm_min", &err); + if (err) { + goto out_end; + } + visit_type_int32(v, &value.tm_sec, "tm_sec", &err); + if (err) { + goto out_end; + } +out_end: + error_propagate(errp, err); + err = NULL; + visit_end_struct(v, errp); +out: + error_propagate(errp, err); + +} + +static void property_release_tm(Object *obj, const char *name, + void *opaque) +{ + TMProperty *prop = opaque; + g_free(prop); +} + +void object_property_add_tm(Object *obj, const char *name, + void (*get)(Object *, struct tm *, Error **), + Error **errp) +{ + Error *local_err = NULL; + TMProperty *prop = g_malloc0(sizeof(*prop)); + + prop->get = get; + + object_property_add(obj, name, "struct tm", + get ? property_get_tm : NULL, NULL, + property_release_tm, + prop, &local_err); + if (local_err) { + error_propagate(errp, local_err); + g_free(prop); + } +} + static char *qdev_get_type(Object *obj, Error **errp) { return g_strdup(object_get_typename(obj));