gnetworkmonitornetlink: Pass a GError into read_netlink_messages()

Currently this function calls `g_warning()` explicitly. It would be
nicer to properly propagate these failure up to the caller that tried to
initialise us.
This commit is contained in:
Iain Lane 2018-09-10 12:07:48 +01:00
parent 6629423e7a
commit 36c79adb2f
No known key found for this signature in database
GPG Key ID: E352D5C51C5041D4

View File

@ -52,9 +52,11 @@ struct _GNetworkMonitorNetlinkPrivate
GPtrArray *dump_networks; GPtrArray *dump_networks;
}; };
static gboolean read_netlink_messages (GSocket *socket, static gboolean read_netlink_messages (GNetworkMonitorNetlink *nl,
GIOCondition condition, GError **error);
gpointer user_data); static gboolean read_netlink_messages_callback (GSocket *socket,
GIOCondition condition,
gpointer user_data);
static gboolean request_dump (GNetworkMonitorNetlink *nl, static gboolean request_dump (GNetworkMonitorNetlink *nl,
GError **error); GError **error);
@ -139,15 +141,20 @@ g_network_monitor_netlink_initable_init (GInitable *initable,
*/ */
while (nl->priv->dump_networks) while (nl->priv->dump_networks)
{ {
if (!read_netlink_messages (NULL, G_IO_IN, nl)) GError *local_error = NULL;
break; if (!read_netlink_messages (nl, &local_error))
{
g_warning ("%s", local_error->message);
g_clear_error (&local_error);
break;
}
} }
g_socket_set_blocking (nl->priv->sock, FALSE); g_socket_set_blocking (nl->priv->sock, FALSE);
nl->priv->context = g_main_context_ref_thread_default (); nl->priv->context = g_main_context_ref_thread_default ();
nl->priv->source = g_socket_create_source (nl->priv->sock, G_IO_IN, NULL); nl->priv->source = g_socket_create_source (nl->priv->sock, G_IO_IN, NULL);
g_source_set_callback (nl->priv->source, g_source_set_callback (nl->priv->source,
(GSourceFunc) read_netlink_messages, nl, NULL); (GSourceFunc) read_netlink_messages_callback, nl, NULL);
g_source_attach (nl->priv->source, nl->priv->context); g_source_attach (nl->priv->source, nl->priv->context);
return initable_parent_iface->init (initable, cancellable, error); return initable_parent_iface->init (initable, cancellable, error);
@ -287,15 +294,13 @@ finish_dump (GNetworkMonitorNetlink *nl)
} }
static gboolean static gboolean
read_netlink_messages (GSocket *socket, read_netlink_messages (GNetworkMonitorNetlink *nl,
GIOCondition condition, GError **error)
gpointer user_data)
{ {
GNetworkMonitorNetlink *nl = user_data;
GInputVector iv; GInputVector iv;
gssize len; gssize len;
gint flags; gint flags;
GError *error = NULL; GError *local_error = NULL;
GSocketAddress *addr = NULL; GSocketAddress *addr = NULL;
struct nlmsghdr *msg; struct nlmsghdr *msg;
struct rtmsg *rtmsg; struct rtmsg *rtmsg;
@ -310,11 +315,9 @@ read_netlink_messages (GSocket *socket,
flags = MSG_PEEK | MSG_TRUNC; flags = MSG_PEEK | MSG_TRUNC;
len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1, len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1,
NULL, NULL, &flags, NULL, &error); NULL, NULL, &flags, NULL, &local_error);
if (len < 0) if (len < 0)
{ {
g_warning ("Error on netlink socket: %s", error->message);
g_clear_error (&error);
retval = FALSE; retval = FALSE;
goto done; goto done;
} }
@ -322,19 +325,15 @@ read_netlink_messages (GSocket *socket,
iv.buffer = g_malloc (len); iv.buffer = g_malloc (len);
iv.size = len; iv.size = len;
len = g_socket_receive_message (nl->priv->sock, &addr, &iv, 1, len = g_socket_receive_message (nl->priv->sock, &addr, &iv, 1,
NULL, NULL, NULL, NULL, &error); NULL, NULL, NULL, NULL, &local_error);
if (len < 0) if (len < 0)
{ {
g_warning ("Error on netlink socket: %s", error->message);
g_clear_error (&error);
retval = FALSE; retval = FALSE;
goto done; goto done;
} }
if (!g_socket_address_to_native (addr, &source_sockaddr, sizeof (source_sockaddr), &error)) if (!g_socket_address_to_native (addr, &source_sockaddr, sizeof (source_sockaddr), &local_error))
{ {
g_warning ("Error on netlink socket: %s", error->message);
g_clear_error (&error);
retval = FALSE; retval = FALSE;
goto done; goto done;
} }
@ -348,7 +347,10 @@ read_netlink_messages (GSocket *socket,
{ {
if (!NLMSG_OK (msg, (size_t) len)) if (!NLMSG_OK (msg, (size_t) len))
{ {
g_warning ("netlink message was truncated; shouldn't happen..."); g_set_error_literal (&local_error,
G_IO_ERROR,
G_IO_ERROR_PARTIAL_INPUT,
"netlink message was truncated; shouldn't happen...");
retval = FALSE; retval = FALSE;
goto done; goto done;
} }
@ -409,13 +411,21 @@ read_netlink_messages (GSocket *socket,
{ {
struct nlmsgerr *e = NLMSG_DATA (msg); struct nlmsgerr *e = NLMSG_DATA (msg);
g_warning ("netlink error: %s", g_strerror (-e->error)); g_set_error (&local_error,
G_IO_ERROR,
g_io_error_from_errno (-e->error),
"netlink error: %s",
g_strerror (-e->error));
} }
retval = FALSE; retval = FALSE;
goto done; goto done;
default: default:
g_warning ("unexpected netlink message %d", msg->nlmsg_type); g_set_error (&local_error,
G_IO_ERROR,
G_IO_ERROR_INVALID_DATA,
"unexpected netlink message %d",
msg->nlmsg_type);
retval = FALSE; retval = FALSE;
goto done; goto done;
} }
@ -427,6 +437,10 @@ read_netlink_messages (GSocket *socket,
if (!retval && nl->priv->dump_networks) if (!retval && nl->priv->dump_networks)
finish_dump (nl); finish_dump (nl);
if (local_error)
g_propagate_prefixed_error (error, local_error, "Error on netlink socket: ");
return retval; return retval;
} }
@ -459,6 +473,24 @@ g_network_monitor_netlink_finalize (GObject *object)
G_OBJECT_CLASS (g_network_monitor_netlink_parent_class)->finalize (object); G_OBJECT_CLASS (g_network_monitor_netlink_parent_class)->finalize (object);
} }
static gboolean
read_netlink_messages_callback (GSocket *socket,
GIOCondition condition,
gpointer user_data)
{
GError *error = NULL;
GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (user_data);
if (!read_netlink_messages (nl, &error))
{
g_warning ("Error reading netlink message: %s", error->message);
g_clear_error (&error);
return FALSE;
}
return TRUE;
}
static void static void
g_network_monitor_netlink_class_init (GNetworkMonitorNetlinkClass *nl_class) g_network_monitor_netlink_class_init (GNetworkMonitorNetlinkClass *nl_class)
{ {