e9649173d5c43cfe8fc36b7e7b4ddcd8cc607454
[framework/appfw/aul-1.git] / legacy / preload.h
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
23 #ifdef PRELOAD_ACTIVATE 
24
25 #include <dlfcn.h>
26 #define PRELOAD_FILE RW_DATA_PREFIX"/preload_list.txt"
27
28 #define EFL_PREINIT_FUNC        "elm_quicklaunch_init"
29 #define EFL_SHUTDOWN_FUNC       "elm_quicklaunch_shutdown"
30
31 static int preload_initialized = 0;
32 static int g_argc;
33 static char **g_argv;
34 static int max_cmdline_size = 0;
35
36 static int (*dl_einit) () = NULL;
37 static int (*dl_efini) () = NULL;
38
39 static inline void __preload_init(int argc, char **argv)
40 {
41         void *handle = NULL;
42         char soname[MAX_LOCAL_BUFSZ];
43         FILE *preload_list;
44         int (*func)() = NULL;
45         int i;
46
47         g_argc = argc;
48         g_argv = argv;
49         for (i = 0; i < argc; i++) {
50                 max_cmdline_size += (strlen(argv[i]) + 1);
51         }
52         _D("max_cmdline_size = %d", max_cmdline_size);
53
54         preload_list = fopen(PRELOAD_FILE, "rt");
55         if (preload_list == NULL) {
56                 _E("no preload\n");
57                 return;
58         }
59
60         while (fgets(soname, MAX_LOCAL_BUFSZ, preload_list) > 0) {
61                 soname[strlen(soname) - 1] = 0;
62                 handle = dlopen(soname, RTLD_NOW);
63                 if (handle == NULL)
64                         continue;
65                 _D("preload %s# - handle : %x\n", soname, handle);
66
67                 func = dlsym(handle, EFL_PREINIT_FUNC);
68                 if (func != NULL) {
69                         _D("get pre-initialization function\n");
70                         dl_einit = func;
71                         func = dlsym(handle, EFL_SHUTDOWN_FUNC);
72                         if (func != NULL) {
73                                 _D("get shutdown function\n");
74                                 dl_efini = func;
75                         }
76                 }
77         }
78
79         fclose(preload_list);
80         preload_initialized = 1;
81 }
82
83 static inline int preinit_init()
84 {
85         if (dl_einit != NULL)
86                 dl_einit(0, NULL);
87         _D("pre-initialzation on");
88         return 0;
89 }
90
91 static inline int preinit_fini()
92 {
93         if (dl_efini != NULL)
94                 dl_efini();
95         _D("pre-initialization off");
96         return 0;
97 }
98
99 /* TODO : how to set cmdline gracefully ?? */
100 static inline int __change_cmdline(char *cmdline)
101 {
102         if (strlen(cmdline) > max_cmdline_size + 1) {
103                 _E("cmdline exceed max size : %d", max_cmdline_size);
104                 return -1;
105         }
106
107         memset(g_argv[0], '\0', max_cmdline_size);
108         snprintf(g_argv[0], max_cmdline_size, "%s", cmdline);
109
110         return 0;
111 }
112
113 static inline void __preload_exec(int argc, char **argv)
114 {
115         void *handle = NULL;
116         int (*dl_main) (int, char **);
117
118         if (!preload_initialized)
119                 return;
120
121         handle = dlopen(argv[0], RTLD_LAZY | RTLD_GLOBAL);
122         if (handle == NULL) {
123                 return;
124         }
125
126         dl_main = dlsym(handle, "main");
127         if (dl_main != NULL) {
128                 if (__change_cmdline(argv[0]) < 0) {
129                         _E("change cmdline fail");
130                         return;
131                 }
132                 dl_main(argc, argv);
133         } else {
134                 _E("dlsym not founded. bad preloaded app - check fpie pie");
135         }
136
137         exit(0);
138 }
139
140 #else
141
142 static inline void __preload_init();
143 static inline void __preload_exec(int argc, char **argv);
144
145 #endif
146