4 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include <sensor_log.h>
22 #include <attr/xattr.h>
28 , m_sock_type(SOCK_STREAM)
29 , m_send_flags(MSG_NOSIGNAL)
30 , m_recv_flags(MSG_NOSIGNAL)
32 memset(&m_addr, 0, sizeof(m_addr));
35 csocket::csocket(int sock_fd)
37 , m_sock_type(SOCK_STREAM)
38 , m_send_flags(MSG_NOSIGNAL)
39 , m_recv_flags(MSG_NOSIGNAL)
43 memset(&m_addr, 0, sizeof(m_addr));
46 csocket::csocket(const csocket &sock)
48 , m_sock_type(SOCK_STREAM)
49 , m_send_flags(MSG_NOSIGNAL)
50 , m_recv_flags(MSG_NOSIGNAL)
55 m_sock_fd = sock.m_sock_fd;
56 m_sock_type = sock.m_sock_type;
57 m_send_flags = sock.m_send_flags;
58 m_recv_flags = sock.m_recv_flags;
60 memcpy(&m_addr, &sock.m_addr, sizeof(sockaddr_un));
63 csocket::~csocket() { }
65 bool csocket::create(int sock_type)
67 m_sock_fd = socket(AF_UNIX, sock_type, 0);
70 _ERRNO(errno, _E, "Failed to create socket for %s", get_client_name());
74 m_sock_type = sock_type;
79 bool csocket::bind(const char *sock_path)
85 _E("%s's socket is invalid", get_client_name());
89 if (!access(sock_path, F_OK)) {
93 m_addr.sun_family = AF_UNIX;
95 strncpy(m_addr.sun_path, sock_path, strlen(sock_path));
97 length = strlen(m_addr.sun_path) + sizeof(m_addr.sun_family);
99 if (::bind(m_sock_fd, (struct sockaddr *)&m_addr, length) < 0) {
100 _ERRNO(errno, _E, "Failed to bind for socket[%d]", m_sock_fd);
105 socket_mode = (S_IRWXU | S_IRWXG | S_IRWXO);
106 if (chmod(sock_path, socket_mode) < 0) {
107 _ERRNO(errno, _E, "Failed to chmod for socket[%d]", m_sock_fd);
115 bool csocket::listen(const int max_connections)
118 _E("Socket(%d) is invalid", m_sock_fd);
122 if (::listen(m_sock_fd, max_connections) < 0) {
123 _ERRNO(errno, _E, "Failed to listen for socket[%d]", m_sock_fd);
131 bool csocket::accept(csocket& client_socket) const
133 const int TIMEOUT = 1;
135 int addr_length = sizeof(m_addr);
142 FD_SET(m_sock_fd, &read_fds);
147 err = ::select(m_sock_fd + 1, &read_fds, NULL, NULL, &tv);
149 _ERRNO(errno, _E, "Failed to select(), m_sock_fd : %d", m_sock_fd);
154 _E("socket is closed, m_sock_fd : %d", m_sock_fd);
162 if (FD_ISSET(m_sock_fd, &read_fds))
165 _ERRNO(errno, _E, "Failed to select(), msock_fd : %d", m_sock_fd);
169 _E("socket is closed, m_sock_fd : %d", m_sock_fd);
174 client_socket.m_sock_fd = ::accept(m_sock_fd, (sockaddr *)&m_addr, (socklen_t *)&addr_length);
175 if (!client_socket.is_valid())
177 } while (err == EINTR);
179 if (!client_socket.is_valid()) {
180 _ERRNO(errno, _E, "Failed to accept for socket[%d]", m_sock_fd);
187 ssize_t csocket::send_for_seqpacket(const void *buffer, size_t size) const
192 len = ::send(m_sock_fd, buffer, size, m_send_flags);
193 err = len < 0 ? errno : 0;
194 } while (err == EINTR);
197 _ERRNO(errno, _E, "Failed to send(%d, %#x, %d, %#x) = %d",
198 m_sock_fd, buffer, size, m_send_flags, len);
201 return err == 0 ? len : -err;
204 ssize_t csocket::recv_for_seqpacket(void* buffer, size_t size) const
209 len = ::recv(m_sock_fd, buffer, size, m_recv_flags);
213 } else if (len == 0) {
214 _E("recv(%d, %#p , %d) = %d, because the peer performed shutdown!",
215 m_sock_fd, buffer, size, len);
220 } while (err == EINTR);
222 if ((err == EAGAIN) || (err == EWOULDBLOCK))
226 _ERRNO(err, _E, "Failed to recv(%d, %#x, %d, %#x) = %d",
227 m_sock_fd, buffer, size, m_recv_flags, len);
230 return err == 0 ? len : -err;
233 ssize_t csocket::send_for_stream(const void *buffer, size_t size) const
237 size_t total_sent_size = 0;
240 len = ::send(m_sock_fd, (const void *)((uint8_t *)buffer + total_sent_size), size - total_sent_size, m_send_flags);
243 total_sent_size += len;
246 _ERRNO(errno, _E, "Failed to send(%d, %#p + %d, %d - %d) = %d for %s",
247 m_sock_fd, buffer, total_sent_size, size, total_sent_size,
248 len, get_client_name());
251 * If socket is not available to use it temporarily,
252 * EAGAIN(EWOULDBLOCK) is returned by ::send().
253 * so in order to prevent that data are omitted, retry to send it
255 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
260 if (errno != EINTR) {
265 } while (total_sent_size < size);
267 return err == 0 ? total_sent_size : -err;
270 ssize_t csocket::recv_for_stream(void* buffer, size_t size) const
274 size_t total_recv_size = 0;
277 len = ::recv(m_sock_fd, (void *)((uint8_t *)buffer + total_recv_size), size - total_recv_size, m_recv_flags);
280 total_recv_size += len;
281 } else if (len == 0) {
282 _E("recv(%d, %#p + %d, %d - %d) = %d, because the peer of %s performed shutdown!",
283 m_sock_fd, buffer, total_recv_size, size, total_recv_size, len, get_client_name());
287 _ERRNO(errno, _E, "Failed to recv(%d, %#p + %d, %d - %d) = %d for %s",
288 m_sock_fd, buffer, total_recv_size, size, total_recv_size,
289 len, get_client_name());
292 * If socket is not available to use during for some time,
293 * EAGAIN(EWOULDBLOCK) is returned by ::recv().
294 * so in order to prevent that data are omitted, retry to receive it
296 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
301 if (errno != EINTR) {
306 } while (total_recv_size < size);
308 return err == 0 ? total_recv_size : -err;
311 ssize_t csocket::send(const void *buffer, size_t size) const
314 _E("Socket(%d) is invalid", m_sock_fd);
318 if (m_sock_type == SOCK_STREAM)
319 return send_for_stream(buffer, size);
321 return send_for_seqpacket(buffer, size);
324 ssize_t csocket::recv(void* buffer, size_t size) const
327 _E("Socket(%d) is invalid", m_sock_fd);
331 if (m_sock_type == SOCK_STREAM)
332 return recv_for_stream(buffer, size);
334 return recv_for_seqpacket(buffer, size);
337 bool csocket::connect(const char *sock_path)
339 const int TIMEOUT = 5;
343 bool prev_blocking_mode;
346 _E("%s's socket is invalid", get_client_name());
350 prev_blocking_mode = is_blocking_mode();
352 set_blocking_mode(false);
354 m_addr.sun_family = AF_UNIX;
356 strncpy(m_addr.sun_path, sock_path, strlen(sock_path));
358 addr_len = strlen(m_addr.sun_path) + sizeof(m_addr.sun_family);
360 if (::connect(m_sock_fd, (sockaddr *) &m_addr, addr_len) < 0) {
361 _ERRNO(errno, _E, "Failed to connect sock_fd: %d for %s",
362 m_sock_fd, get_client_name());
367 FD_SET(m_sock_fd, &write_fds);
373 ret = select(m_sock_fd + 1, NULL, &write_fds, NULL, &tv);
376 _ERRNO(errno, _E, "select error: sock_fd: %d\n for %s", m_sock_fd, get_client_name());
380 _ERRNO(errno, _E, "select timeout: %d seconds elapsed for %s", tv.tv_sec, get_client_name());
385 if (!FD_ISSET(m_sock_fd, &write_fds)) {
386 _ERRNO(errno, _E, "select failed for %s, nothing to write, m_sock_fd : %d", get_client_name(), m_sock_fd);
392 socklen_t len = sizeof(so_error);
394 if (getsockopt(m_sock_fd, SOL_SOCKET, SO_ERROR, &so_error, &len) == -1) {
395 _ERRNO(errno, _E, "getsockopt failed for %s, m_sock_fd : %d", get_client_name(), m_sock_fd);
401 _ERRNO(errno, _E, "SO_ERROR occurred for %s, m_sock_fd : %d, so_error : %d",
402 get_client_name(), m_sock_fd, so_error);
407 if (prev_blocking_mode)
408 set_blocking_mode(true);
413 bool csocket::set_blocking_mode(bool blocking)
418 _E("Socket(%d) is invalid", m_sock_fd);
422 flags = fcntl(m_sock_fd, F_GETFL);
425 _ERRNO(errno, _E, "fcntl(F_GETFL) failed for %s, m_sock_fd: %d", get_client_name(), m_sock_fd);
429 flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
431 flags = fcntl(m_sock_fd, F_SETFL, flags);
434 _ERRNO(errno, _E, "fcntl(F_SETFL) failed for %s, m_sock_fd: %d", get_client_name(), m_sock_fd);
441 bool csocket::set_sock_type(void)
446 opt_len = sizeof(sock_type);
449 _E("Socket(%d) is invalid", m_sock_fd);
453 if (getsockopt(m_sock_fd, SOL_SOCKET, SO_TYPE, &sock_type, &opt_len) < 0) {
454 _ERRNO(errno, _E, "getsockopt(SOL_SOCKET, SO_TYPE) failed for %s, m_sock_fd: %d",
455 get_client_name(), m_sock_fd);
459 m_sock_type = sock_type;
463 bool csocket::set_connection_mode(void)
466 const int TIMEOUT = 5;
468 set_blocking_mode(true);
474 _E("Socket(%d) is invalid", m_sock_fd);
478 if (setsockopt(m_sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
479 _ERRNO(errno, _E, "Set SO_RCVTIMEO failed for %s, m_sock_fd : %d", get_client_name(), m_sock_fd);
484 m_send_flags = MSG_NOSIGNAL;
485 m_recv_flags = MSG_NOSIGNAL;
490 bool csocket::set_transfer_mode(void)
492 set_blocking_mode(false);
494 m_send_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
495 m_recv_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
500 bool csocket::is_blocking_mode(void)
505 _E("Socket(%d) is invalid", m_sock_fd);
509 flags = fcntl(m_sock_fd, F_GETFL);
512 _ERRNO(errno, _E, "fcntl(F_GETFL) failed for %s, m_sock_fd: %d", get_client_name(), m_sock_fd);
516 return !(flags & O_NONBLOCK);
519 bool csocket::is_valid(void) const
521 return (m_sock_fd >= 0);
524 int csocket::get_socket_fd(void) const
529 bool csocket::close(void)
531 if (m_sock_fd >= 0) {
532 if (::close(m_sock_fd) < 0) {
533 _ERRNO(errno, _E, "Failed to close socket[%d]", m_sock_fd);