X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcommon%2Fsocket%2Fabstract_socket.cc;h=02ef6d41fca9b88e069914b6f0a408fa576c5a20;hb=79d7bb153b2d90c5c61204b7d8f6af9e388afc2a;hp=b730cc124205d7f3807cbd80cb13786a97a0501d;hpb=696ade0d1e11c96ddda6fc6257c72c475179ea48;p=platform%2Fcore%2Fappfw%2Fpkgmgr-info.git diff --git a/src/common/socket/abstract_socket.cc b/src/common/socket/abstract_socket.cc index b730cc1..02ef6d4 100644 --- a/src/common/socket/abstract_socket.cc +++ b/src/common/socket/abstract_socket.cc @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "abstract_socket.hh" + #include #include #include @@ -21,8 +23,9 @@ #include #include -#include "debug.h" -#include "abstract_socket.hh" +#include "utils/logging.hh" + +#include "pkgmgrinfo_debug.h" namespace pkgmgr_common { namespace socket { @@ -30,17 +33,22 @@ namespace socket { AbstractSocket::AbstractSocket(std::string path) : path_(std::move(path)), fd_(-1), addr_{} {} -AbstractSocket::AbstractSocket(int fd) : fd_(fd), addr_{} {} +AbstractSocket::AbstractSocket(int fd) : fd_(fd), addr_{} { + GetFdInfo(); +} -AbstractSocket::~AbstractSocket() { Destroy(); } +AbstractSocket::~AbstractSocket() { + Disconnect(); +} int AbstractSocket::SendData(const void* buf, unsigned int size) { auto buffer = static_cast(buf); unsigned int left = size; + while (left) { ssize_t send_byte = send(fd_, buffer, left, MSG_NOSIGNAL); if (send_byte < 0) { - LOGE("send() is failed. fd(%d), errno(%d)", fd_, errno); + LOG(ERROR) << "send() is failed. fd: " << fd_ << ", errno:" << errno; return -ECOMM; } @@ -53,28 +61,47 @@ int AbstractSocket::SendData(const void* buf, unsigned int size) { int AbstractSocket::ReceiveData(void* buf, unsigned int size) { bool is_blocking = true; - if (fcntl(fd_, F_GETFL, 0) & O_NONBLOCK) is_blocking = false; + int retry_count = 20; + int block_retry_count = 5; + + if (fcntl(fd_, F_GETFL, 0) & O_NONBLOCK) + is_blocking = false; auto buffer = static_cast(buf); unsigned int left = size; while (left) { ssize_t recv_byte = recv(fd_, buffer, left, 0); if (recv_byte == 0) { - LOGW("Socket was disconnected. fd(%d)", fd_); - return -ECOMM; + int err = errno; + LOG(WARNING) << "Socket was disconnected. fd: " << fd_ + << ", errno: " << err; + return -err; } else if (recv_byte < 0) { if (errno == EINTR) { + LOG(WARNING) << "Interrupt occuered, try to receive data continue"; continue; } else if (errno == EAGAIN) { if (is_blocking) { - LOGE("Timed out. fd(%d)", fd_); + LOG(ERROR) << "Timed out. fd: " << fd_ << ", errno: " << EAGAIN + << " remaining retry count : " << block_retry_count; + if (block_retry_count > 0) { + block_retry_count--; + continue; + } return -EAGAIN; } - continue; + if (retry_count > 0) { + LOG(WARNING) << "Fail to receive data from " + << "non-blocking socket retry count : " << retry_count + << " left byte : " << left << " receive byte : " << recv_byte; + usleep(100 * 1000); + retry_count--; + continue; + } } - LOGE("recv() is failed. fd(%d), errno(%d)", fd_, errno); + LOG(ERROR) << "recv() is failed. fd: " << fd_ << ", errno: " << errno; return -ECOMM; } @@ -85,36 +112,75 @@ int AbstractSocket::ReceiveData(void* buf, unsigned int size) { return 0; } -int AbstractSocket::GetFd() { return fd_; } +int AbstractSocket::GetFd() { + return fd_; +} + +std::string AbstractSocket::GetPath() { + return path_; +} + +pid_t AbstractSocket::GetPID() { + return pid_; +} -std::string AbstractSocket::GetPath() { return path_; } +uid_t AbstractSocket::GetUID() { + return uid_; +} void AbstractSocket::SetOption() { int size = 2048; int ret = setsockopt(fd_, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); + if (ret < 0) { - LOGE("setsockopt() is failed. fd(%d), errno(%d)", fd_, errno); + LOG(ERROR) << "setsockopt() is failed. fd: " << fd_ + << ", errno: " << errno; return; } ret = setsockopt(fd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); - if (ret < 0) LOGE("setsockopt() is failed. fd(%d), errno(%d)", fd_, errno); + if (ret < 0) + LOG(ERROR) << "setsockopt() is failed. fd: " << fd_ + << ", errno: " << errno; } int AbstractSocket::Create() { + if (fd_ != -1) + return 0; + fd_ = ::socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); if (fd_ < 0) { - LOGE("socket() is failed. errno(%d)", errno); + LOG(ERROR) << "socket() is failed. errno: " << errno; return fd_; } addr_.sun_family = AF_UNIX; snprintf(addr_.sun_path, sizeof(addr_.sun_path), "%s", path_.c_str()); + SetOption(); + GetFdInfo(); return 0; } -void AbstractSocket::Destroy() { - if (fd_ > 0) close(fd_); +void AbstractSocket::GetFdInfo() { + int r; + struct ucred cred = {}; + socklen_t len = sizeof(cred); + + r = getsockopt(fd_, SOL_SOCKET, SO_PEERCRED, &cred, &len); + if (r < 0) { + LOG(ERROR) << "getsockopt has failed, errno: " << errno; + return; + } + + pid_ = cred.pid; + uid_ = cred.uid; +} + +void AbstractSocket::Disconnect() { + if (fd_ > 0) + close(fd_); + + fd_ = -1; } } // namespace socket