fixed term timer cb bug
[framework/appfw/aul-1.git] / am_daemon / amd_status.c
1 /*
2  *  aul
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <glib.h>
25 #include <aul.h>
26 #include <string.h>
27 #include <Ecore.h>
28
29 #include "amd_config.h"
30 #include "amd_status.h"
31 #include "amd_appinfo.h"
32 #include "aul_util.h"
33 #include "simple_util.h"
34 #include "app_sock.h"
35 #include "menu_db_util.h"
36
37 GSList *app_status_info_list = NULL;
38
39 struct appinfomgr *_saf = NULL;
40
41 int _status_add_app_info_list(char *appid, char *app_path, int pid)
42 {
43         GSList *iter = NULL;
44         app_status_info_t *info_t = NULL;
45
46         for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
47         {
48                 info_t = (app_status_info_t *)iter->data;
49                 if(pid == info_t->pid) {
50                         return 0;
51                 }
52         }
53
54         info_t = malloc(sizeof(app_status_info_t));
55         strncpy(info_t->appid, appid, MAX_PACKAGE_STR_SIZE-1);
56         strncpy(info_t->app_path, app_path, MAX_PACKAGE_APP_PATH_SIZE-1);
57         info_t->status = STATUS_LAUNCHING;
58         info_t->pid = pid;
59         app_status_info_list = g_slist_append(app_status_info_list, info_t);
60
61         for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
62         {
63                 info_t = (app_status_info_t *)iter->data;
64
65                 _D("%s, %d, %d", info_t->appid, info_t->pid, info_t->status);
66         }
67
68         return 0;
69 }
70
71 static Eina_Bool __app_terminate_timer_cb(void *data)
72 {
73         int pid = (int)data;
74         int ret = 0;
75
76         _D("pid(%d)", pid);
77
78         ret = kill(pid, SIGKILL);
79         if (ret == -1)
80                 _E("send SIGKILL: %s", strerror(errno));
81
82         return ECORE_CALLBACK_CANCEL;
83 }
84
85 int _status_update_app_info_list(int pid, int status)
86 {
87         GSList *iter = NULL;
88         app_status_info_t *info_t = NULL;
89
90         for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
91         {
92                 info_t = (app_status_info_t *)iter->data;
93                 if(pid == info_t->pid) {
94                         info_t->status = status;
95                         if(status == STATUS_DYING) {
96                                 ecore_timer_add(2, __app_terminate_timer_cb, info_t->pid);
97                         }
98                         break;
99                 }
100         }
101
102         for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
103         {
104                 info_t = (app_status_info_t *)iter->data;
105
106                 _D("%s, %d, %d", info_t->appid, info_t->pid, info_t->status);
107         }
108
109         return 0;
110 }
111
112 int _status_remove_app_info_list(int pid)
113 {
114         GSList *iter = NULL;
115         app_status_info_t *info_t = NULL;
116
117         for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
118         {
119                 info_t = (app_status_info_t *)iter->data;
120                 if(pid == info_t->pid) {
121                         app_status_info_list = g_slist_remove(app_status_info_list, info_t);
122                         free(info_t);
123                         break;
124                 }
125         }
126
127         for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
128         {
129                 info_t = (app_status_info_t *)iter->data;
130
131                 _D("%s, %d, %d", info_t->appid, info_t->pid, info_t->status);
132         }
133
134         return 0;
135 }
136
137 int _status_get_app_info_status(int pid)
138 {
139         GSList *iter = NULL;
140         app_status_info_t *info_t = NULL;
141
142         for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
143         {
144                 info_t = (app_status_info_t *)iter->data;
145                 if(pid == info_t->pid) {
146                         return info_t->status;
147                 }
148         }
149 }
150
151
152 int _status_app_is_running(char *appid)
153 {
154         GSList *iter = NULL;
155         app_status_info_t *info_t = NULL;
156
157         for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
158         {
159                 info_t = (app_status_info_t *)iter->data;
160                 if( strncmp(appid, info_t->appid, MAX_PACKAGE_STR_SIZE) == 0 ) {
161                         return info_t->pid;
162                 }
163         }
164         return -1;
165 }
166
167 int _status_send_running_appinfo(int fd)
168 {
169         GSList *iter = NULL;
170         app_status_info_t *info_t = NULL;
171         app_pkt_t *pkt = NULL;
172         int len;
173         char tmp_pid[MAX_PID_STR_BUFSZ];
174
175         pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
176         if(!pkt) {
177                 _E("malloc fail");
178                 return 0;
179         }
180
181         memset(pkt, 0, AUL_SOCK_MAXBUFF);
182
183         for (iter = app_status_info_list; iter != NULL; iter = g_slist_next(iter))
184         {
185                 info_t = (app_status_info_t *)iter->data;
186                 snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", info_t->pid);
187                 strncat((char *)pkt->data, tmp_pid, MAX_PID_STR_BUFSZ);
188                 strncat((char *)pkt->data, ":", 1);
189                 strncat((char *)pkt->data, info_t->appid, MAX_PACKAGE_STR_SIZE);
190                 strncat((char *)pkt->data, ":", 1);
191                 strncat((char *)pkt->data, info_t->app_path, MAX_PACKAGE_APP_PATH_SIZE);
192                 strncat((char *)pkt->data, ";", 1);
193         }
194
195         pkt->cmd = APP_RUNNING_INFO_RESULT;
196         pkt->len = strlen((char *)pkt->data) + 1;
197
198         if ((len = send(fd, pkt, pkt->len + 8, 0)) != pkt->len + 8) {
199                 if (errno == EPIPE)
200                         _E("send failed due to EPIPE.\n");
201                 _E("send fail to client");
202         }
203
204         if(pkt)
205                 free(pkt);
206
207         close(fd);
208
209         return 0;
210 }
211
212 int _status_app_is_running_v2(char *appid)
213 {
214         char *apppath = NULL;
215         int ret = 0;
216         int i = 0;
217         const struct appinfo *ai;
218
219         if(appid == NULL)
220                 return -1;
221
222         ai = appinfo_find(_saf, appid);
223
224         if(ai == NULL)
225                 return -1;
226
227         apppath = strdup(appinfo_get_value(ai, AIT_EXEC));
228
229         /*truncate apppath if it includes default bundles */
230         while (apppath[i] != 0) {
231                 if (apppath[i] == ' ' || apppath[i] == '\t') {
232                         apppath[i]='\0';
233                         break;
234                 }
235                 i++;
236         }
237
238         ret = __proc_iter_cmdline(NULL, apppath);
239
240         free(apppath);
241
242         return ret;
243 }
244
245 static int __get_pkginfo(const char *dname, const char *cmdline, void *priv)
246 {
247         app_info_from_db *menu_info;
248         char *r_info;
249
250         r_info = (char *)priv;
251
252         if ((menu_info = _get_app_info_from_db_by_apppath(cmdline)) == NULL)
253                 goto out;
254         else {
255                 strncat(r_info, dname, 8);
256                 strncat(r_info, ":", 1);
257                 strncat(r_info, _get_pkgname(menu_info), MAX_PACKAGE_STR_SIZE);
258                 strncat(r_info, ":", 1);
259                 strncat(r_info, _get_app_path(menu_info), MAX_PACKAGE_APP_PATH_SIZE);
260                 strncat(r_info, ";", 1);
261         }
262
263  out:
264         if (menu_info != NULL)
265                 _free_app_info_from_db(menu_info);
266         return 0;
267 }
268
269 int _status_send_running_appinfo_v2(int fd)
270 {
271         app_pkt_t *pkt = NULL;
272         int len;
273
274         pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
275         if(!pkt) {
276                 _E("malloc fail");
277                 close(fd);
278                 return 0;
279         }
280
281         memset(pkt, 0, AUL_SOCK_MAXBUFF);
282
283         __proc_iter_cmdline(__get_pkginfo, pkt->data);
284
285         pkt->cmd = APP_RUNNING_INFO_RESULT;
286         pkt->len = strlen((char *)pkt->data) + 1;
287
288         if ((len = send(fd, pkt, pkt->len + 8, 0)) != pkt->len + 8) {
289                 if (errno == EPIPE)
290                         _E("send failed due to EPIPE.\n");
291                 _E("send fail to client");
292         }
293
294         if(pkt)
295                 free(pkt);
296
297         close(fd);
298
299         return 0;
300 }
301
302 static int __get_pkgname_bypid(int pid, char *pkgname, int len)
303 {
304         char *cmdline;
305         app_info_from_db *menu_info;
306
307         cmdline = __proc_get_cmdline_bypid(pid);
308         if (cmdline == NULL)
309                 return -1;
310
311         if ((menu_info = _get_app_info_from_db_by_apppath(cmdline)) == NULL) {
312                 free(cmdline);
313                 return -1;
314         } else {
315                 snprintf(pkgname, len, "%s", _get_pkgname(menu_info));
316         }
317
318         free(cmdline);
319         _free_app_info_from_db(menu_info);
320
321         return 0;
322 }
323
324 int _status_get_appid_bypid(int fd, int pid)
325 {
326         app_pkt_t *pkt = NULL;
327         int len;
328         int pgid;
329
330         pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
331         if(!pkt) {
332                 _E("malloc fail");
333                 close(fd);
334                 return 0;
335         }
336
337         memset(pkt, 0, AUL_SOCK_MAXBUFF);
338
339         pkt->cmd = APP_GET_APPID_BYPID_ERROR;
340
341         if (__get_pkgname_bypid(pid, (char *)pkt->data, MAX_PACKAGE_STR_SIZE) == 0) {
342                 _D("appid for %d is %s", pid, pkt->data);
343                 pkt->cmd = APP_GET_APPID_BYPID_OK;
344                 goto out;
345         }
346         /* support app launched by shell script*/
347         _D("second chance");
348         pgid = getpgid(pid);
349         if (pgid <= 1)
350                 goto out;
351
352         _D("second change pgid = %d, pid = %d", pgid, pid);
353         if (__get_pkgname_bypid(pgid, (char *)pkt->data, MAX_PACKAGE_STR_SIZE) == 0)
354                 pkt->cmd = APP_GET_APPID_BYPID_OK;
355
356  out:
357         pkt->len = strlen((char *)pkt->data) + 1;
358
359         if ((len = send(fd, pkt, pkt->len + 8, 0)) != pkt->len + 8) {
360                 if (errno == EPIPE)
361                         _E("send failed due to EPIPE.\n");
362                 _E("send fail to client");
363         }
364
365         if(pkt)
366                 free(pkt);
367
368         close(fd);
369
370         return 0;
371 }
372
373
374 int _status_init(struct amdmgr* amd)
375 {
376         _saf = amd->af;
377
378         return 0;
379 }
380