void nm_dnsmasq_manager_stop (NMDnsMasqManager *manager) { NMDnsMasqManagerPrivate *priv; g_return_if_fail (NM_IS_DNSMASQ_MANAGER (manager)); priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (manager); if (priv->dm_watch_id) { g_source_remove (priv->dm_watch_id); priv->dm_watch_id = 0; } if (priv->pid) { if (kill (priv->pid, SIGTERM) == 0) g_timeout_add_seconds (2, ensure_killed, GINT_TO_POINTER (priv->pid)); else { kill (priv->pid, SIGKILL); /* ensure the child is reaped */ nm_debug ("waiting for dnsmasq pid %d to exit", priv->pid); waitpid (priv->pid, NULL, 0); nm_debug ("dnsmasq pid %d cleaned up", priv->pid); } priv->pid = 0; } unlink (priv->pidfile); }
static void finalize (GObject *object) { NMDnsMasqManagerPrivate *priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (object); nm_dnsmasq_manager_stop (NM_DNSMASQ_MANAGER (object)); g_free (priv->iface); g_free (priv->pidfile); G_OBJECT_CLASS (nm_dnsmasq_manager_parent_class)->finalize (object); }
NMDnsMasqManager * nm_dnsmasq_manager_new (const char *iface) { NMDnsMasqManager *manager; NMDnsMasqManagerPrivate *priv; manager = (NMDnsMasqManager *) g_object_new (NM_TYPE_DNSMASQ_MANAGER, NULL); priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (manager); priv->iface = g_strdup (iface); priv->pidfile = g_strdup_printf (LOCALSTATEDIR "/run/nm-dnsmasq-%s.pid", iface); return manager; }
gboolean nm_dnsmasq_manager_start (NMDnsMasqManager *manager, NMIP4Config *ip4_config, GError **error) { NMDnsMasqManagerPrivate *priv; NMCmdLine *dm_cmd; char *cmd_str; g_return_val_if_fail (NM_IS_DNSMASQ_MANAGER (manager), FALSE); if (error) g_return_val_if_fail (*error == NULL, FALSE); priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (manager); kill_existing_for_iface (priv->iface, priv->pidfile); dm_cmd = create_dm_cmd_line (priv->iface, ip4_config, priv->pidfile, error); if (!dm_cmd) return FALSE; g_ptr_array_add (dm_cmd->array, NULL); nm_info ("Starting dnsmasq..."); cmd_str = nm_cmd_line_to_str (dm_cmd); nm_debug ("Command line: %s", cmd_str); g_free (cmd_str); priv->pid = 0; if (!g_spawn_async (NULL, (char **) dm_cmd->array->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, dm_child_setup, NULL, &priv->pid, error)) { goto out; } nm_debug ("dnsmasq started with pid %d", priv->pid); priv->dm_watch_id = g_child_watch_add (priv->pid, (GChildWatchFunc) dm_watch_cb, manager); out: if (dm_cmd) nm_cmd_line_destroy (dm_cmd); return priv->pid > 0; }
void nm_dnsmasq_manager_stop (NMDnsMasqManager *manager) { NMDnsMasqManagerPrivate *priv; g_return_if_fail (NM_IS_DNSMASQ_MANAGER (manager)); priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (manager); if (priv->dm_watch_id) { g_source_remove (priv->dm_watch_id); priv->dm_watch_id = 0; } if (priv->pid) { nm_utils_kill_child_async (priv->pid, SIGTERM, LOGD_SHARING, "dnsmasq", 2000, NULL, NULL); priv->pid = 0; } unlink (priv->pidfile); }
static void dm_watch_cb (GPid pid, gint status, gpointer user_data) { NMDnsMasqManager *manager = NM_DNSMASQ_MANAGER (user_data); NMDnsMasqManagerPrivate *priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (manager); guint err; if (WIFEXITED (status)) { err = WEXITSTATUS (status); if (err != 0) dm_exit_code (err); } else if (WIFSTOPPED (status)) g_warning ("dnsmasq stopped unexpectedly with signal %d", WSTOPSIG (status)); else if (WIFSIGNALED (status)) g_warning ("dnsmasq died with signal %d", WTERMSIG (status)); else g_warning ("dnsmasq died from an unknown cause"); priv->pid = 0; g_signal_emit (manager, signals[STATE_CHANGED], 0, NM_DNSMASQ_STATUS_DEAD); }