4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@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 "ipc-socket.h"
24 #include "ipc-library-build.h"
25 #include "emf-dbglog.h"
26 #include "emf-types.h"
28 #include <sys/socket.h>
30 #include <sys/ioctl.h>
31 #include <sys/types.h>
39 ipcEmailSocket::ipcEmailSocket() : maxfd(-1)
41 m_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
43 EM_DEBUG_LOG("fd = %d", m_sockfd);
46 EM_DEBUG_LOG("socket creation fails!!!: %s", strerror(errno));
53 ipcEmailSocket::~ipcEmailSocket()
57 EM_DEBUG_LOG("socket object is destoryed");
61 void ipcEmailSocket::Close()
66 EM_DEBUG_LOG("sockfd = [%d] is closed", m_sockfd);
69 void ipcEmailSocket::Close(int fd)
71 EM_DEBUG_FUNC_BEGIN("fd [%d]",fd);
74 EM_DEBUG_LOG("server_socket not init");
78 EM_DEBUG_LOG("%d to be removed", fd);
81 std::map<int, int>::iterator it = mapFds.find(fd);
82 if(it == mapFds.end()) {
83 EM_DEBUG_LOG("No matching socket fd [%d]", fd);
90 for( it = mapFds.begin() ; it != mapFds.end() ; it++ )
91 newmax = (it->second > newmax )? it->second : newmax;
94 EM_DEBUG_LOG("fd %d removal done", fd);
99 bool ipcEmailSocket::IsConnected()
104 int ipcEmailSocket::writen (int fd, const char *buf, int len)
110 nwrite = ::send(fd, (const void*) buf, nleft, MSG_NOSIGNAL);
111 /* nwrite = ::write(fd, (const void*) buf, nleft); */
113 EM_DEBUG_LOG("write: %s", EM_STRERROR(errno));
114 if (errno == EINTR) continue;
116 } else if ( nwrite == 0 )
125 int ipcEmailSocket::Send(int fd, char* buffer, int buf_len)
127 EM_DEBUG_FUNC_BEGIN("fd [%d], buffer [%p], buf_len [%d]", fd, buffer, buf_len);
130 EM_DEBUG_EXCEPTION("No data to send");
136 EM_DEBUG_EXCEPTION("Socket is not connected.");
141 int send_bytes = sizeof(int)+buf_len;
142 char buf[send_bytes];
143 memcpy(buf, (char*) &buf_len, sizeof(int)); /* write buffer lenth */
144 memcpy(buf + sizeof(int), buffer, buf_len); /* write buffer */
146 EM_DEBUG_LOG("Sending %dB data to [fd = %d] ", send_bytes, fd);
147 int nRet = writen(fd, buf, send_bytes);
152 EM_DEBUG_LOG("Sending %dB data to [fd = %d] ", buf_len, fd);
153 int n = writen(fd, buffer, buf_len);
156 EM_DEBUG_LOG("WARNING: write buf_size[%d] != send_len [%d]", n, buf_len);
165 int ipcEmailSocket::readn( int fd, char *buf, int len )
171 nread = ::read(fd, (void*)buf, nleft);
173 EM_DEBUG_EXCEPTION("read: %s", strerror(errno));
174 if (errno == EINTR) continue;
176 } else if( nread == 0 )
185 int ipcEmailSocket::Recv(int fd, char** buffer)
187 EM_DEBUG_FUNC_BEGIN();
189 EM_DEBUG_LOG("buffer MUST NOT NULL");
193 /* read the data size first and store it to len */
196 EM_DEBUG_LOG("[IPC Socket] Receiving header begins");
197 n = readn(fd, (char*) &len, sizeof(int));
198 EM_DEBUG_LOG("[IPC Socket] Receiving header %dB data", len);
200 if ( n == 0 ) /* if service gets down, it signals to all IPC clients */
201 return n; else if ( n != sizeof(int) ) {
202 EM_DEBUG_LOG("WARNING: read header_size[%d] not matched [%d]", n, sizeof(int));
205 /* if( ioctl(fd, FIONREAD, &len) == -1 ) {
206 EM_DEBUG_LOG("FIONREAD %s", EM_STRERROR(errno));
210 /* alloc buffer and read data */
211 *buffer = new char[len];
213 EM_DEBUG_LOG("[IPC Socket] Receiving Body begins for [%d] bytes", len);
214 n = readn(fd, *buffer, len);
218 EM_DEBUG_LOG("WARNING: read buf_size [%d] != read_len[%d]", n, len);
222 EM_DEBUG_LOG("[IPC Socket] Receiving [%d] bytes Completed", len);
227 int ipcEmailSocket::GetSocketID()
233 int ipcEmailSocket::accept()
235 EM_DEBUG_FUNC_BEGIN();
237 if (m_sockfd == -1) {
238 EM_DEBUG_LOG("server_socket not init");
242 struct sockaddr_un remote;
244 int t = sizeof(remote);
245 int fd = ::accept(m_sockfd, (struct sockaddr *)&remote, (socklen_t*) &t);
247 EM_DEBUG_LOG("accept: %s", EM_STRERROR(errno));
252 EM_DEBUG_LOG("%d is added", fd);
258 int ipcEmailSocket::open(const char* path)
260 EM_DEBUG_FUNC_BEGIN("path [%s]", path);
262 if (!path || strlen(path) > 108) {
263 EM_DEBUG_LOG("path is null");
267 if ( m_sockfd <= 0 ) {
268 EM_DEBUG_LOG("Server_socket not created %d", m_sockfd);
272 struct sockaddr_un local;
274 local.sun_family = AF_UNIX;
275 strcpy(local.sun_path, path);
276 unlink(local.sun_path);
278 int len = strlen(local.sun_path) + sizeof(local.sun_family);
280 if (bind(m_sockfd, (struct sockaddr *)&local, len) == -1) {
281 EM_DEBUG_LOG("bind: %s", strerror(errno));
286 * determine permission of socket file
288 * - S_IRWXU : for user, allow read and write and execute
289 * - S_IRWXG : for group, allow read and write and execute
290 * - S_IRWXO : for other, allow read and write and execute
292 * - S_IRUSR, S_IWUSR, S_IXUSR : for user, allow only read, write, execute respectively
293 * - S_IRGRP, S_IWGRP, S_IXGRP : for group, allow only read, write, execute respectively
294 * - S_IROTH, S_IWOTH, S_IXOTH : for other, allow only read, write, execute respectively
296 mode_t sock_mode = (S_IRWXU | S_IRWXG | S_IRWXO); /* has 777 permission */
298 if (chmod(path, sock_mode) == -1) {
299 EM_DEBUG_LOG("chmod: %s", strerror(errno));
303 if (listen(m_sockfd, 10) == -1) {
304 EM_DEBUG_LOG("listen: %s", strerror(errno));
315 int ipcEmailSocket::Connect()
317 EM_DEBUG_FUNC_BEGIN();
319 struct sockaddr_un serverSA;
320 serverSA.sun_family = AF_UNIX;
321 strcpy(serverSA.sun_path, EM_SOCKET_PATH); /* "./socket" */
323 int len = strlen(serverSA.sun_path) + sizeof(serverSA.sun_family);
325 if (::connect(m_sockfd, (struct sockaddr *)&serverSA, len) == -1) {
326 EM_DEBUG_LOG("cannot connect server %s", strerror(errno));
330 /* add fd for select() */
337 void ipcEmailSocket::addfd(int fd)
339 EM_DEBUG_LOG("%d added", fd);
342 std::map<int, int>::iterator it = mapFds.find(fd);
343 if(it != mapFds.end()) {
344 EM_DEBUG_LOG("Duplicate FD %d", fd);