mirror of
https://github.com/AuxXxilium/eudev.git
synced 2024-12-19 13:08:42 +07:00
unit: deduce following unit value dynamically instead of statically, to avoid dangling pointers
This commit is contained in:
parent
672c48cc06
commit
a7f241db3f
@ -413,6 +413,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
|
||||
const char *description, *load_state, *active_state, *sub_state, *sjob_type, *following;
|
||||
DBusMessageIter sub2;
|
||||
uint32_t job_id;
|
||||
Unit *f;
|
||||
|
||||
if (k != u->meta.id)
|
||||
continue;
|
||||
@ -424,7 +425,9 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
|
||||
load_state = unit_load_state_to_string(u->meta.load_state);
|
||||
active_state = unit_active_state_to_string(unit_active_state(u));
|
||||
sub_state = unit_sub_state_to_string(u);
|
||||
following = u->meta.following ? u->meta.following->meta.id : "";
|
||||
|
||||
f = unit_following(u);
|
||||
following = f ? f->meta.id : "";
|
||||
|
||||
if (!(u_path = unit_dbus_path(u)))
|
||||
goto oom;
|
||||
|
@ -48,7 +48,7 @@ int bus_unit_append_names(Manager *m, DBusMessageIter *i, const char *property,
|
||||
}
|
||||
|
||||
int bus_unit_append_following(Manager *m, DBusMessageIter *i, const char *property, void *data) {
|
||||
Unit *u = data;
|
||||
Unit *u = data, *f;
|
||||
const char *d;
|
||||
|
||||
assert(m);
|
||||
@ -56,7 +56,8 @@ int bus_unit_append_following(Manager *m, DBusMessageIter *i, const char *proper
|
||||
assert(property);
|
||||
assert(u);
|
||||
|
||||
d = u->meta.following ? u->meta.following->meta.id : "";
|
||||
f = unit_following(u);
|
||||
d = f ? f->meta.id : "";
|
||||
|
||||
if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d))
|
||||
return -ENOMEM;
|
||||
|
56
src/device.c
56
src/device.c
@ -40,22 +40,21 @@ static void device_unset_sysfs(Device *d) {
|
||||
|
||||
assert(d);
|
||||
|
||||
if (d->sysfs) {
|
||||
/* Remove this unit from the chain of devices which share the
|
||||
* same sysfs path. */
|
||||
first = hashmap_get(d->meta.manager->devices_by_sysfs, d->sysfs);
|
||||
LIST_REMOVE(Device, same_sysfs, first, d);
|
||||
if (!d->sysfs)
|
||||
return;
|
||||
|
||||
if (first)
|
||||
hashmap_remove_and_replace(d->meta.manager->devices_by_sysfs, d->sysfs, first->sysfs, first);
|
||||
else
|
||||
hashmap_remove(d->meta.manager->devices_by_sysfs, d->sysfs);
|
||||
/* Remove this unit from the chain of devices which share the
|
||||
* same sysfs path. */
|
||||
first = hashmap_get(d->meta.manager->devices_by_sysfs, d->sysfs);
|
||||
LIST_REMOVE(Device, same_sysfs, first, d);
|
||||
|
||||
free(d->sysfs);
|
||||
d->sysfs = NULL;
|
||||
}
|
||||
if (first)
|
||||
hashmap_remove_and_replace(d->meta.manager->devices_by_sysfs, d->sysfs, first->sysfs, first);
|
||||
else
|
||||
hashmap_remove(d->meta.manager->devices_by_sysfs, d->sysfs);
|
||||
|
||||
d->meta.following = NULL;
|
||||
free(d->sysfs);
|
||||
d->sysfs = NULL;
|
||||
}
|
||||
|
||||
static void device_init(Unit *u) {
|
||||
@ -268,10 +267,7 @@ static int device_update_unit(Manager *m, struct udev_device *dev, const char *p
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
u->meta.following = NULL;
|
||||
} else
|
||||
device_find_escape_name(m, sysfs, &u->meta.following);
|
||||
}
|
||||
|
||||
unit_add_to_dbus_queue(u);
|
||||
return 0;
|
||||
@ -365,6 +361,30 @@ static int device_process_removed_device(Manager *m, struct udev_device *dev) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Unit *device_following(Unit *u) {
|
||||
Device *d = DEVICE(u);
|
||||
Device *other, *first = NULL;
|
||||
|
||||
assert(d);
|
||||
|
||||
if (startswith(u->meta.id, "sys-"))
|
||||
return NULL;
|
||||
|
||||
/* Make everybody follow the unit that's named after the sysfs path */
|
||||
for (other = d->same_sysfs_next; other; other = other->same_sysfs_next)
|
||||
if (startswith(other->meta.id, "sys-"))
|
||||
return UNIT(other);
|
||||
|
||||
for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) {
|
||||
if (startswith(other->meta.id, "sys-"))
|
||||
return UNIT(other);
|
||||
|
||||
first = other;
|
||||
}
|
||||
|
||||
return UNIT(first);
|
||||
}
|
||||
|
||||
static void device_shutdown(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
@ -512,6 +532,8 @@ const UnitVTable device_vtable = {
|
||||
|
||||
.bus_message_handler = bus_device_message_handler,
|
||||
|
||||
.following = device_following,
|
||||
|
||||
.enumerate = device_enumerate,
|
||||
.shutdown = device_shutdown
|
||||
};
|
||||
|
14
src/unit.c
14
src/unit.c
@ -589,6 +589,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
timestamp3[FORMAT_TIMESTAMP_MAX],
|
||||
timestamp4[FORMAT_TIMESTAMP_MAX],
|
||||
timespan[FORMAT_TIMESPAN_MAX];
|
||||
Unit *following;
|
||||
|
||||
assert(u);
|
||||
assert(u->meta.type >= 0);
|
||||
@ -625,8 +626,8 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
SET_FOREACH(t, u->meta.names, i)
|
||||
fprintf(f, "%s\tName: %s\n", prefix, t);
|
||||
|
||||
if (u->meta.following)
|
||||
fprintf(f, "%s\tFollowing: %s\n", prefix, u->meta.following->meta.id);
|
||||
if ((following = unit_following(u)))
|
||||
fprintf(f, "%s\tFollowing: %s\n", prefix, following->meta.id);
|
||||
|
||||
if (u->meta.fragment_path)
|
||||
fprintf(f, "%s\tFragment Path: %s\n", prefix, u->meta.fragment_path);
|
||||
@ -2081,6 +2082,15 @@ void unit_reset_maintenance(Unit *u) {
|
||||
UNIT_VTABLE(u)->reset_maintenance(u);
|
||||
}
|
||||
|
||||
Unit *unit_following(Unit *u) {
|
||||
assert(u);
|
||||
|
||||
if (UNIT_VTABLE(u)->following)
|
||||
return UNIT_VTABLE(u)->following(u);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
|
||||
[UNIT_SERVICE] = "service",
|
||||
[UNIT_TIMER] = "timer",
|
||||
|
@ -176,9 +176,6 @@ struct Meta {
|
||||
/* GC queue */
|
||||
LIST_FIELDS(Meta, gc_queue);
|
||||
|
||||
/* This follows another unit in state */
|
||||
Unit *following;
|
||||
|
||||
/* Used during GC sweeps */
|
||||
unsigned gc_marker;
|
||||
|
||||
@ -313,6 +310,9 @@ struct UnitVTable {
|
||||
/* Called for each message received on the bus */
|
||||
DBusHandlerResult (*bus_message_handler)(Unit *u, DBusConnection *c, DBusMessage *message);
|
||||
|
||||
/* Return the unit this unit is following */
|
||||
Unit *(*following)(Unit *u);
|
||||
|
||||
/* This is called for each unit type and should be used to
|
||||
* enumerate existing devices and load them. However,
|
||||
* everything that is loaded here should still stay in
|
||||
@ -475,6 +475,8 @@ bool unit_need_daemon_reload(Unit *u);
|
||||
|
||||
void unit_reset_maintenance(Unit *u);
|
||||
|
||||
Unit *unit_following(Unit *u);
|
||||
|
||||
const char *unit_type_to_string(UnitType i);
|
||||
UnitType unit_type_from_string(const char *s);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user