ipc_helper.cpp revision 09aa736ee6136787b18807d7ab459feba23cec04
1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "uds/ipc_helper.h" 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <alloca.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <errno.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <log/log.h> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <poll.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <string.h> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/inotify.h> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/param.h> 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/socket.h> 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <algorithm> 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service.h> 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/utility.h> 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace pdx { 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace uds { 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkouint32_t kMagicPreamble = 0x7564736d; // 'udsm'. 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct MessagePreamble { 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint32_t magic{0}; 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint32_t data_size{0}; 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint32_t fd_count{0}; 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 2909aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendPayload::Send(const BorrowedHandle& socket_fd) { 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Send(socket_fd, nullptr); 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 3309aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendPayload::Send(const BorrowedHandle& socket_fd, 3409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko const ucred* cred) { 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko MessagePreamble preamble; 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko preamble.magic = kMagicPreamble; 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko preamble.data_size = buffer_.size(); 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko preamble.fd_count = file_handles_.size(); 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko ssize_t ret = RETRY_EINTR( 4109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko send(socket_fd.Get(), &preamble, sizeof(preamble), MSG_NOSIGNAL)); 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret != sizeof(preamble)) 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msghdr msg = {}; 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iovec recv_vect = {buffer_.data(), buffer_.size()}; 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iov = &recv_vect; 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iovlen = 1; 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (cred || !file_handles_.empty()) { 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const size_t fd_bytes = file_handles_.size() * sizeof(int); 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_controllen = (cred ? CMSG_SPACE(sizeof(ucred)) : 0) + 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (fd_bytes == 0 ? 0 : CMSG_SPACE(fd_bytes)); 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_control = alloca(msg.msg_controllen); 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cmsghdr* control = CMSG_FIRSTHDR(&msg); 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (cred) { 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_level = SOL_SOCKET; 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_type = SCM_CREDENTIALS; 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_len = CMSG_LEN(sizeof(ucred)); 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(CMSG_DATA(control), cred, sizeof(ucred)); 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control = CMSG_NXTHDR(&msg, control); 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (fd_bytes) { 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_level = SOL_SOCKET; 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_type = SCM_RIGHTS; 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_len = CMSG_LEN(fd_bytes); 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(CMSG_DATA(control), file_handles_.data(), fd_bytes); 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 7509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko ret = RETRY_EINTR(sendmsg(socket_fd.Get(), &msg, MSG_NOSIGNAL)); 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (static_cast<size_t>(ret) != buffer_.size()) 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// MessageWriter 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid* SendPayload::GetNextWriteBufferSection(size_t size) { 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return buffer_.grow_by(size); 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoOutputResourceMapper* SendPayload::GetOutputResourceMapper() { return this; } 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// OutputResourceMapper 91f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> SendPayload::PushFileHandle(const LocalHandle& handle) { 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (handle) { 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int ref = file_handles_.size(); 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.push_back(handle.Get()); 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ref; 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 101f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> SendPayload::PushFileHandle( 102f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const BorrowedHandle& handle) { 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (handle) { 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int ref = file_handles_.size(); 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.push_back(handle.Get()); 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ref; 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 112f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> SendPayload::PushFileHandle(const RemoteHandle& handle) { 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 116f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> SendPayload::PushChannelHandle( 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalChannelHandle& /*handle*/) { 118f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EOPNOTSUPP}; 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 120f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> SendPayload::PushChannelHandle( 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BorrowedChannelHandle& /*handle*/) { 122f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EOPNOTSUPP}; 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 124f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> SendPayload::PushChannelHandle( 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const RemoteChannelHandle& /*handle*/) { 126f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EOPNOTSUPP}; 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 12909aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd) { 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Receive(socket_fd, nullptr); 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 13309aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd, 13409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko ucred* cred) { 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko MessagePreamble preamble; 13609aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko ssize_t ret = RETRY_EINTR( 13709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko recv(socket_fd.Get(), &preamble, sizeof(preamble), MSG_WAITALL)); 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 1406890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka else if (ret == 0) 1416890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return ErrorStatus(ESHUTDOWN); 1426890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka else if (ret != sizeof(preamble) || preamble.magic != kMagicPreamble) 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer_.resize(preamble.data_size); 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.clear(); 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_pos_ = 0; 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msghdr msg = {}; 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko iovec recv_vect = {buffer_.data(), buffer_.size()}; 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iov = &recv_vect; 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iovlen = 1; 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (cred || preamble.fd_count) { 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const size_t receive_fd_bytes = preamble.fd_count * sizeof(int); 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_controllen = 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (cred ? CMSG_SPACE(sizeof(ucred)) : 0) + 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (receive_fd_bytes == 0 ? 0 : CMSG_SPACE(receive_fd_bytes)); 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_control = alloca(msg.msg_controllen); 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 16209aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko ret = RETRY_EINTR(recvmsg(socket_fd.Get(), &msg, MSG_WAITALL)); 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 1656890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka else if (ret == 0) 1666890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return ErrorStatus(ESHUTDOWN); 1676890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka else if (static_cast<uint32_t>(ret) != preamble.data_size) 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool cred_available = false; 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.reserve(preamble.fd_count); 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (cmsg) { 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS && 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cred && cmsg->cmsg_len == CMSG_LEN(sizeof(ucred))) { 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cred_available = true; 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(cred, CMSG_DATA(cmsg), sizeof(ucred)); 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (cmsg->cmsg_level == SOL_SOCKET && 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cmsg->cmsg_type == SCM_RIGHTS) { 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko socklen_t payload_len = cmsg->cmsg_len - CMSG_LEN(0); 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int* fds = reinterpret_cast<const int*>(CMSG_DATA(cmsg)); 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t fd_count = payload_len / sizeof(int); 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::transform(fds, fds + fd_count, std::back_inserter(file_handles_), 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko [](int fd) { return LocalHandle{fd}; }); 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cmsg = CMSG_NXTHDR(&msg, cmsg); 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (cred && !cred_available) { 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// MessageReader 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoMessageReader::BufferSection ReceivePayload::GetNextReadBufferSection() { 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {buffer_.data() + read_pos_, &*buffer_.end()}; 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid ReceivePayload::ConsumeReadBufferSectionData(const void* new_start) { 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_pos_ = PointerDistance(new_start, buffer_.data()); 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoInputResourceMapper* ReceivePayload::GetInputResourceMapper() { return this; } 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// InputResourceMapper 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ReceivePayload::GetFileHandle(FileReference ref, LocalHandle* handle) { 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ref < 0) { 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = LocalHandle{ref}; 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (static_cast<size_t>(ref) > file_handles_.size()) 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = std::move(file_handles_[ref]); 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ReceivePayload::GetChannelHandle(ChannelReference /*ref*/, 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle* /*handle*/) { 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 22409aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendData(const BorrowedHandle& socket_fd, const void* data, 22509aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko size_t size) { 22609aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko ssize_t size_written = 22709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko RETRY_EINTR(send(socket_fd.Get(), data, size, MSG_NOSIGNAL)); 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (size_written < 0) 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (static_cast<size_t>(size_written) != size) 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 23509aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendDataVector(const BorrowedHandle& socket_fd, const iovec* data, 23609aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko size_t count) { 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msghdr msg = {}; 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iov = const_cast<iovec*>(data); 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iovlen = count; 24009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko ssize_t size_written = 24109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko RETRY_EINTR(sendmsg(socket_fd.Get(), &msg, MSG_NOSIGNAL)); 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (size_written < 0) 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (static_cast<size_t>(size_written) != CountVectorSize(data, count)) 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 24909aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceiveData(const BorrowedHandle& socket_fd, void* data, 25009aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko size_t size) { 25109aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko ssize_t size_read = 25209aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko RETRY_EINTR(recv(socket_fd.Get(), data, size, MSG_WAITALL)); 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (size_read < 0) 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 2556890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka else if (size_read == 0) 2566890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return ErrorStatus(ESHUTDOWN); 2576890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka else if (static_cast<size_t>(size_read) != size) 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 26209aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceiveDataVector(const BorrowedHandle& socket_fd, 26309aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko const iovec* data, size_t count) { 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msghdr msg = {}; 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iov = const_cast<iovec*>(data); 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iovlen = count; 26709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko ssize_t size_read = RETRY_EINTR(recvmsg(socket_fd.Get(), &msg, MSG_WAITALL)); 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (size_read < 0) 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 2706890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka else if (size_read == 0) 2716890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka return ErrorStatus(ESHUTDOWN); 2726890d95ec8b96970202518b439bfa8ab2d9dbf77Corey Tabaka else if (static_cast<size_t>(size_read) != CountVectorSize(data, count)) 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkosize_t CountVectorSize(const iovec* vector, size_t count) { 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::accumulate( 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko vector, vector + count, size_t{0}, 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko [](size_t size, const iovec& vec) { return size + vec.iov_len; }); 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid InitRequest(android::pdx::uds::RequestHeader<BorrowedHandle>* request, 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int opcode, uint32_t send_len, uint32_t max_recv_len, 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool is_impulse) { 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->op = opcode; 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->cred.pid = getpid(); 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->cred.uid = geteuid(); 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->cred.gid = getegid(); 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->send_len = send_len; 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->max_recv_len = max_recv_len; 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->is_impulse = is_impulse; 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> WaitForEndpoint(const std::string& endpoint_path, 296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t timeout_ms) { 297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Endpoint path must be absolute. 298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (endpoint_path.empty() || endpoint_path.front() != '/') 299e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EINVAL); 300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create inotify fd. 302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle fd{inotify_init()}; 303e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!fd) 304e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Set the inotify fd to non-blocking. 307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ret = fcntl(fd.Get(), F_GETFL); 308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko fcntl(fd.Get(), F_SETFL, ret | O_NONBLOCK); 309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Setup the pollfd. 311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pollfd pfd = {fd.Get(), POLLIN, 0}; 312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Find locations of each path separator. 314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<size_t> separators{0}; // The path is absolute, so '/' is at #0. 315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t pos = endpoint_path.find('/', 1); 316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (pos != std::string::npos) { 317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko separators.push_back(pos); 318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pos = endpoint_path.find('/', pos + 1); 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko separators.push_back(endpoint_path.size()); 321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Walk down the path, checking for existence and waiting if needed. 323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pos = 1; 324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t links = 0; 325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string current; 326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (pos < separators.size() && links <= MAXSYMLINKS) { 327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string previous = current; 328e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko current = endpoint_path.substr(0, separators[pos]); 329e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Check for existence; proceed to setup a watch if not. 331e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (access(current.c_str(), F_OK) < 0) { 332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (errno != ENOENT) 333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Extract the name of the path component to wait for. 336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string next = current.substr( 337e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko separators[pos - 1] + 1, separators[pos] - separators[pos - 1] - 1); 338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Add a watch on the last existing directory we reach. 340e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int wd = inotify_add_watch( 341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko fd.Get(), previous.c_str(), 342e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko IN_CREATE | IN_DELETE_SELF | IN_MOVE_SELF | IN_MOVED_TO); 343e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (wd < 0) { 344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (errno != ENOENT) 345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 346e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Restart at the beginning if previous was deleted. 347e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko links = 0; 348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko current.clear(); 349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pos = 1; 350e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko continue; 351e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Make sure current didn't get created before the watch was added. 354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = access(current.c_str(), F_OK); 355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) { 356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (errno != ENOENT) 357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool exit_poll = false; 360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (!exit_poll) { 361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Wait for an event or timeout. 362e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = poll(&pfd, 1, timeout_ms); 363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret <= 0) 364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(ret == 0 ? ETIMEDOUT : errno); 365e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 366e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Read events. 367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko char buffer[sizeof(inotify_event) + NAME_MAX + 1]; 368e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 369e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = read(fd.Get(), buffer, sizeof(buffer)); 370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) { 371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (errno == EAGAIN || errno == EWOULDBLOCK) 372e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko continue; 373e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 374e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 375e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(ret) < sizeof(struct inotify_event)) { 376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 378e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* event = reinterpret_cast<const inotify_event*>(buffer); 380e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* end = reinterpret_cast<const inotify_event*>(buffer + ret); 381e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (event < end) { 382e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string event_for; 383e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (event->len > 0) 384e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event_for = event->name; 385e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 386e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (event->mask & (IN_CREATE | IN_MOVED_TO)) { 387e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // See if this is the droid we're looking for. 388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (next == event_for) { 389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko exit_poll = true; 390e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 391e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 392e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (event->mask & (IN_DELETE_SELF | IN_MOVE_SELF)) { 393e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Restart at the beginning if our watch dir is deleted. 394e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko links = 0; 395e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko current.clear(); 396e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pos = 0; 397e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko exit_poll = true; 398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 399e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 400e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event = reinterpret_cast<const inotify_event*>(AdvancePointer( 402e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event, sizeof(struct inotify_event) + event->len)); 403e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } // while (event < end) 404e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } // while (!exit_poll) 405e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } // Current dir doesn't exist. 406e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = inotify_rm_watch(fd.Get(), wd); 407e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0 && errno != EINVAL) 408e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 409e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } // if (access(current.c_str(), F_OK) < 0) 410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 411e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Check for symbolic link and update link count. 412e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko struct stat stat_buf; 413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = lstat(current.c_str(), &stat_buf); 414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0 && errno != ENOENT) 415e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 416e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else if (ret == 0 && S_ISLNK(stat_buf.st_mode)) 417e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko links++; 418e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pos++; 419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } // while (pos < separators.size() && links <= MAXSYMLINKS) 420e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 421e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 422e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 423e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 424e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace uds 425e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 426e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 427