[Release] wrt_0.8.166 for tizen_2.1 branch
[platform/framework/web/wrt.git] / src / wrt-launchpad-daemon / src / process_pool.c
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
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  * @file    process_pool.c
18  * @author  Tae-Jeong Lee (taejeong.lee@samsung.com)
19  * @version 0.1
20  * @brief   process pool socket apis
21  */
22
23 #include <unistd.h>
24 #include <sys/socket.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <linux/un.h>
28 #include <errno.h>
29 #include <stdio.h>
30
31 #include "process_pool.h"
32 #include "simple_util.h"
33
34 #define TMP_PATH "/tmp"
35 #define PROCESS_POOL_SERVER "wrt_process_pool_server"
36 #define MAX_PENDING_CONNECTIONS 10
37 #define CONNECT_RETRY_TIME 100 * 1000
38 #define CONNECT_RETRY_COUNT 3
39
40 int __create_process_pool_server()
41 {
42     struct sockaddr_un addr;
43     int fd = -1;
44
45     memset(&addr, 0x00, sizeof(struct sockaddr_un));
46
47     fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
48
49     if (fd < 0)
50     {
51         _E("socket error");
52         goto err_create_process_pool_server;
53     }
54
55     addr.sun_family = AF_UNIX;
56     snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", TMP_PATH, PROCESS_POOL_SERVER);
57     unlink(addr.sun_path);
58
59     _D("bind to %s", addr.sun_path);
60     if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
61     {
62         _E("bind error");
63         goto err_create_process_pool_server;
64     }
65
66     _D("chmod to %s", addr.sun_path);
67     if (chmod(addr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0)
68     {
69         _E("chmod error");
70         goto err_create_process_pool_server;
71     }
72
73     _D("listen to %s", addr.sun_path);
74     if (listen(fd, MAX_PENDING_CONNECTIONS) == -1)
75     {
76         _E("listen error");
77         goto err_create_process_pool_server;
78     }
79
80     _D("__create_process_pool_server done : %d", fd);
81     return fd;
82
83
84 err_create_process_pool_server:
85
86     if (fd != -1)
87     {
88         close(fd);
89     }
90
91     return -1;
92 }
93
94
95 int __connect_process_pool_server()
96 {
97     struct sockaddr_un addr;
98     int fd = -1;
99     int retry = CONNECT_RETRY_COUNT;
100     int send_ret = -1;
101     int client_pid = getpid();
102
103     memset(&addr, 0x00, sizeof(struct sockaddr_un));
104
105     fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
106
107     if (fd < 0)
108     {
109         _E("socket error");
110
111         goto err_connect_process_pool_server;
112     }
113
114     addr.sun_family = AF_UNIX;
115     snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%s", TMP_PATH, PROCESS_POOL_SERVER);
116
117
118     _D("connect to %s", addr.sun_path);
119     while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
120     {
121         if (errno != ETIMEDOUT || retry <= 0)
122         {
123             _E("connect error : %d", errno);
124
125             goto err_connect_process_pool_server;
126         }
127
128         usleep(CONNECT_RETRY_TIME);
129         retry--;
130         _D("re-connect to %s (%d)", addr.sun_path, retry);
131     }
132
133     send_ret = send(fd, &client_pid, sizeof(client_pid), 0);
134     _D("send(%d) : %d", client_pid, send_ret);
135
136     if (send_ret == -1)
137     {
138         _E("send error");
139
140         goto err_connect_process_pool_server;
141     }
142
143     _D("__connect_process_pool_server done : %d", fd);
144     return fd;
145
146 err_connect_process_pool_server:
147
148     if (fd != -1)
149     {
150         close(fd);
151     }
152
153     return -1;
154 }
155
156
157 int __accept_dummy_process(int server_fd, int* out_client_fd, int* out_client_pid)
158 {
159     int client_fd = -1, client_pid = 0, recv_ret = 0;
160
161     if (server_fd == -1 || out_client_fd == NULL || out_client_pid == NULL)
162     {
163         _E("arguments error!");
164
165         goto err__accept_dummy_process;
166     }
167
168     client_fd = accept(server_fd, NULL, NULL);
169
170     if (client_fd == -1)
171     {
172         _E("accept error!");
173
174         goto err__accept_dummy_process;
175     }
176
177     recv_ret = recv(client_fd, &client_pid, sizeof(client_pid), MSG_WAITALL);
178
179     if (recv_ret == -1)
180     {
181         _E("recv error!");
182
183         goto err__accept_dummy_process;
184     }
185
186     *out_client_fd = client_fd;
187     *out_client_pid = client_pid;
188
189     return *out_client_fd;
190
191 err__accept_dummy_process:
192
193     if (client_fd != -1)
194     {
195         close(client_fd);
196     }
197
198     return -1;
199 }
200
201 void __refuse_dummy_process(int server_fd)
202 {
203     int client_fd = -1;
204
205     if (server_fd == -1)
206     {
207         _E("arguments error!");
208
209         goto err__refuse_dummy_process;
210     }
211
212     client_fd = accept(server_fd, NULL, NULL);
213
214     if (client_fd == -1)
215     {
216         _E("accept error!");
217
218         goto err__refuse_dummy_process;
219     }
220
221     close(client_fd);
222     _D("refuse connection!");
223
224     return;
225
226 err__refuse_dummy_process:
227
228     if (client_fd != -1)
229     {
230         close(client_fd);
231     }
232
233     return;
234 }
235
236
237 int __send_pkt_raw_data(int client_fd, app_pkt_t* pkt)
238 {
239     int send_ret = 0;
240     int pkt_size = 0;
241
242     if (client_fd == -1 || pkt == NULL)
243     {
244         _E("arguments error!");
245
246         goto err__send_pkt_raw_data;
247     }
248
249     pkt_size = sizeof(pkt->cmd) + sizeof(pkt->len) + pkt->len;
250
251     send_ret = send(client_fd, pkt, pkt_size, 0);
252     _D("send(%d) : %d / %d", client_fd, send_ret, pkt_size);
253
254     if (send_ret == -1)
255     {
256         _E("send error!");
257
258         goto err__send_pkt_raw_data;
259     }
260     else if (send_ret != pkt_size)
261     {
262         _E("send byte fail!");
263
264         goto err__send_pkt_raw_data;
265     }
266
267     return 0;
268
269 err__send_pkt_raw_data:
270
271     return -1;
272 }