Update tts for tizen 2.0 beta
[platform/core/uifw/tts.git] / client / tts_setting.c
1 /*
2 *  Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved 
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14
15 #include <sys/wait.h>
16 #include <Ecore.h>
17
18 #include "tts_main.h"
19 #include "tts_setting.h"
20 #include "tts_setting_dbus.h"
21
22 static bool g_is_daemon_started = false;
23
24 static int __check_tts_daemon();
25
26 static tts_setting_state_e g_state = TTS_SETTING_STATE_NONE;
27
28 static tts_setting_initialized_cb g_initialized_cb;
29 static void* g_user_data;
30
31 static int g_reason;
32
33 /* API Implementation */
34 static Eina_Bool __tts_setting_initialized(void *data)
35 {
36         g_initialized_cb(g_state, g_reason, g_user_data);
37
38         return EINA_FALSE;
39 }
40
41 static Eina_Bool __tts_setting_connect_daemon(void *data)
42 {
43         /* Send hello */
44         if (0 != tts_setting_dbus_request_hello()) {
45                 if (false == g_is_daemon_started) {
46                         g_is_daemon_started = true;
47                         __check_tts_daemon();
48                 }
49                 return EINA_TRUE;
50         }
51
52         SLOG(LOG_DEBUG, TAG_TTSC, "===== Connect daemon");
53
54         /* do request initialize */
55         int ret = -1;
56
57         ret = tts_setting_dbus_request_initialize();
58
59         if (TTS_SETTING_ERROR_ENGINE_NOT_FOUND == ret) {
60                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
61         } else if (TTS_SETTING_ERROR_NONE != ret) {
62                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to connection : %d", ret);
63         } else {
64                 /* success to connect tts-daemon */
65                 g_state = TTS_SETTING_STATE_READY;
66         }
67
68         g_reason = ret;
69
70         ecore_timer_add(0, __tts_setting_initialized, NULL);
71
72         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
73         SLOG(LOG_DEBUG, TAG_TTSC, " ");
74
75         return EINA_FALSE;
76 }
77
78 int tts_setting_initialize()
79 {
80         SLOG(LOG_DEBUG, TAG_TTSC, "===== Initialize TTS Setting");
81
82         if (TTS_SETTING_STATE_READY == g_state) {
83                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] TTS Setting has already been initialized. \n");
84                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
85                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
86                 return TTS_SETTING_ERROR_NONE;
87         }
88
89         if( 0 != tts_setting_dbus_open_connection() ) {
90                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open connection\n ");
91                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
92                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
93                 return TTS_SETTING_ERROR_OPERATION_FAILED;
94         }
95
96         /* Send hello */
97         if (0 != tts_setting_dbus_request_hello()) {
98                 __check_tts_daemon();
99         }
100
101         /* do request */
102         int i = 1;
103         int ret = 0;
104         while(1) {
105                 ret = tts_setting_dbus_request_initialize();
106
107                 if( TTS_SETTING_ERROR_ENGINE_NOT_FOUND == ret ) {
108                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine not found");
109                         break;
110                 } else if(ret) {
111                         sleep(1);
112                         if (i == 3) {
113                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Connection Time out");
114                                 ret = TTS_SETTING_ERROR_TIMED_OUT;                          
115                                 break;
116                         }    
117                         i++;
118                 } else {
119                         /* success to connect tts-daemon */
120                         break;
121                 }
122         }
123
124         if (TTS_SETTING_ERROR_NONE == ret) {
125                 g_state = TTS_SETTING_STATE_READY;
126                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Initialize");
127         }
128
129         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
130         SLOG(LOG_DEBUG, TAG_TTSC, " ");
131
132         return ret;
133 }
134
135 int tts_setting_initialize_async(tts_setting_initialized_cb callback, void* user_data)
136 {
137         SLOG(LOG_DEBUG, TAG_TTSC, "===== Initialize TTS Setting");
138
139         if (TTS_SETTING_STATE_READY == g_state) {
140                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] TTS Setting has already been initialized. \n");
141                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
142                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
143                 return TTS_SETTING_ERROR_NONE;
144         }
145
146         if( 0 != tts_setting_dbus_open_connection() ) {
147                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to open connection\n ");
148                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
149                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
150                 return TTS_SETTING_ERROR_OPERATION_FAILED;
151         }
152         
153         g_initialized_cb = callback;
154         g_user_data = user_data;
155
156         ecore_timer_add(0, __tts_setting_connect_daemon, NULL);
157
158         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
159         SLOG(LOG_DEBUG, TAG_TTSC, " ");
160
161         return TTS_SETTING_ERROR_NONE;
162 }
163
164
165 int tts_setting_finalize()
166 {
167         SLOG(LOG_DEBUG, TAG_TTSC, "===== Finalize TTS Setting");
168
169         if (TTS_SETTING_STATE_NONE == g_state) {
170                 SLOG(LOG_WARN, TAG_TTSC, "[WARNING] Not initialized");
171                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
172                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
173                 return TTS_SETTING_ERROR_INVALID_STATE;
174         }
175
176         int ret = tts_setting_dbus_request_finalilze(); 
177         if (0 != ret) {
178                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] result : %d", ret);
179                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
180                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
181
182                 return TTS_SETTING_ERROR_OPERATION_FAILED;
183         }
184
185         if (0 != tts_setting_dbus_close_connection()) {
186                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to close connection\n ");
187         } else {
188                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Finalize");
189         }
190
191         g_state = TTS_SETTING_STATE_NONE;
192         
193         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
194         SLOG(LOG_DEBUG, TAG_TTSC, " ");
195
196         return TTS_SETTING_ERROR_NONE;
197 }
198
199 int tts_setting_foreach_supported_engines(tts_setting_supported_engine_cb callback, void* user_data)
200 {    
201         SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported engines");
202
203         if (TTS_SETTING_STATE_NONE == g_state) {
204                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
205                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
206                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
207                 return TTS_SETTING_ERROR_INVALID_STATE;
208         }
209
210         if (NULL == callback) {
211                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Callback is NULL");
212                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
213                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
214                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
215         }
216
217         int ret = tts_setting_dbus_request_get_engine_list(callback, user_data);
218         if (0 != ret) {
219                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
220         } else {
221                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Foreach supported engines");
222         }
223         
224         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
225         SLOG(LOG_DEBUG, TAG_TTSC, " ");
226                 
227         return ret;
228 }
229
230 int tts_setting_get_engine(char** engine_id)
231 {
232         SLOG(LOG_DEBUG, TAG_TTSC, "===== Get current engine");
233
234         if (TTS_SETTING_STATE_NONE == g_state) {
235                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
236                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
237                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
238                 return TTS_SETTING_ERROR_INVALID_STATE;
239         }
240
241         if (NULL == engine_id) {
242                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine id is NULL");
243                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
244                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
245                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
246         }
247
248         int ret = tts_setting_dbus_request_get_engine(engine_id);
249         if (0 != ret) {
250                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
251         } else {
252                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Get current engine");
253         }
254
255         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
256         SLOG(LOG_DEBUG, TAG_TTSC, " ");
257
258         return ret;
259 }
260
261 int tts_setting_set_engine(const char* engine_id)
262 {
263         SLOG(LOG_DEBUG, TAG_TTSC, "===== Set current engine");
264
265         if (TTS_SETTING_STATE_NONE == g_state) {
266                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
267                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
268                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
269                 return TTS_SETTING_ERROR_INVALID_STATE;
270         }
271
272         if (NULL == engine_id) {
273                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Engine id is NULL");
274                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
275                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
276                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
277         }
278
279         int ret = tts_setting_dbus_request_set_engine(engine_id);
280         if (0 != ret) {
281                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
282         } else {
283                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set current engine");
284         }
285         
286         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
287         SLOG(LOG_DEBUG, TAG_TTSC, " ");
288     
289         return ret;
290 }
291
292 int tts_setting_foreach_surpported_voices(tts_setting_supported_voice_cb callback, void* user_data)
293 {
294         SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach supported voices");
295
296         if (TTS_SETTING_STATE_NONE == g_state) {
297                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
298                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
299                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
300                 return TTS_SETTING_ERROR_INVALID_STATE;
301         }
302
303         if (NULL == callback) {
304                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Param is NULL");
305                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
306                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
307                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
308         }
309
310         int ret = tts_setting_dbus_request_get_voice_list(callback, user_data);
311
312         if (0 != ret) {
313                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
314         } else {
315                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Foreach supported voices");
316         }
317
318         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
319         SLOG(LOG_DEBUG, TAG_TTSC, " ");
320
321         return ret;
322 }
323
324 int tts_setting_get_default_voice(char** language, tts_setting_voice_type_e* voice_type)
325 {
326         SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default voice");
327
328         if (TTS_SETTING_STATE_NONE == g_state) {
329                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
330                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
331                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
332                 return TTS_SETTING_ERROR_INVALID_STATE;
333         }
334
335         if (NULL == language || NULL == voice_type) {
336                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is NULL");
337                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
338                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
339                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
340         }
341
342         int ret = tts_setting_dbus_request_get_default_voice(language, voice_type);
343         if (0 != ret) {
344                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
345         } else {
346                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Foreach supported voices");
347         }
348
349         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
350         SLOG(LOG_DEBUG, TAG_TTSC, " ");
351
352         return ret;
353 }
354
355 int tts_setting_set_default_voice(const char* language, tts_setting_voice_type_e voice_type)
356 {
357         SLOG(LOG_DEBUG, TAG_TTSC, "===== Set default voice");
358
359         if (TTS_SETTING_STATE_NONE == g_state) {
360                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
361                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
362                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
363                 return TTS_SETTING_ERROR_INVALID_STATE;
364         }
365
366         if (NULL == language) {
367                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is NULL");
368                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
369                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
370                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
371         }
372
373         if (voice_type < TTS_SETTING_VOICE_TYPE_MALE || TTS_SETTING_VOICE_TYPE_USER3 < voice_type ) {
374                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid voice type");
375                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
376                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
377                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
378         }
379
380         int ret = tts_setting_dbus_request_set_default_voice(language, voice_type);
381         if (0 != ret) {
382                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
383         } else {
384                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set default voice");
385         }
386
387         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
388         SLOG(LOG_DEBUG, TAG_TTSC, " ");
389     
390         return ret;
391 }
392
393
394 int tts_setting_get_default_speed(tts_setting_speed_e* speed)
395 {
396         SLOG(LOG_DEBUG, TAG_TTSC, "===== Get default speed");
397
398         if (TTS_SETTING_STATE_NONE == g_state) {
399                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
400                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
401                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
402                 return TTS_SETTING_ERROR_INVALID_STATE;
403         }
404
405         if (NULL == speed) {
406                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Param is NULL");
407                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
408                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
409                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
410         }
411
412         int temp;
413         temp = 0;
414
415         int ret = tts_setting_dbus_request_get_default_speed(&temp);
416         if (0 != ret) {
417                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
418         } else {
419                 /* Copy value */
420                 *speed = (tts_setting_speed_e)temp;
421                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Get default speed : %d ", (int)*speed);
422         }
423
424         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
425         SLOG(LOG_DEBUG, TAG_TTSC, " ");
426
427         return ret;
428 }
429
430
431 int tts_setting_set_default_speed(tts_setting_speed_e speed)
432 {
433         SLOG(LOG_DEBUG, TAG_TTSC, "===== Set default speed");
434
435         if (TTS_SETTING_STATE_NONE == g_state) {
436                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
437                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
438                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
439                 return TTS_SETTING_ERROR_INVALID_STATE;
440         }
441
442         if (speed < TTS_SETTING_SPEED_VERY_SLOW || TTS_SETTING_SPEED_VERY_FAST < speed) {
443                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Invalid speed");
444                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
445                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
446                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
447         }
448
449         int ret = tts_setting_dbus_request_set_default_speed((int)speed);
450         if (0 != ret) {
451                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
452         } else {
453                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Set default speed");
454         }
455         
456         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
457         SLOG(LOG_DEBUG, TAG_TTSC, " ");
458
459         return ret;
460 }
461
462 int tts_setting_foreach_engine_settings(tts_setting_engine_setting_cb callback, void* user_data)
463 {
464         SLOG(LOG_DEBUG, TAG_TTSC, "===== Foreach engine setting");
465
466         if (TTS_SETTING_STATE_NONE == g_state) {
467                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
468                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
469                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
470                 return TTS_SETTING_ERROR_INVALID_STATE;
471         }
472
473         if (NULL == callback) {
474                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input parameter is NULL");
475                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
476                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
477                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
478         }
479
480         int ret = tts_setting_dbus_request_get_engine_setting(callback, user_data);
481         if (0 != ret) {
482                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
483         } else {
484                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Foreach engine setting");
485         }
486
487         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
488         SLOG(LOG_DEBUG, TAG_TTSC, " ");
489
490         return ret;
491 }
492
493 int tts_setting_set_engine_setting(const char* key, const char* value)
494 {
495         SLOG(LOG_DEBUG, TAG_TTSC, "===== Set engine setting");
496
497         if (TTS_SETTING_STATE_NONE == g_state) {
498                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Not initialized");
499                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
500                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
501                 return TTS_SETTING_ERROR_INVALID_STATE;
502         }
503
504         if(NULL == key || NULL == value) {
505                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Param is NULL");
506                 SLOG(LOG_DEBUG, TAG_TTSC, "=====");
507                 SLOG(LOG_DEBUG, TAG_TTSC, " ");
508                 return TTS_SETTING_ERROR_INVALID_PARAMETER;
509         }
510
511         int ret = tts_setting_dbus_request_set_engine_setting(key, value);
512         if (0 != ret) {
513                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Result : %d", ret);
514         } else {
515                 SLOG(LOG_DEBUG, TAG_TTSC, "[SUCCESS] Foreach engine setting");
516         }
517
518         SLOG(LOG_DEBUG, TAG_TTSC, "=====");
519         SLOG(LOG_DEBUG, TAG_TTSC, " ");
520
521         return ret;
522 }
523
524
525
526 /* Functions for tts-daemon fork */
527 static bool __tts_is_alive()
528 {
529         FILE *fp = NULL;
530         char buff[256];
531         char cmd[256];
532
533         memset(buff, '\0', sizeof(char) * 256);
534         memset(cmd, '\0', sizeof(char) * 256);
535
536         fp = popen("ps", "r");
537         if (NULL == fp) {
538                 SLOG(LOG_DEBUG, TAG_TTSC, "[TTS SETTING ERROR] popen error");
539                 return FALSE;
540         }
541
542         while (fgets(buff, 255, fp)) {
543                 strcpy(cmd, buff + 26);
544
545                 if( 0 == strncmp(cmd, "[tts-daemon]", strlen("[tts-daemon]")) ||
546                         0 == strncmp(cmd, "tts-daemon", strlen("tts-daemon")) ||
547                         0 == strncmp(cmd, "/usr/bin/tts-daemon", strlen("/usr/bin/tts-daemon"))
548                         ) {
549                         SLOG(LOG_DEBUG, TAG_TTSC, "tts-daemon is ALIVE !!");
550                         fclose(fp);
551                         return TRUE;
552                 }
553
554         }
555         fclose(fp);
556
557         SLOG(LOG_DEBUG, TAG_TTSC, "THERE IS NO tts-daemon !! \n");
558
559         return FALSE;
560 }
561
562 static void __my_sig_child(int signo, siginfo_t *info, void *data)
563 {
564         int status;
565         pid_t child_pid, child_pgid;
566
567         child_pgid = getpgid(info->si_pid);
568         SLOG(LOG_DEBUG, TAG_TTSC, "Signal handler: dead pid = %d, pgid = %d", info->si_pid, child_pgid);
569
570         while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
571                 if(child_pid == child_pgid)
572                         killpg(child_pgid, SIGKILL);
573         }
574
575         return;
576 }
577
578 static int __check_tts_daemon()
579 {
580         if( TRUE == __tts_is_alive() )
581                 return 0;
582
583         /* fork-exec tts-daemom */
584         int pid, i;
585         struct sigaction act, dummy;
586
587         act.sa_handler = NULL;
588         act.sa_sigaction = __my_sig_child;
589         sigemptyset(&act.sa_mask);
590         act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
591
592         if (sigaction(SIGCHLD, &act, &dummy) < 0) {
593                 SLOG(LOG_ERROR, TAG_TTSC, "Cannot make a signal handler");
594                 return -1;
595         }
596
597         pid = fork();
598
599         switch(pid) {
600         case -1:
601                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to create tts-daemon ");
602                 break;
603
604         case 0:
605                 setsid();
606                 for( i = 0 ; i < _NSIG ; i++ )
607                         signal(i, SIG_DFL);
608
609                 execl("/usr/bin/tts-daemon", "/usr/bin/tts-daemon", NULL);
610                 break;
611
612         default:
613                 break;
614         }
615
616         return 0;
617 }