c9a8747096c834aad3333146f93cd6efbdacaa4e
[platform/core/appfw/data-provider-master.git] / src / main.c
1 /*
2  * Copyright 2016  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <sys/signalfd.h>
24 #include <signal.h>
25 #include <ctype.h>
26
27 #include <systemd/sd-daemon.h>
28 #include <glib.h>
29 #include <glib-object.h>
30 #include <aul.h>
31 #include <vconf.h>
32 #include <dlog.h>
33 #include <locale.h>
34
35 #include "debug.h"
36 #include "service_common.h"
37 #include "shortcut_service.h"
38 #include "notification_service.h"
39 #include "badge_service.h"
40
41 static GMainLoop *main_loop;
42 static GIOChannel *channel;
43 static guint source;
44
45 static void lang_key_changed_cb(keynode_t *node, void *first)
46 {
47         char *lang;
48         char *r;
49
50         lang = vconf_get_str(VCONFKEY_LANGSET);
51         if (lang) {
52                 setenv("LANG", lang, 1);
53                 setenv("LC_MESSAGES", lang, 1);
54                 r = setlocale(LC_ALL, "");
55                 if (r == NULL) {
56                         r = setlocale(LC_ALL, lang);
57                         if (r != NULL)
58                                 DBG("setlocale = %s", r);
59                 }
60                 DBG("setlocale [%s]", r);
61                 free(lang);
62         }
63 }
64
65 static inline int app_create(void)
66 {
67         int ret;
68
69         ret = vconf_notify_key_changed(VCONFKEY_LANGSET, lang_key_changed_cb, NULL);
70         if (ret < 0)
71                 DBG("VCONFKEY_LANGSET notify key chenaged [%d]", ret);
72
73         lang_key_changed_cb(NULL, NULL);
74
75         ret = shortcut_service_init();
76         if (ret < 0)
77                 WARN("shortcut [%d]", ret);
78
79         ret = notification_service_init();
80         if (ret < 0)
81                 WARN("notification [%d]", ret);
82
83         ret = badge_service_init();
84         if (ret < 0)
85                 WARN("badge [%d]", ret);
86
87         service_common_init();
88         INFO("Successfully initialized");
89
90         return 0;
91 }
92
93 static inline int app_terminate(void)
94 {
95         int ret;
96
97         ret = badge_service_fini();
98         if (ret < 0)
99                 DBG("badge [%d]", ret);
100
101         ret = notification_service_fini();
102         if (ret < 0)
103                 DBG("notification [%d]", ret);
104
105         ret = shortcut_service_fini();
106         if (ret < 0)
107                 DBG("shortcut [%d]", ret);
108
109         return 0;
110 }
111
112 static gboolean __signal_handler(GIOChannel *channel,
113                 GIOCondition cond, gpointer data)
114 {
115         struct signalfd_siginfo fdsi;
116         ssize_t size;
117         int sfd;
118
119         sfd = g_io_channel_unix_get_fd(channel);
120
121         size = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
122         if (size != sizeof(struct signalfd_siginfo)) {
123                 ERR("signal read failed [%d]", errno);
124                 return TRUE;
125         }
126
127         if (fdsi.ssi_signo == SIGTERM) {
128                 ERR("Terminated(SIGTERM)");
129                 g_main_loop_quit(main_loop);
130         } else {
131                 ERR("Unknown SIG[%d] received", fdsi.ssi_signo);
132         }
133
134         return TRUE;
135 }
136
137 static int __init_signal_handler(void)
138 {
139         sigset_t mask;
140         int sfd;
141         int ret;
142
143         ret = sigemptyset(&mask);
144         if (ret < 0) {
145                 ERR("sigemptyset : %d", errno);
146                 return -1;
147         }
148
149         ret = sigaddset(&mask, SIGTERM);
150         if (ret < 0) {
151                 ERR("sigaddset: %d", errno);
152                 return -1;
153         }
154
155         ret = sigprocmask(SIG_BLOCK, &mask, NULL);
156         if (ret < 0) {
157                 ERR("sigprocmask: %d", errno);
158                 return -1;
159         }
160
161         sfd = signalfd(-1, &mask, SFD_NONBLOCK);
162         if (sfd < 0) {
163                 ERR("signalfd: %d", errno);
164                 return -1;
165         }
166
167         channel = g_io_channel_unix_new(sfd);
168         g_io_channel_set_close_on_unref(channel, TRUE);
169         g_io_channel_set_encoding(channel, NULL, NULL);
170         g_io_channel_set_buffered(channel, FALSE);
171
172         source = g_io_add_watch(channel, G_IO_IN, __signal_handler, NULL);
173
174         INFO("source[%u]", source);
175
176         return 0;
177 }
178
179 void __finish(void)
180 {
181         if (source > 0)
182                 g_source_remove(source);
183         if (channel)
184                 g_io_channel_unref(channel);
185
186         app_terminate();
187 }
188
189 int main(int argc, char *argv[])
190 {
191         int restart_count = 0;
192
193         main_loop = g_main_loop_new(NULL, FALSE);
194         if (!main_loop)
195                 return -1;
196
197 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
198         g_type_init();
199 #endif
200
201         vconf_get_int(VCONFKEY_MASTER_RESTART_COUNT, &restart_count);
202
203         app_create();
204         sd_notify(0, "READY=1");
205
206         restart_count++;
207         vconf_set_int(VCONFKEY_MASTER_RESTART_COUNT, restart_count);
208
209         if (__init_signal_handler() < 0)
210                 ERR("Failed to init signal handler");
211
212         g_main_loop_run(main_loop);
213
214         __finish();
215
216         g_main_loop_unref(main_loop);
217
218         return 0;
219 }
220
221 /* End of a file */