Prevent segfault in get_items()

One segfault resulted from an incorrect dbus call in sni_watcher. The
other from duplicate items in the sni host.
This commit is contained in:
Calvin Lee 2017-10-26 12:27:48 -06:00
parent 4231061e4d
commit 5bc46f458c
2 changed files with 30 additions and 18 deletions

View file

@ -389,9 +389,9 @@ static void get_property(DBusConnection *connection, DBusMessage *message) {
DBUS_TYPE_STRUCT, NULL, &dstruct); DBUS_TYPE_STRUCT, NULL, &dstruct);
dbus_message_iter_append_basic(&dstruct, dbus_message_iter_append_basic(&dstruct,
DBUS_TYPE_OBJECT_PATH, item->obj_path); DBUS_TYPE_OBJECT_PATH, &item->obj_path);
dbus_message_iter_append_basic(&dstruct, dbus_message_iter_append_basic(&dstruct,
DBUS_TYPE_STRING, item->unique_name); DBUS_TYPE_STRING, &item->unique_name);
dbus_message_iter_close_container(&array, &dstruct); dbus_message_iter_close_container(&array, &dstruct);
} }

View file

@ -75,11 +75,6 @@ static void get_items_reply(DBusPendingCall *pending, void *_data) {
goto bail; goto bail;
} }
// Clear list
list_foreach(tray->items, (void (*)(void *))sni_free);
list_free(tray->items);
tray->items = create_list();
// O(n) function, could be faster dynamically reading values // O(n) function, could be faster dynamically reading values
int len = dbus_message_iter_get_element_count(&variant); int len = dbus_message_iter_get_element_count(&variant);
@ -88,12 +83,14 @@ static void get_items_reply(DBusPendingCall *pending, void *_data) {
const char *name; const char *name;
dbus_message_iter_get_basic(&array, &name); dbus_message_iter_get_basic(&array, &name);
struct StatusNotifierItem *item = sni_create(name); if (list_seq_find(tray->items, sni_str_cmp, name) == -1) {
struct StatusNotifierItem *item = sni_create(name);
if (item) { if (item) {
sway_log(L_DEBUG, "Item registered with host: %s", name); sway_log(L_DEBUG, "Item registered with host: %s", name);
list_add(tray->items, item); list_add(tray->items, item);
dirty = true; dirty = true;
}
} }
} }
@ -149,15 +146,22 @@ static void get_obj_items_reply(DBusPendingCall *pending, void *_data) {
dbus_message_iter_recurse(&array, &dstruct); dbus_message_iter_recurse(&array, &dstruct);
dbus_message_iter_get_basic(&dstruct, &object_path); dbus_message_iter_get_basic(&dstruct, &object_path);
dbus_message_iter_next(&dstruct);
dbus_message_iter_get_basic(&dstruct, &unique_name); dbus_message_iter_get_basic(&dstruct, &unique_name);
struct StatusNotifierItem *item = struct ObjName obj_name = {
sni_create_from_obj_path(unique_name, object_path); object_path,
unique_name,
};
if (list_seq_find(tray->items, sni_obj_name_cmp, &obj_name) == -1) {
struct StatusNotifierItem *item =
sni_create_from_obj_path(unique_name, object_path);
if (item) { if (item) {
sway_log(L_DEBUG, "Item registered with host: %s", unique_name); sway_log(L_DEBUG, "Item registered with host: %s", unique_name);
list_add(tray->items, item); list_add(tray->items, item);
dirty = true; dirty = true;
}
} }
} }
@ -167,6 +171,11 @@ bail:
} }
static void get_items() { static void get_items() {
// Clear list
list_foreach(tray->items, (void (*)(void *))sni_free);
list_free(tray->items);
tray->items = create_list();
DBusPendingCall *pending; DBusPendingCall *pending;
DBusMessage *message = dbus_message_new_method_call( DBusMessage *message = dbus_message_new_method_call(
"org.freedesktop.StatusNotifierWatcher", "org.freedesktop.StatusNotifierWatcher",
@ -352,6 +361,9 @@ static int init_host() {
register_host(name); register_host(name);
// Chances are if an item is already running, we'll get it two times.
// Once from this and another time from queued signals. Still we want
// to do this to be a complient sni host just in case.
get_items(); get_items();
// Perhaps use addmatch helper functions like wlc does? // Perhaps use addmatch helper functions like wlc does?