Release 0.0.3
[platform/core/system/tlm.git] / src / sessiond / main.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of tlm
5  *
6  * Copyright (C) 2014 Intel Corporation.
7  *
8  * Contact: Imran Zaman <imran.zaman@intel.com>
9  *
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.
14  *
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.
19  *
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
23  * 02110-1301 USA
24  */
25
26 #include <config.h>
27 #include <errno.h>
28 #include <signal.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <glib-unix.h>
32 #include <glib.h>
33 #include <gio/gio.h>
34 #include <sys/prctl.h>
35
36 #include "common/tlm-log.h"
37 #include "tlm-session-daemon.h"
38
39 static TlmSessionDaemon *_daemon = NULL;
40 static guint _sig_source_id[3];
41
42 static void
43 _on_daemon_closed (gpointer data, GObject *server)
44 {
45     _daemon = NULL;
46     DBG ("Daemon closed");
47     if (data) g_main_loop_quit ((GMainLoop *)data);
48 }
49
50 static gboolean
51 _handle_quit_signal (gpointer user_data)
52 {
53     GMainLoop *ml = (GMainLoop *) user_data;
54
55     g_return_val_if_fail (ml != NULL, FALSE);
56     DBG ("Received quit signal");
57     if (ml) g_main_loop_quit (ml);
58
59     return FALSE;
60 }
61
62 static void 
63 _install_sighandlers (GMainLoop *main_loop)
64 {
65     GSource *source = NULL;
66     GMainContext *ctx = g_main_loop_get_context (main_loop);
67
68     source = g_unix_signal_source_new (SIGTERM);
69     g_source_set_callback (source,
70                            _handle_quit_signal,
71                            main_loop,
72                            NULL);
73     _sig_source_id[0] = g_source_attach (source, ctx);
74
75     source = g_unix_signal_source_new (SIGINT);
76     g_source_set_callback (source,
77                            _handle_quit_signal,
78                            main_loop,
79                            NULL);
80     _sig_source_id[1] = g_source_attach (source, ctx);
81
82     source = g_unix_signal_source_new (SIGHUP);
83     g_source_set_callback (source,
84                            _handle_quit_signal,
85                            main_loop,
86                            NULL);
87     _sig_source_id[2] = g_source_attach (source, ctx);
88
89     if (prctl(PR_SET_PDEATHSIG, SIGHUP))
90         WARN ("failed to set parent death signal");
91 }
92
93 int main (int argc, char **argv)
94 {
95     GMainLoop *main_loop = NULL;
96     gint in_fd = 0, out_fd = 1;
97
98     /* Duplicates stdin and stdout descriptors and point the descriptors
99      * to /dev/null to avoid anyone writing to descriptors
100      * */
101     in_fd = dup(0);
102     if (in_fd == -1) {
103         WARN ("Failed to dup stdin : %s(%d)", strerror(errno), errno);
104         in_fd = 0;
105     }
106     if (!freopen("/dev/null", "r+", stdin)) {
107         WARN ("Unable to redirect stdin to /dev/null");
108     }
109
110     out_fd = dup(1);
111     if (out_fd == -1) {
112         WARN ("Failed to dup stdout : %s(%d)", strerror(errno), errno);
113         out_fd = 1;
114     }
115
116     if (!freopen("/dev/null", "w+", stdout)) {
117         WARN ("Unable to redirect stdout to /dev/null");
118     }
119
120     /* Reattach stdout to stderr */
121     //dup2 (2, 1);
122
123 #if !GLIB_CHECK_VERSION (2, 36, 0)
124     g_type_init ();
125 #endif
126
127     DBG ("old pgid=%u", getpgrp ());
128
129     _daemon = tlm_session_daemon_new (in_fd, out_fd);
130     if (_daemon == NULL) {
131         return -1;
132     }
133
134     main_loop = g_main_loop_new (NULL, FALSE);
135     g_object_weak_ref (G_OBJECT (_daemon), _on_daemon_closed, main_loop);
136     _install_sighandlers (main_loop);
137
138     tlm_log_init(G_LOG_DOMAIN);
139
140     DBG ("Entering main event loop");
141
142     g_main_loop_run (main_loop);
143
144     if(_daemon) {
145         g_object_unref (_daemon);
146     }
147
148     if (main_loop) {
149         g_main_loop_unref (main_loop);
150     }
151     tlm_log_close (NULL);
152     return 0;
153 }