1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of gsignond
6 * Copyright (C) 2013 Intel Corporation.
8 * Contact: Imran Zaman <imran.zaman@intel.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
31 #include <glib-unix.h>
34 #include <sys/prctl.h>
36 #include "gsignond/gsignond-log.h"
37 #include "daemon/dbus/gsignond-dbus.h"
38 #include "gsignond-plugin-daemon.h"
40 static GSignondPluginDaemon *_daemon = NULL;
41 static guint _sig_source_id[3];
44 _on_daemon_closed (gpointer data, GObject *server)
47 DBG ("Daemon closed");
48 if (data) g_main_loop_quit ((GMainLoop *)data);
52 _handle_quit_signal (gpointer user_data)
54 GMainLoop *ml = (GMainLoop *) user_data;
56 g_return_val_if_fail (ml != NULL, FALSE);
57 DBG ("Received quit signal");
58 if (ml) g_main_loop_quit (ml);
64 _install_sighandlers (GMainLoop *main_loop)
66 GSource *source = NULL;
67 GMainContext *ctx = g_main_loop_get_context (main_loop);
69 source = g_unix_signal_source_new (SIGTERM);
70 g_source_set_callback (source,
74 _sig_source_id[0] = g_source_attach (source, ctx);
76 source = g_unix_signal_source_new (SIGINT);
77 g_source_set_callback (source,
81 _sig_source_id[1] = g_source_attach (source, ctx);
83 source = g_unix_signal_source_new (SIGHUP);
84 g_source_set_callback (source,
88 _sig_source_id[2] = g_source_attach (source, ctx);
90 if (prctl(PR_SET_PDEATHSIG, SIGHUP))
91 WARN ("failed to set parent death signal");
94 int main (int argc, char **argv)
97 GMainLoop *main_loop = NULL;
98 GOptionContext *opt_context = NULL;
99 gchar **plugin_args = NULL;
100 gint in_fd = 0, out_fd = 1;
101 GOptionEntry opt_entries[] = {
102 {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &plugin_args,
103 "Plugin Args", NULL},
107 /* Duplicates stdin,stdout,stderr descriptors and point the descriptors
108 * to /dev/null to avoid anyone writing to descriptors before initial
109 * "plugind-is-ready" notification is sent to gsignond
113 WARN ("Failed to dup stdin : %s(%d)", strerror(errno), errno);
116 if (!freopen("/dev/null", "r+", stdin)) {
117 WARN ("Unable to redirect stdin to /dev/null");
122 WARN ("Failed to dup stdout : %s(%d)", strerror(errno), errno);
126 /* Reattach stderr to stdout */
129 #if !GLIB_CHECK_VERSION (2, 36, 0)
133 opt_context = g_option_context_new ("<plugin_path> <plugin_name>");
134 g_option_context_set_summary (opt_context, "gSSO helper plugin daemon");
135 g_option_context_add_main_entries (opt_context, opt_entries, NULL);
136 g_option_context_set_ignore_unknown_options (opt_context, TRUE);
137 g_option_context_parse (opt_context, &argc, &argv, &error);
138 g_option_context_free (opt_context);
140 WARN ("Error in arguments parsing: %s", error->message);
141 g_error_free (error);
143 if (!plugin_args || !plugin_args[0] || !plugin_args[1]) {
144 WARN ("plugin path or plugin type missing");
145 if (plugin_args) g_strfreev(plugin_args);
149 _daemon = gsignond_plugin_daemon_new (plugin_args[0], plugin_args[1], in_fd,
151 g_strfreev(plugin_args);
152 if (_daemon == NULL) {
156 main_loop = g_main_loop_new (NULL, FALSE);
157 g_object_weak_ref (G_OBJECT (_daemon), _on_daemon_closed, main_loop);
158 _install_sighandlers (main_loop);
160 DBG ("Entering main event loop");
162 g_main_loop_run (main_loop);
165 g_object_unref (_daemon);
169 g_main_loop_unref (main_loop);