struct netlink_info *netlink_new(int protocol) { struct netlink_info *netlink; int sk; netlink = g_try_new0(struct netlink_info, 1); if (!netlink) return NULL; netlink->next_seq = 1; netlink->next_command_id = 1; netlink->next_notify_id = 1; sk = create_netlink_socket(protocol, &netlink->pid); if (sk < 0) { g_free(netlink); return NULL; } netlink->channel = g_io_channel_unix_new(sk); g_io_channel_set_close_on_unref(netlink->channel, TRUE); g_io_channel_set_encoding(netlink->channel, NULL, NULL); g_io_channel_set_buffered(netlink->channel, FALSE); g_io_add_watch(netlink->channel, G_IO_IN, can_read_data, netlink); g_io_add_watch(netlink->channel, G_IO_NVAL | G_IO_HUP | G_IO_ERR, netlink_event, netlink); netlink->command_queue = g_queue_new(); netlink->command_pending = g_hash_table_new(g_direct_hash, g_direct_equal); netlink->command_lookup = g_hash_table_new(g_direct_hash, g_direct_equal); netlink->notify_groups = g_hash_table_new(g_direct_hash, g_direct_equal); netlink->notify_lookup = g_hash_table_new(g_direct_hash, g_direct_equal); return netlink; }
/* Constructor, kicks off bootstrapping */ static void gupnp_linux_context_manager_constructed (GObject *object) { GObjectClass *parent_class; GUPnPLinuxContextManager *self; GError *error = NULL; self = GUPNP_LINUX_CONTEXT_MANAGER (object); if (!create_ioctl_socket (self, &error)) goto cleanup; if (!create_netlink_socket (self, &error)) goto cleanup; self->priv->bootstrap_source = g_idle_source_new (); g_source_attach (self->priv->bootstrap_source, g_main_context_get_thread_default ()); g_source_set_callback (self->priv->bootstrap_source, (GSourceFunc) on_bootstrap, self, NULL); cleanup: if (error) { if (self->priv->fd > 0) close (self->priv->fd); g_warning ("Failed to setup Linux context manager: %s", error->message); g_error_free (error); } /* Chain-up */ parent_class = G_OBJECT_CLASS (gupnp_linux_context_manager_parent_class); if (parent_class->constructed) parent_class->constructed (object); }