4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <sys/types.h>
\r
27 #include <sys/stat.h>
\r
32 #include "ac_sock.h"
\r
33 #include "internal.h"
\r
35 static int __connect_client_sock(int sockfd, const struct sockaddr *saptr, socklen_t salen,
\r
38 static inline void __set_sock_option(int fd, int cli)
\r
41 struct timeval tv = { 5, 200 * 1000 }; /* 5.2 sec */
\r
43 size = AC_SOCK_MAXBUFF;
\r
44 setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
\r
45 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
\r
47 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
\r
50 int _create_server_sock()
\r
52 struct sockaddr_un saddr;
\r
53 struct sockaddr_un p_saddr;
\r
56 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
\r
57 /* support above version 2.6.27*/
\r
59 if(errno == EINVAL) {
\r
60 fd = socket(AF_UNIX, SOCK_STREAM, 0);
\r
62 _E("second chance - socket create error");
\r
71 bzero(&saddr, sizeof(saddr));
\r
72 saddr.sun_family = AF_UNIX;
\r
73 snprintf(saddr.sun_path, UNIX_PATH_MAX, "%s",AC_SOCK_NAME);
\r
74 unlink(saddr.sun_path);
\r
76 if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
\r
81 if (chmod(saddr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
\r
82 /* Flawfinder: ignore*/
\r
83 _E("failed to change the socket permission");
\r
87 __set_sock_option(fd, 0);
\r
89 if (listen(fd, 10) == -1) {
\r
97 int _create_client_sock()
\r
100 struct sockaddr_un saddr = { 0, };
\r
104 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
\r
105 /* support above version 2.6.27*/
\r
107 if (errno == EINVAL) {
\r
108 fd = socket(AF_UNIX, SOCK_STREAM, 0);
\r
110 _E("second chance - socket create error");
\r
114 _E("socket error");
\r
119 saddr.sun_family = AF_UNIX;
\r
120 snprintf(saddr.sun_path, UNIX_PATH_MAX, "%s", AC_SOCK_NAME);
\r
122 ret = __connect_client_sock(fd, (struct sockaddr *)&saddr, sizeof(saddr),
\r
125 _E("maybe peer not launched or peer daed\n");
\r
127 usleep(100 * 1000);
\r
137 __set_sock_option(fd, 1);
\r
142 static int __connect_client_sock(int fd, const struct sockaddr *saptr, socklen_t salen,
\r
151 struct timeval timeout;
\r
153 flags = fcntl(fd, F_GETFL, 0);
\r
154 fcntl(fd, F_SETFL, flags | O_NONBLOCK);
\r
157 if ((ret = connect(fd, (struct sockaddr *)saptr, salen)) < 0) {
\r
158 if (errno != EAGAIN && errno != EINPROGRESS) {
\r
159 fcntl(fd, F_SETFL, flags);
\r
164 /* Do whatever we want while the connect is taking place. */
\r
166 goto done; /* connect completed immediately */
\r
169 FD_SET(fd, &readfds);
\r
170 writefds = readfds;
\r
171 timeout.tv_sec = 0;
\r
172 timeout.tv_usec = nsec;
\r
174 if ((ret = select(fd + 1, &readfds, &writefds, NULL,
\r
175 nsec ? &timeout : NULL)) == 0) {
\r
176 close(fd); /* timeout */
\r
181 if (FD_ISSET(fd, &readfds) || FD_ISSET(fd, &writefds)) {
\r
182 len = sizeof(error);
\r
183 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
\r
184 return (-1); /* Solaris pending error */
\r
186 return (-1); /* select error: sockfd not set*/
\r
189 fcntl(fd, F_SETFL, flags);
\r
199 * @brief Send data (in raw) to the process with 'pid' via socket
\r
201 int _app_send_raw(int cmd, unsigned char *data, int datalen)
\r
206 ac_pkt_t *pkt = NULL;
\r
208 if (data == NULL || datalen > AC_SOCK_MAXBUFF - 8) {
\r
209 _E("keybundle error\n");
\r
213 fd = _create_client_sock();
\r
217 pkt = (ac_pkt_t *) malloc(sizeof(char) * AC_SOCK_MAXBUFF);
\r
219 _E("Malloc Failed!");
\r
222 memset(pkt, 0, AC_SOCK_MAXBUFF);
\r
225 pkt->len = datalen;
\r
226 memcpy(pkt->data, data, datalen);
\r
228 if ((len = send(fd, pkt, datalen + 8, 0)) != datalen + 8) {
\r
229 _E("sendto() failed - %d %d", len, datalen + 8);
\r
230 if (errno == EPIPE) {
\r
245 len = recv(fd, &res, sizeof(int), 0);
\r
247 if (errno == EAGAIN) {
\r
248 _E("recv timeout \n");
\r
251 _E("recv error\n");
\r
255 _D("recv result = %d (%d)", res, len);
\r
261 ac_pkt_t *_app_recv_raw(int fd, int *clifd, struct ucred *cr)
\r
264 struct sockaddr_un aul_addr = { 0, };
\r
266 ac_pkt_t *pkt = NULL;
\r
267 int cl = sizeof(struct ucred);
\r
269 sun_size = sizeof(struct sockaddr_un);
\r
271 if ((*clifd = accept(fd, (struct sockaddr *)&aul_addr,
\r
272 (socklen_t *) &sun_size)) == -1) {
\r
273 if (errno != EINTR)
\r
274 _E("accept error");
\r
278 if (getsockopt(*clifd, SOL_SOCKET, SO_PEERCRED, cr,
\r
279 (socklen_t *) &cl) < 0) {
\r
280 _E("peer information error");
\r
285 pkt = (ac_pkt_t *) malloc(sizeof(char) * AC_SOCK_MAXBUFF);
\r
290 memset(pkt, 0, AC_SOCK_MAXBUFF);
\r
292 __set_sock_option(*clifd, 1);
\r
295 /* receive single packet from socket */
\r
296 len = recv(*clifd, pkt, AC_SOCK_MAXBUFF, 0);
\r
298 if (errno == EINTR)
\r
301 if ((len < 8) || (len != (pkt->len + 8))) {
\r
302 _E("recv error %d %d", len, pkt->len);
\r
311 int _send_result_to_server(int fd, int res)
\r
313 if (send(fd, &res, sizeof(int), MSG_NOSIGNAL) < 0) {
\r
314 if (errno == EPIPE)
\r
315 _E("send failed due to EPIPE.\n");
\r
316 _E("send fail to client");
\r