tizen 2.3 release
[framework/system/swap-probe.git] / helper / daforkexec.c
1 /*
2  *  DA probe
3  *
4  * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Vitaliy Cherepanov <v.cherepanov@samsung.com>
9  *
10  * This library is free software; you can redistribute it and/or modify it under
11  * the terms of the GNU Lesser General Public License as published by the
12  * Free Software Foundation; either version 2.1 of the License, or (at your option)
13  * any later version.
14  *
15  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
16  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this library; if not, write to the Free Software Foundation, Inc., 51
22  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  *
24  * Contributors:
25  * - Samsung RnD Institute Russia
26  *
27  */
28 #include <sys/types.h>
29 #include <signal.h>
30
31 #include "daprobe.h"
32 #include "dahelper.h"
33 #include "binproto.h"
34 #include "daforkexec.h"
35
36 DECLARE(int, execl , const char *path, const char *arg, ...);
37 DECLARE(int, execlp, const char *file, const char *arg, ...);
38 DECLARE(int, execle, const char *path, const char *arg, ...);//, char * const envp[]);
39 DECLARE(int, execv, const char *path, char *const argv[]);
40 DECLARE(int, execve, const char *filename, char *const argv[],char *const envp[]);
41 DECLARE(int, execvp, const char *file, char *const argv[]);
42 DECLARE(int, execvpe, const char *file, char *const argv[],char *const envp[]);
43 DECLARE(pid_t, fork, void);
44
45 void init_exec_fork()
46 {
47         INIT_FUNC_EXEC(fork);
48         INIT_FUNC_EXEC(execl);
49         INIT_FUNC_EXEC(execlp);
50         INIT_FUNC_EXEC(execle);
51         INIT_FUNC_EXEC(execv);
52         INIT_FUNC_EXEC(execve);
53         INIT_FUNC_EXEC(execvp);
54         INIT_FUNC_EXEC(execvpe);
55 }
56
57 #define prepare_params( FUNCTION , p1, p2)              \
58         va_list ap;                                     \
59         int args_count = 0;                             \
60         int i;                                          \
61                                                         \
62         INIT_FUNC_EXEC( FUNCTION );                     \
63                                                         \
64         va_start(ap, p2);                               \
65         do                                              \
66                 args_count++;                           \
67         while (va_arg(ap, char *));                     \
68         va_end(ap);                                     \
69         args_count += 2 + 1;                            \
70                                                         \
71         char *arg_arr[args_count];                      \
72                                                         \
73         va_start(ap, p2);                               \
74                                                         \
75         arg_arr[0] = (char *)p1;                        \
76         arg_arr[1] = (char *)p2;                        \
77         for (i = 2; i < args_count; i++)                \
78                 arg_arr[i] = va_arg(ap, char *);        \
79                                                         \
80         va_end(ap)
81
82 int _da_call_original(void *funcp, char *args[], int args_count);
83
84 #define print_params(buf, p1, p2)                       \
85         char *p = buf;                                  \
86         char *pp;                                       \
87         va_list par;                                    \
88         p += sprintf(p, "--> %s ", __FUNCTION__);       \
89         p += sprintf(p, "[%d]: <", getpid());           \
90         p += sprintf(p, " \"%s\",", p1);                \
91         p += sprintf(p, " \"%s\",", p2);                \
92         va_start(par, p2);                              \
93         while ( (pp = va_arg(par, char *)) != NULL)     \
94                 p += sprintf(p, " \"%s\",", pp);        \
95         va_end(par);                                    \
96         p += sprintf(p, ">");
97
98 int execl(const char *path, const char *arg, ...)
99 {
100         int res;
101         PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
102
103         _uninit_();
104         prepare_params(execl, path, arg);
105         res = _da_call_original(&execl_p, arg_arr, args_count);
106         _init_();
107
108         PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, res, path);
109         return res;
110 }
111
112 int execlp(const char *file, const char *arg, ...)
113 {
114         int res;
115         PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
116
117         _uninit_();
118         prepare_params(execlp, file, arg);
119         res = _da_call_original(&execlp_p, arg_arr, args_count);
120         _init_();
121
122         PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, file, res);
123         return res;
124 }
125
126 int execle(const char *path, const char *arg, ...
127         /* original func have one more argument but
128          * i can't leave it in code by compilation reasons
129          * so it is commented:
130          *
131          *,__attribute__((unused)) char * const envp[] */
132         )
133 {
134         int res;
135         PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
136
137         _uninit_();
138         prepare_params(execle, path, arg);
139         res = _da_call_original(&execle_p, arg_arr, args_count);
140         _init_();
141
142         PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, path, res);
143         return res;
144 }
145
146 int execv(const char *path, char *const argv[])
147 {
148         int res;
149         PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
150
151         _uninit_();
152         res = execv_p(path, argv);
153         _init_();
154
155         PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, path, res);
156         return res;
157 }
158
159 int execvp(const char *file, char *const argv[])
160 {
161         int res;
162         PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
163
164         _uninit_();
165         res = execvp_p(file, argv);
166         _init_();
167
168         PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, file, res);
169         return res;
170 }
171
172 int execve(const char *filename, char *const argv[],char *const envp[])
173 {
174         int res;
175         PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
176
177         _uninit_();
178         res =  execve_p(filename, argv, envp);
179         _init_();
180
181         PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, filename, res);
182         return res;
183 }
184
185 int execvpe(const char *file, char *const argv[],char *const envp[])
186 {
187         int res;
188         PRINTMSG("%s [%d] ", __FUNCTION__, getpid());
189
190         _uninit_();
191         res =  execvpe_p(file, argv, envp);
192         _init_();
193
194         PRINTWRN("%s(%s, ...) return %d", __FUNCTION__, file, res);
195         return res;
196 }
197
198 pid_t fork(void)
199 {
200         pid_t res = fork_p();
201
202         PRINTMSG("<fork = %d>", res);
203         if (res == 0) {
204                 reset_pid_tid(); /* important reset pid values */
205                 if (gTraceInfo.socket.daemonSock >= 0) {
206                         close(gTraceInfo.socket.daemonSock);
207                         _init_();
208                 }
209         }
210
211         return res;
212 }