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