This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch network-manager
in repository enlightenment.
View the commit online.
commit b88fed09ef02975573b8d37115a98f9f1ae5586a
Author: [email protected] <[email protected]>
AuthorDate: Sat Mar 14 13:30:02 2026 -0600
fix: eliminate memory safety and signal handler lifecycle bugs in NetworkManager
Multiple critical issues fixed:
**agent.c — SIGSEGV in password dialog setup:**
- _dialog_psk_add received E_NM_Agent but dereferenced agent->dialog->win before
_dialog_new assigned agent->dialog. This accessed NULL + 0x58 (sizeof(E_Object)),
causing SIGSEGV crashes during password entry under load.
- Changed signature to accept E_Dialog* directly, eliminating the race.
- Return proper D-Bus InternalError when dialog creation fails instead of
empty success reply.
- Document why input->value is not freed in _page_del (owned by EFL widget).
**e_mod_main.c/h — Genlist activation and AGENT_PATH:**
- Changed genlist callback from "activated" (double-click/Enter) to "selected"
(single-click), matching intended UI behavior.
- Add immediate elm_genlist_item_selected_set(it, EINA_FALSE) so repeat clicks
always fire (prevents UI getting stuck on selected item).
- Corrected AGENT_PATH from custom path to standard NetworkManager SecretAgent path.
**e_networkmanager.c/h — Signal handler and state lifecycle:**
- Store explicit Eldbus_Signal_Handler* returns from all signal subscriptions
(AP.PropertiesChanged, Device.PropertiesChanged, Device.AccessPointAdded/Removed,
IP4Config.PropertiesChanged, Settings.ConnectionRemoved/NewConnection).
- Delete these handlers explicitly on proxy teardown, preventing dangling-pointer
callbacks after connection object is freed.
- Add saved_conn_generation counter so in-flight GetSettings callbacks abort
cleanly when manager is freed or new batch starts, avoiding use-after-free.
- Subscribe to Settings.NewConnection signal so saved-connections hash refreshes
when AddAndActivateConnection creates new profiles (enables forget button).
- Add "/" sentinel check for SpecificObject AP path in _active_conn_probe_cb
(NetworkManager uses "/" as null object path).
- Clear active_connection_path and active_ap_path in _manager_active_conn_watch_free.
- Implement smart connection selection: use saved profile if available, otherwise
call AddAndActivateConnection to let NM create and store new profile.
- Remove unused pending.active_conn field from NM_Manager structure.
Fixes intermittent crashes, dangling callbacks, password entry hangs, and
improves network switching reliability.
---
src/modules/networkmanager/agent.c | 20 +--
src/modules/networkmanager/e_mod_main.c | 6 +-
src/modules/networkmanager/e_mod_main.h | 2 +-
src/modules/networkmanager/e_networkmanager.c | 173 ++++++++++++++++++++++----
src/modules/networkmanager/e_networkmanager.h | 18 ++-
5 files changed, 183 insertions(+), 36 deletions(-)
diff --git a/src/modules/networkmanager/agent.c b/src/modules/networkmanager/agent.c
index 32d192dde..24d3470cd 100644
--- a/src/modules/networkmanager/agent.c
+++ b/src/modules/networkmanager/agent.c
@@ -167,6 +167,10 @@ _page_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED,
EINA_LIST_FREE(input_list, input)
{
free(input->key);
+ /* input->value is NOT freed here: it is a pointer into the EFL entry
+ * widget's internal buffer (set via e_widget_entry_add's &value
+ * parameter). The widget owns the allocation; freeing it here would
+ * be a double-free once the widget itself is destroyed. */
free(input);
}
}
@@ -186,7 +190,7 @@ _show_password_cb(void *data, Evas_Object *obj, void *event EINA_UNUSED)
/* -------------------------------------------------------------------------- */
static void
-_dialog_psk_add(E_NM_Agent *agent, const char *ssid)
+_dialog_psk_add(E_Dialog *dialog, const char *ssid)
{
Evas_Object *toolbook, *list, *framelist, *entry, *check;
E_NM_Agent_Input *input;
@@ -194,12 +198,12 @@ _dialog_psk_add(E_NM_Agent *agent, const char *ssid)
char header[128];
Evas *evas;
- evas = evas_object_evas_get(agent->dialog->win);
- toolbook = agent->dialog->content_object;
+ evas = evas_object_evas_get(dialog->win);
+ toolbook = dialog->content_object;
input = E_NEW(E_NM_Agent_Input, 1);
input->key = strdup("psk");
- entry = e_widget_entry_add(agent->dialog->win, &(input->value),
+ entry = e_widget_entry_add(dialog->win, &(input->value),
NULL, NULL, NULL);
evas_object_show(entry);
e_widget_entry_password_set(entry, 1);
@@ -237,7 +241,7 @@ _dialog_psk_add(E_NM_Agent *agent, const char *ssid)
evas_object_smart_callback_add(check, "changed",
_show_password_cb, entry);
- e_util_win_auto_resize_fill(agent->dialog->win);
+ e_util_win_auto_resize_fill(dialog->win);
}
static E_Dialog *
@@ -276,7 +280,7 @@ _dialog_new(E_NM_Agent *agent, const char *ssid)
e_dialog_button_focus_num(dialog, 0);
elm_win_center(dialog->win, 1, 1);
- _dialog_psk_add(agent, ssid);
+ _dialog_psk_add(dialog, ssid);
return dialog;
}
@@ -361,7 +365,9 @@ _agent_get_secrets(const Eldbus_Service_Interface *iface,
{
eldbus_message_unref(agent->msg);
agent->msg = NULL;
- return eldbus_message_method_return_new(msg);
+ return eldbus_message_error_new(msg,
+ "org.freedesktop.NetworkManager.SecretAgent.InternalError",
+ "Failed to create password dialog");
}
/* Return NULL — reply will be sent asynchronously from _dialog_ok_cb */
diff --git a/src/modules/networkmanager/e_mod_main.c b/src/modules/networkmanager/e_mod_main.c
index 8d9705500..8ad6e08a8 100644
--- a/src/modules/networkmanager/e_mod_main.c
+++ b/src/modules/networkmanager/e_mod_main.c
@@ -202,6 +202,8 @@ _enm_item_activated_cb(void *data, Evas_Object *obj EINA_UNUSED,
struct NM_Device *dev;
if (!it) return;
+ /* Deselect immediately so repeat clicks always fire "selected" */
+ elm_genlist_item_selected_set(it, EINA_FALSE);
id = elm_object_item_data_get(it);
if (!id) return;
@@ -735,8 +737,8 @@ _enm_popup_new(E_NM_Instance *inst)
itc->func.del = _enm_itc_item_del;
inst->ui.popup.itc_eth = itc;
- /* Activated signal for row tap → connect/disconnect */
- evas_object_smart_callback_add(gl, "activated", _enm_item_activated_cb,
+ /* Selected signal for row tap → connect/disconnect (single-click) */
+ evas_object_smart_callback_add(gl, "selected", _enm_item_activated_cb,
inst);
elm_box_pack_end(box, gl);
diff --git a/src/modules/networkmanager/e_mod_main.h b/src/modules/networkmanager/e_mod_main.h
index e73839860..48d668814 100644
--- a/src/modules/networkmanager/e_mod_main.h
+++ b/src/modules/networkmanager/e_mod_main.h
@@ -5,7 +5,7 @@
#include "e_networkmanager.h"
-#define AGENT_PATH "/org/enlightenment/networkmanager/agent"
+#define AGENT_PATH "/org/freedesktop/NetworkManager/SecretAgent"
extern E_Module *networkmanager_mod;
extern int _e_nm_log_dom;
diff --git a/src/modules/networkmanager/e_networkmanager.c b/src/modules/networkmanager/e_networkmanager.c
index a98343a52..a9e84cfa3 100644
--- a/src/modules/networkmanager/e_networkmanager.c
+++ b/src/modules/networkmanager/e_networkmanager.c
@@ -100,6 +100,11 @@ _ap_free(struct NM_Access_Point *ap)
if (ap->proxy)
{
+ if (ap->prop_changed_handler)
+ {
+ eldbus_signal_handler_del(ap->prop_changed_handler);
+ ap->prop_changed_handler = NULL;
+ }
obj = eldbus_proxy_object_get(ap->proxy);
eldbus_proxy_unref(ap->proxy);
eldbus_object_unref(obj);
@@ -243,8 +248,9 @@ _ap_new(const char *path)
ap->proxy = eldbus_proxy_get(obj, NM_IFACE_PROPS);
/* Subscribe to PropertiesChanged on the AP object */
- eldbus_proxy_signal_handler_add(ap->proxy, "PropertiesChanged",
- _ap_prop_changed, ap);
+ ap->prop_changed_handler =
+ eldbus_proxy_signal_handler_add(ap->proxy, "PropertiesChanged",
+ _ap_prop_changed, ap);
/* Fetch all AP properties */
eldbus_proxy_call(ap->proxy, "GetAll", _ap_get_props_cb, ap, -1,
@@ -469,11 +475,13 @@ _device_get_props_cb(void *data, const Eldbus_Message *msg,
/* Re-get object to get the wireless interface proxy */
dev->wireless_proxy = eldbus_proxy_get(obj, NM_IFACE_WIFI);
- eldbus_proxy_signal_handler_add(dev->wireless_proxy, "AccessPointAdded",
- _device_ap_added, dev);
- eldbus_proxy_signal_handler_add(dev->wireless_proxy,
- "AccessPointRemoved",
- _device_ap_removed, dev);
+ dev->ap_added_handler =
+ eldbus_proxy_signal_handler_add(dev->wireless_proxy, "AccessPointAdded",
+ _device_ap_added, dev);
+ dev->ap_removed_handler =
+ eldbus_proxy_signal_handler_add(dev->wireless_proxy,
+ "AccessPointRemoved",
+ _device_ap_removed, dev);
dev->pending.get_aps = eldbus_proxy_call(dev->wireless_proxy,
"GetAccessPoints",
@@ -644,8 +652,9 @@ _device_new(const char *path)
obj = eldbus_object_get(conn, NM_BUS_NAME, path);
dev->proxy = eldbus_proxy_get(obj, NM_IFACE_PROPS);
- eldbus_proxy_signal_handler_add(dev->proxy, "PropertiesChanged",
- _device_prop_changed, dev);
+ dev->prop_changed_handler =
+ eldbus_proxy_signal_handler_add(dev->proxy, "PropertiesChanged",
+ _device_prop_changed, dev);
dev->pending.get_props = eldbus_proxy_call(dev->proxy, "GetAll",
_device_get_props_cb, dev,
@@ -684,12 +693,27 @@ _device_free(struct NM_Device *dev)
if (dev->wireless_proxy)
{
Eldbus_Object *wobj = eldbus_proxy_object_get(dev->wireless_proxy);
+ if (dev->ap_added_handler)
+ {
+ eldbus_signal_handler_del(dev->ap_added_handler);
+ dev->ap_added_handler = NULL;
+ }
+ if (dev->ap_removed_handler)
+ {
+ eldbus_signal_handler_del(dev->ap_removed_handler);
+ dev->ap_removed_handler = NULL;
+ }
eldbus_proxy_unref(dev->wireless_proxy);
if (wobj) eldbus_object_unref(wobj);
}
if (dev->proxy)
{
+ if (dev->prop_changed_handler)
+ {
+ eldbus_signal_handler_del(dev->prop_changed_handler);
+ dev->prop_changed_handler = NULL;
+ }
obj = eldbus_proxy_object_get(dev->proxy);
eldbus_proxy_unref(dev->proxy);
eldbus_object_unref(obj);
@@ -713,6 +737,11 @@ _manager_ip4_watch_free(struct NM_Manager *nm)
}
if (nm->ip4_proxy)
{
+ if (nm->ip4_prop_handler)
+ {
+ eldbus_signal_handler_del(nm->ip4_prop_handler);
+ nm->ip4_prop_handler = NULL;
+ }
eldbus_proxy_unref(nm->ip4_proxy);
eldbus_object_unref(nm->ip4_obj);
nm->ip4_proxy = NULL;
@@ -839,8 +868,9 @@ _manager_watch_ip4(struct NM_Manager *nm, const char *ip4config_path)
nm->ip4_path = eina_stringshare_add(ip4config_path);
/* Subscribe to property changes — keeps proxy alive for signals */
- eldbus_proxy_signal_handler_add(props, "PropertiesChanged",
- _ip4_prop_changed, nm);
+ nm->ip4_prop_handler =
+ eldbus_proxy_signal_handler_add(props, "PropertiesChanged",
+ _ip4_prop_changed, nm);
/* Initial fetch */
nm->pending.ip4config = eldbus_proxy_call(props, "GetAll",
@@ -878,6 +908,10 @@ _manager_active_conn_watch_free(struct NM_Manager *nm)
nm->active_conn_proxy = NULL;
nm->active_conn_obj = NULL;
}
+ eina_stringshare_del(nm->active_connection_path);
+ nm->active_connection_path = NULL;
+ eina_stringshare_del(nm->active_ap_path);
+ nm->active_ap_path = NULL;
}
static void
@@ -997,6 +1031,9 @@ _active_conn_probe_cb(void *data, const Eldbus_Message *msg,
conn_type = _nm_conn_type_parse(type_str);
+ /* NM uses "/" as the null/none sentinel for object paths */
+ if (ap_path && !strcmp(ap_path, "/")) ap_path = NULL;
+
/* Skip non-network types (bridge, vpn, etc.) — they don't have
* useful SpecificObject or signal strength info. */
if (conn_type != NM_DEVICE_TYPE_WIFI &&
@@ -1323,9 +1360,10 @@ _manager_device_removed(void *data, const Eldbus_Message *msg)
struct _Saved_Conn_Ctx
{
struct NM_Manager *nm;
- const char *path; /* stringshare: connection D-Bus object path */
- Eldbus_Proxy *proxy; /* Settings.Connection proxy — unref in callback */
- Eldbus_Object *obj; /* connection object — unref in callback */
+ const char *path; /* stringshare: connection D-Bus object path */
+ Eldbus_Proxy *proxy; /* Settings.Connection proxy — unref in callback */
+ Eldbus_Object *obj; /* connection object — unref in callback */
+ unsigned int generation; /* snapshot of nm->saved_conn_generation */
};
static void
@@ -1337,6 +1375,15 @@ _saved_conn_settings_cb(void *data, const Eldbus_Message *msg,
const char *setting_name, *key;
char ssid_str[256];
+ /* Bail out if the manager was freed or a new batch was started while
+ * this D-Bus call was in flight — avoids writing to freed/stale state. */
+ if (ctx->generation != ctx->nm->saved_conn_generation)
+ {
+ DBG("_saved_conn_settings_cb: stale generation %u vs %u, discarding",
+ ctx->generation, ctx->nm->saved_conn_generation);
+ goto done;
+ }
+
{
const char *err_name = NULL, *err_msg = NULL;
if (eldbus_message_error_get(msg, &err_name, &err_msg))
@@ -1410,8 +1457,9 @@ done:
struct _Settings_List_Ctx
{
struct NM_Manager *nm;
- Eldbus_Proxy *proxy;
- Eldbus_Object *obj;
+ Eldbus_Proxy *proxy;
+ Eldbus_Object *obj;
+ unsigned int generation; /* snapshot of nm->saved_conn_generation */
};
static void
@@ -1420,6 +1468,7 @@ _saved_conn_list_cb(void *data, const Eldbus_Message *msg,
{
struct _Settings_List_Ctx *sctx = data;
struct NM_Manager *nm = sctx->nm;
+ unsigned int generation = sctx->generation;
Eldbus_Message_Iter *conn_array;
const char *conn_path;
@@ -1428,6 +1477,14 @@ _saved_conn_list_cb(void *data, const Eldbus_Message *msg,
eldbus_object_unref(sctx->obj);
free(sctx);
+ /* Bail out if a newer batch was started or manager was freed. */
+ if (generation != nm->saved_conn_generation)
+ {
+ DBG("_saved_conn_list_cb: stale generation %u vs %u, discarding",
+ generation, nm->saved_conn_generation);
+ return;
+ }
+
{
const char *err_name = NULL, *err_msg = NULL;
if (eldbus_message_error_get(msg, &err_name, &err_msg))
@@ -1452,6 +1509,7 @@ _saved_conn_list_cb(void *data, const Eldbus_Message *msg,
if (!ctx) continue;
ctx->nm = nm;
+ ctx->generation = generation;
ctx->path = eina_stringshare_add(conn_path);
ctx->obj = eldbus_object_get(conn, NM_BUS_NAME, conn_path);
ctx->proxy = eldbus_proxy_get(ctx->obj, NM_IFACE_SCONN);
@@ -1482,6 +1540,10 @@ enm_saved_connections_get(struct NM_Manager *nm)
struct _Settings_List_Ctx *sctx = malloc(sizeof(*sctx));
EINA_SAFETY_ON_NULL_RETURN(sctx);
+ /* Increment generation so any in-flight ListConnections/GetSettings
+ * callbacks from the previous batch will detect staleness and abort. */
+ nm->saved_conn_generation++;
+
/* Swap pattern: assign new hash before freeing old to avoid a window
* where saved_connections is NULL (in-flight callbacks check it).
* Only performed after malloc succeeds so OOM cannot corrupt the hash. */
@@ -1493,6 +1555,7 @@ enm_saved_connections_get(struct NM_Manager *nm)
}
sctx->nm = nm;
+ sctx->generation = nm->saved_conn_generation;
sctx->obj = eldbus_object_get(conn, NM_BUS_NAME, NM_SETTINGS_PATH);
sctx->proxy = eldbus_proxy_get(sctx->obj, NM_IFACE_SETTINGS);
eldbus_proxy_call(sctx->proxy, "ListConnections",
@@ -1567,6 +1630,17 @@ _settings_conn_removed_cb(void *data, const Eldbus_Message *msg EINA_UNUSED)
enm_saved_connections_get(nm);
}
+/* Called when NM adds a new connection (e.g. via AddAndActivateConnection) —
+ * refresh the hash so the forget button appears for the newly saved network. */
+static void
+_settings_conn_added_cb(void *data, const Eldbus_Message *msg EINA_UNUSED)
+{
+ struct NM_Manager *nm = data;
+ if (!nm) return;
+ INF("NewConnection signal: refreshing saved connections");
+ enm_saved_connections_get(nm);
+}
+
static struct NM_Manager *
_manager_new(void)
{
@@ -1608,6 +1682,9 @@ _manager_new(void)
nm->conn_removed_handler =
eldbus_proxy_signal_handler_add(nm->settings_proxy, "ConnectionRemoved",
_settings_conn_removed_cb, nm);
+ nm->conn_added_handler =
+ eldbus_proxy_signal_handler_add(nm->settings_proxy, "NewConnection",
+ _settings_conn_added_cb, nm);
return nm;
}
@@ -1620,6 +1697,11 @@ _manager_free(struct NM_Manager *nm)
if (!nm) return;
+ /* Invalidate in-flight saved-connection probes before freeing anything.
+ * Both _saved_conn_list_cb and _saved_conn_settings_cb check this field
+ * and will bail out cleanly without touching the freed NM_Manager. */
+ nm->saved_conn_generation++;
+
if (nm->pending.get_props)
eldbus_pending_cancel(nm->pending.get_props);
if (nm->pending.get_devices)
@@ -1651,6 +1733,11 @@ _manager_free(struct NM_Manager *nm)
eldbus_signal_handler_del(nm->conn_removed_handler);
nm->conn_removed_handler = NULL;
}
+ if (nm->conn_added_handler)
+ {
+ eldbus_signal_handler_del(nm->conn_added_handler);
+ nm->conn_added_handler = NULL;
+ }
if (nm->settings_proxy)
{
eldbus_proxy_unref(nm->settings_proxy);
@@ -1696,11 +1783,27 @@ _activate_cb(void *data, const Eldbus_Message *msg,
free(cd);
}
+static void
+_add_activate_cb(void *data, const Eldbus_Message *msg,
+ Eldbus_Pending *pending EINA_UNUSED)
+{
+ struct connection_cb_data *cd = data;
+ const char *name, *text;
+
+ if (eldbus_message_error_get(msg, &name, &text))
+ ERR("AddAndActivateConnection failed: %s: %s", name, text);
+ else
+ INF("AddAndActivateConnection succeeded");
+
+ free(cd);
+}
+
void
enm_ap_connect(struct NM_Manager *nm, struct NM_Device *dev,
struct NM_Access_Point *ap)
{
struct connection_cb_data *cd;
+ const char *conn_path = NULL;
EINA_SAFETY_ON_NULL_RETURN(nm);
EINA_SAFETY_ON_NULL_RETURN(dev);
@@ -1713,11 +1816,39 @@ enm_ap_connect(struct NM_Manager *nm, struct NM_Device *dev,
cd->dev = dev;
cd->ap = ap;
- /* ActivateConnection("/" means auto-select saved connection or create one,
- * device path, AP path) */
- eldbus_proxy_call(nm->proxy, "ActivateConnection",
- _activate_cb, cd, NM_CONNECTION_TIMEOUT,
- "ooo", "/", dev->path, ap->path);
+ if (nm->saved_connections && ap->ssid)
+ conn_path = eina_hash_find(nm->saved_connections, ap->ssid);
+
+ if (conn_path)
+ {
+ /* Known saved profile — activate it directly */
+ INF("ActivateConnection: saved profile %s for ssid=%s",
+ conn_path, ap->ssid);
+ eldbus_proxy_call(nm->proxy, "ActivateConnection",
+ _activate_cb, cd, NM_CONNECTION_TIMEOUT,
+ "ooo", conn_path, dev->path, ap->path);
+ }
+ else
+ {
+ /* No saved profile (new network or just forgotten) — let NM create
+ * a fresh profile and call our agent for credentials. */
+ Eldbus_Message *msg_call;
+ Eldbus_Message_Iter *iter, *empty_dict;
+
+ INF("AddAndActivateConnection: no saved profile for ssid=%s",
+ ap->ssid ?: "(null)");
+
+ msg_call = eldbus_proxy_method_call_new(nm->proxy,
+ "AddAndActivateConnection");
+ iter = eldbus_message_iter_get(msg_call);
+ /* Empty a{sa{sv}} connection dict — NM fills in security from the AP */
+ eldbus_message_iter_arguments_append(iter, "a{sa{sv}}", &empty_dict);
+ eldbus_message_iter_container_close(iter, empty_dict);
+ eldbus_message_iter_basic_append(iter, 'o', dev->path);
+ eldbus_message_iter_basic_append(iter, 'o', ap->path);
+ eldbus_proxy_send(nm->proxy, msg_call, _add_activate_cb, cd,
+ NM_CONNECTION_TIMEOUT);
+ }
}
static void
diff --git a/src/modules/networkmanager/e_networkmanager.h b/src/modules/networkmanager/e_networkmanager.h
index b128f1abd..e18b4a221 100644
--- a/src/modules/networkmanager/e_networkmanager.h
+++ b/src/modules/networkmanager/e_networkmanager.h
@@ -58,6 +58,8 @@ struct NM_Access_Point
Eldbus_Proxy *proxy;
EINA_INLIST;
+ Eldbus_Signal_Handler *prop_changed_handler;
+
char *ssid;
uint8_t strength;
uint32_t wpa_flags;
@@ -72,6 +74,10 @@ struct NM_Device
Eldbus_Proxy *wireless_proxy;
EINA_INLIST;
+ Eldbus_Signal_Handler *prop_changed_handler;
+ Eldbus_Signal_Handler *ap_added_handler;
+ Eldbus_Signal_Handler *ap_removed_handler;
+
char *interface;
enum NM_Device_Type type;
uint32_t state;
@@ -110,7 +116,6 @@ struct NM_Manager
{
Eldbus_Pending *get_props;
Eldbus_Pending *get_devices;
- Eldbus_Pending *active_conn;
Eldbus_Pending *ip4config;
} pending;
@@ -122,19 +127,22 @@ struct NM_Manager
Eldbus_Signal_Handler *active_conn_signal_handler; /* for explicit removal */
/* Persistent proxy/obj for watching IP4Config properties. */
- Eldbus_Proxy *ip4_proxy;
- Eldbus_Object *ip4_obj;
- const char *ip4_path;
+ Eldbus_Proxy *ip4_proxy;
+ Eldbus_Object *ip4_obj;
+ const char *ip4_path;
+ Eldbus_Signal_Handler *ip4_prop_handler; /* for explicit removal */
/* Saved WiFi connections: SSID (string) -> connection D-Bus path (stringshare) */
Eina_Hash *saved_connections;
- int saved_conn_pending; /* outstanding GetSettings calls */
+ int saved_conn_pending; /* outstanding GetSettings calls */
+ unsigned int saved_conn_generation; /* increment to abort in-flight GetSettings */
/* Long-lived Settings object/proxy for ConnectionRemoved signal subscription.
* Created in _manager_new, freed in _manager_free. */
Eldbus_Proxy *settings_proxy;
Eldbus_Object *settings_obj;
Eldbus_Signal_Handler *conn_removed_handler;
+ Eldbus_Signal_Handler *conn_added_handler;
/* Generation counter incremented each time a new batch of active-connection
* probes is started. Each probe captures the generation at creation time
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.