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 21d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenkonamespace { 22d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 23adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenkoconstexpr size_t kMaxFdCount = 24adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko 256; // Total of 1KiB of data to transfer these FDs. 25adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko 26d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// Default implementations of Send/Receive interfaces to use standard socket 27d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// send/sendmsg/recv/recvmsg functions. 28d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenkoclass SocketSender : public SendInterface { 29d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko public: 30d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t Send(int socket_fd, const void* data, size_t size, 31d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko int flags) override { 32d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return send(socket_fd, data, size, flags); 33d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 34d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t SendMessage(int socket_fd, const msghdr* msg, int flags) override { 35d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return sendmsg(socket_fd, msg, flags); 36d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 37d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko} g_socket_sender; 38d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 39d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenkoclass SocketReceiver : public RecvInterface { 40d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko public: 41d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t Receive(int socket_fd, void* data, size_t size, int flags) override { 42d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return recv(socket_fd, data, size, flags); 43d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 44d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t ReceiveMessage(int socket_fd, msghdr* msg, int flags) override { 45d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return recvmsg(socket_fd, msg, flags); 46d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 47d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko} g_socket_receiver; 48d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 49d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko} // anonymous namespace 50d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 51d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// Helper wrappers around send()/sendmsg() which repeat send() calls on data 52d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// that was not sent with the initial call to send/sendmsg. This is important to 53d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// handle transmissions interrupted by signals. 54d618b567630d347be0929ea25ce6c68921005ed6Alex VakulenkoStatus<void> SendAll(SendInterface* sender, const BorrowedHandle& socket_fd, 55d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko const void* data, size_t size) { 56d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko Status<void> ret; 57d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko const uint8_t* ptr = static_cast<const uint8_t*>(data); 58d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko while (size > 0) { 59d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t size_written = 60d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko RETRY_EINTR(sender->Send(socket_fd.Get(), ptr, size, MSG_NOSIGNAL)); 61d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko if (size_written < 0) { 62d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.SetError(errno); 63d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ALOGE("SendAll: Failed to send data over socket: %s", 64d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.GetErrorMessage().c_str()); 65d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko break; 66d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 67d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko size -= size_written; 68d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ptr += size_written; 69d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 70d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return ret; 71d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko} 72d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 73d618b567630d347be0929ea25ce6c68921005ed6Alex VakulenkoStatus<void> SendMsgAll(SendInterface* sender, const BorrowedHandle& socket_fd, 74d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko const msghdr* msg) { 75d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko Status<void> ret; 76d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t sent_size = 77d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko RETRY_EINTR(sender->SendMessage(socket_fd.Get(), msg, MSG_NOSIGNAL)); 78d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko if (sent_size < 0) { 79d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.SetError(errno); 80d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ALOGE("SendMsgAll: Failed to send data over socket: %s", 81d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.GetErrorMessage().c_str()); 82d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return ret; 83d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 84d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 85d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t chunk_start_offset = 0; 86d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko for (size_t i = 0; i < msg->msg_iovlen; i++) { 87d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t chunk_end_offset = chunk_start_offset + msg->msg_iov[i].iov_len; 88d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko if (sent_size < chunk_end_offset) { 89d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko size_t offset_within_chunk = sent_size - chunk_start_offset; 90d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko size_t data_size = msg->msg_iov[i].iov_len - offset_within_chunk; 91d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko const uint8_t* chunk_base = 92d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko static_cast<const uint8_t*>(msg->msg_iov[i].iov_base); 93d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret = SendAll(sender, socket_fd, chunk_base + offset_within_chunk, 94d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko data_size); 95d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko if (!ret) 96d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko break; 97d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko sent_size += data_size; 98d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 99d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko chunk_start_offset = chunk_end_offset; 100d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 101d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return ret; 102d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko} 103d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 104d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// Helper wrappers around recv()/recvmsg() which repeat recv() calls on data 105d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// that was not received with the initial call to recvmsg(). This is important 106d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// to handle transmissions interrupted by signals as well as the case when 107d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// initial data did not arrive in a single chunk over the socket (e.g. socket 108d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// buffer was full at the time of transmission, and only portion of initial 109d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// message was sent and the rest was blocked until the buffer was cleared by the 110d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko// receiving side). 111d618b567630d347be0929ea25ce6c68921005ed6Alex VakulenkoStatus<void> RecvMsgAll(RecvInterface* receiver, 112d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko const BorrowedHandle& socket_fd, msghdr* msg) { 113d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko Status<void> ret; 114d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t size_read = RETRY_EINTR(receiver->ReceiveMessage( 115d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko socket_fd.Get(), msg, MSG_WAITALL | MSG_CMSG_CLOEXEC)); 116d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko if (size_read < 0) { 117d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.SetError(errno); 118d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ALOGE("RecvMsgAll: Failed to receive data from socket: %s", 119d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.GetErrorMessage().c_str()); 120d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return ret; 121d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } else if (size_read == 0) { 122d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.SetError(ESHUTDOWN); 123d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ALOGW("RecvMsgAll: Socket has been shut down"); 124d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return ret; 125d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 126d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 127d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t chunk_start_offset = 0; 128d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko for (size_t i = 0; i < msg->msg_iovlen; i++) { 129d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t chunk_end_offset = chunk_start_offset + msg->msg_iov[i].iov_len; 130d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko if (size_read < chunk_end_offset) { 131d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko size_t offset_within_chunk = size_read - chunk_start_offset; 132d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko size_t data_size = msg->msg_iov[i].iov_len - offset_within_chunk; 133d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko uint8_t* chunk_base = static_cast<uint8_t*>(msg->msg_iov[i].iov_base); 134d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret = RecvAll(receiver, socket_fd, chunk_base + offset_within_chunk, 135d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko data_size); 136d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko if (!ret) 137d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko break; 138d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko size_read += data_size; 139d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 140d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko chunk_start_offset = chunk_end_offset; 141d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 142d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return ret; 143d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko} 144d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 145d618b567630d347be0929ea25ce6c68921005ed6Alex VakulenkoStatus<void> RecvAll(RecvInterface* receiver, const BorrowedHandle& socket_fd, 146d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko void* data, size_t size) { 147d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko Status<void> ret; 148d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko uint8_t* ptr = static_cast<uint8_t*>(data); 149d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko while (size > 0) { 150d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ssize_t size_read = RETRY_EINTR(receiver->Receive( 151d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko socket_fd.Get(), ptr, size, MSG_WAITALL | MSG_CMSG_CLOEXEC)); 152d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko if (size_read < 0) { 153d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.SetError(errno); 154d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ALOGE("RecvAll: Failed to receive data from socket: %s", 155d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.GetErrorMessage().c_str()); 156d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko break; 157d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } else if (size_read == 0) { 158d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.SetError(ESHUTDOWN); 159d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ALOGW("RecvAll: Socket has been shut down"); 160d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko break; 161d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 162d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko size -= size_read; 163d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ptr += size_read; 164d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 165d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return ret; 166d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko} 167d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkouint32_t kMagicPreamble = 0x7564736d; // 'udsm'. 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct MessagePreamble { 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint32_t magic{0}; 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint32_t data_size{0}; 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint32_t fd_count{0}; 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 17609aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendPayload::Send(const BorrowedHandle& socket_fd) { 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Send(socket_fd, nullptr); 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 18009aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendPayload::Send(const BorrowedHandle& socket_fd, 181adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko const ucred* cred, const iovec* data_vec, 182adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko size_t vec_count) { 183adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko if (file_handles_.size() > kMaxFdCount) { 184adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko ALOGE( 185adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko "SendPayload::Send: Trying to send too many file descriptors (%zu), " 186adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko "max allowed = %zu", 187adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko file_handles_.size(), kMaxFdCount); 188adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko return ErrorStatus{EINVAL}; 189adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko } 190adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko 191d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko SendInterface* sender = sender_ ? sender_ : &g_socket_sender; 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko MessagePreamble preamble; 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko preamble.magic = kMagicPreamble; 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko preamble.data_size = buffer_.size(); 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko preamble.fd_count = file_handles_.size(); 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msghdr msg = {}; 198adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_iovlen = 2 + vec_count; 199adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_iov = static_cast<iovec*>(alloca(sizeof(iovec) * msg.msg_iovlen)); 200adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_iov[0].iov_base = &preamble; 201adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_iov[0].iov_len = sizeof(preamble); 202adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_iov[1].iov_base = buffer_.data(); 203adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_iov[1].iov_len = buffer_.size(); 204adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko for (size_t i = 0; i < vec_count; i++) 205adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_iov[i + 2] = data_vec[i]; 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (cred || !file_handles_.empty()) { 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const size_t fd_bytes = file_handles_.size() * sizeof(int); 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_controllen = (cred ? CMSG_SPACE(sizeof(ucred)) : 0) + 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko (fd_bytes == 0 ? 0 : CMSG_SPACE(fd_bytes)); 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_control = alloca(msg.msg_controllen); 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cmsghdr* control = CMSG_FIRSTHDR(&msg); 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (cred) { 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_level = SOL_SOCKET; 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_type = SCM_CREDENTIALS; 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_len = CMSG_LEN(sizeof(ucred)); 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(CMSG_DATA(control), cred, sizeof(ucred)); 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control = CMSG_NXTHDR(&msg, control); 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (fd_bytes) { 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_level = SOL_SOCKET; 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_type = SCM_RIGHTS; 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko control->cmsg_len = CMSG_LEN(fd_bytes); 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(CMSG_DATA(control), file_handles_.data(), fd_bytes); 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 230d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return SendMsgAll(sender, socket_fd, &msg); 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// MessageWriter 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid* SendPayload::GetNextWriteBufferSection(size_t size) { 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return buffer_.grow_by(size); 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoOutputResourceMapper* SendPayload::GetOutputResourceMapper() { return this; } 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// OutputResourceMapper 241f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> SendPayload::PushFileHandle(const LocalHandle& handle) { 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (handle) { 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int ref = file_handles_.size(); 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.push_back(handle.Get()); 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ref; 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 251f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> SendPayload::PushFileHandle( 252f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko const BorrowedHandle& handle) { 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (handle) { 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int ref = file_handles_.size(); 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.push_back(handle.Get()); 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ref; 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 262f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<FileReference> SendPayload::PushFileHandle(const RemoteHandle& handle) { 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return handle.Get(); 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 266f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> SendPayload::PushChannelHandle( 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const LocalChannelHandle& /*handle*/) { 268f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EOPNOTSUPP}; 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 270f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> SendPayload::PushChannelHandle( 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const BorrowedChannelHandle& /*handle*/) { 272f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EOPNOTSUPP}; 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 274f0a7bd033941e26e380232a0515e903cf8e678e5Alex VakulenkoStatus<ChannelReference> SendPayload::PushChannelHandle( 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const RemoteChannelHandle& /*handle*/) { 276f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko return ErrorStatus{EOPNOTSUPP}; 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 27909aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd) { 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Receive(socket_fd, nullptr); 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 28309aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd, 28409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko ucred* cred) { 285d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko RecvInterface* receiver = receiver_ ? receiver_ : &g_socket_receiver; 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko MessagePreamble preamble; 287adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msghdr msg = {}; 288adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko iovec recv_vect = {&preamble, sizeof(preamble)}; 289adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_iov = &recv_vect; 290adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_iovlen = 1; 291adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko const size_t receive_fd_bytes = kMaxFdCount * sizeof(int); 292adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_controllen = CMSG_SPACE(sizeof(ucred)) + CMSG_SPACE(receive_fd_bytes); 293adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko msg.msg_control = alloca(msg.msg_controllen); 294adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko 295adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko Status<void> ret = RecvMsgAll(receiver, socket_fd, &msg); 296d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko if (!ret) 297d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return ret; 298d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko 299d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko if (preamble.magic != kMagicPreamble) { 3006eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko ALOGE("ReceivePayload::Receive: Message header is invalid"); 301d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.SetError(EIO); 302d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return ret; 303d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko } 304e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer_.resize(preamble.data_size); 306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.clear(); 307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_pos_ = 0; 308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool cred_available = false; 310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko file_handles_.reserve(preamble.fd_count); 311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); 312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (cmsg) { 313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS && 314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cred && cmsg->cmsg_len == CMSG_LEN(sizeof(ucred))) { 315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cred_available = true; 316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memcpy(cred, CMSG_DATA(cmsg), sizeof(ucred)); 317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (cmsg->cmsg_level == SOL_SOCKET && 318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cmsg->cmsg_type == SCM_RIGHTS) { 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko socklen_t payload_len = cmsg->cmsg_len - CMSG_LEN(0); 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int* fds = reinterpret_cast<const int*>(CMSG_DATA(cmsg)); 321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t fd_count = payload_len / sizeof(int); 322e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::transform(fds, fds + fd_count, std::back_inserter(file_handles_), 323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko [](int fd) { return LocalHandle{fd}; }); 324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko cmsg = CMSG_NXTHDR(&msg, cmsg); 326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 328adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko ret = RecvAll(receiver, socket_fd, buffer_.data(), buffer_.size()); 329adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko if (!ret) 330adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko return ret; 331adfc42ead3921f94339372ffb561bc3e8d7f3c86Alex Vakulenko 3326eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko if (cred && !cred_available) { 3336eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko ALOGE("ReceivePayload::Receive: Failed to obtain message credentials"); 334d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko ret.SetError(EIO); 3356eefa42d33bdddc3603211634f98937b00abc532Alex Vakulenko } 336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 337d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return ret; 338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 340e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// MessageReader 341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoMessageReader::BufferSection ReceivePayload::GetNextReadBufferSection() { 342e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {buffer_.data() + read_pos_, &*buffer_.end()}; 343e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid ReceivePayload::ConsumeReadBufferSectionData(const void* new_start) { 346e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko read_pos_ = PointerDistance(new_start, buffer_.data()); 347e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoInputResourceMapper* ReceivePayload::GetInputResourceMapper() { return this; } 350e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 351e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// InputResourceMapper 352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ReceivePayload::GetFileHandle(FileReference ref, LocalHandle* handle) { 353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ref < 0) { 354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = LocalHandle{ref}; 355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (static_cast<size_t>(ref) > file_handles_.size()) 358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *handle = std::move(file_handles_[ref]); 360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return true; 361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 362e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool ReceivePayload::GetChannelHandle(ChannelReference /*ref*/, 364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalChannelHandle* /*handle*/) { 365e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return false; 366e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 36809aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendData(const BorrowedHandle& socket_fd, const void* data, 36909aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko size_t size) { 370d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return SendAll(&g_socket_sender, socket_fd, data, size); 371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 372e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 37309aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> SendDataVector(const BorrowedHandle& socket_fd, const iovec* data, 37409aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko size_t count) { 375e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msghdr msg = {}; 376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iov = const_cast<iovec*>(data); 377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iovlen = count; 378d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return SendMsgAll(&g_socket_sender, socket_fd, &msg); 379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 380e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 38109aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceiveData(const BorrowedHandle& socket_fd, void* data, 38209aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko size_t size) { 383d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return RecvAll(&g_socket_receiver, socket_fd, data, size); 384e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 385e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 38609aa736ee6136787b18807d7ab459feba23cec04Alex VakulenkoStatus<void> ReceiveDataVector(const BorrowedHandle& socket_fd, 38709aa736ee6136787b18807d7ab459feba23cec04Alex Vakulenko const iovec* data, size_t count) { 388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msghdr msg = {}; 389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iov = const_cast<iovec*>(data); 390e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko msg.msg_iovlen = count; 391d618b567630d347be0929ea25ce6c68921005ed6Alex Vakulenko return RecvMsgAll(&g_socket_receiver, socket_fd, &msg); 392e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 393e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 394e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkosize_t CountVectorSize(const iovec* vector, size_t count) { 395e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::accumulate( 396e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko vector, vector + count, size_t{0}, 397e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko [](size_t size, const iovec& vec) { return size + vec.iov_len; }); 398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 399e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 400e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid InitRequest(android::pdx::uds::RequestHeader<BorrowedHandle>* request, 401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int opcode, uint32_t send_len, uint32_t max_recv_len, 402e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool is_impulse) { 403e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->op = opcode; 404e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->cred.pid = getpid(); 405e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->cred.uid = geteuid(); 406e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->cred.gid = getegid(); 407e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->send_len = send_len; 408e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->max_recv_len = max_recv_len; 409e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko request->is_impulse = is_impulse; 410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 411e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 412e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoStatus<void> WaitForEndpoint(const std::string& endpoint_path, 413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int64_t timeout_ms) { 414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Endpoint path must be absolute. 415e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (endpoint_path.empty() || endpoint_path.front() != '/') 416e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EINVAL); 417e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 418e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create inotify fd. 419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko LocalHandle fd{inotify_init()}; 420e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!fd) 421e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 422e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 423e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Set the inotify fd to non-blocking. 424e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int ret = fcntl(fd.Get(), F_GETFL); 425e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko fcntl(fd.Get(), F_SETFL, ret | O_NONBLOCK); 426e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 427e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Setup the pollfd. 428e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pollfd pfd = {fd.Get(), POLLIN, 0}; 429e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 430e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Find locations of each path separator. 431e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<size_t> separators{0}; // The path is absolute, so '/' is at #0. 432e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t pos = endpoint_path.find('/', 1); 433e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (pos != std::string::npos) { 434e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko separators.push_back(pos); 435e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pos = endpoint_path.find('/', pos + 1); 436e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 437e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko separators.push_back(endpoint_path.size()); 438e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 439e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Walk down the path, checking for existence and waiting if needed. 440e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pos = 1; 441e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko size_t links = 0; 442e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string current; 443e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (pos < separators.size() && links <= MAXSYMLINKS) { 444e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string previous = current; 445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko current = endpoint_path.substr(0, separators[pos]); 446e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 447e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Check for existence; proceed to setup a watch if not. 448e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (access(current.c_str(), F_OK) < 0) { 449e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (errno != ENOENT) 450e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 451e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 452e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Extract the name of the path component to wait for. 453e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string next = current.substr( 454e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko separators[pos - 1] + 1, separators[pos] - separators[pos - 1] - 1); 455e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 456e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Add a watch on the last existing directory we reach. 457e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int wd = inotify_add_watch( 458e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko fd.Get(), previous.c_str(), 459e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko IN_CREATE | IN_DELETE_SELF | IN_MOVE_SELF | IN_MOVED_TO); 460e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (wd < 0) { 461e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (errno != ENOENT) 462e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 463e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Restart at the beginning if previous was deleted. 464e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko links = 0; 465e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko current.clear(); 466e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pos = 1; 467e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko continue; 468e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 469e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 470e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Make sure current didn't get created before the watch was added. 471e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = access(current.c_str(), F_OK); 472e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) { 473e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (errno != ENOENT) 474e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 475e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 476e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko bool exit_poll = false; 477e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (!exit_poll) { 478e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Wait for an event or timeout. 479e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = poll(&pfd, 1, timeout_ms); 480e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret <= 0) 481e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(ret == 0 ? ETIMEDOUT : errno); 482e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 483e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Read events. 484e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko char buffer[sizeof(inotify_event) + NAME_MAX + 1]; 485e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 486e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = read(fd.Get(), buffer, sizeof(buffer)); 487e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0) { 488e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (errno == EAGAIN || errno == EWOULDBLOCK) 489e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko continue; 490e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 491e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 492e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (static_cast<size_t>(ret) < sizeof(struct inotify_event)) { 493e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(EIO); 494e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 495e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 496e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* event = reinterpret_cast<const inotify_event*>(buffer); 497e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto* end = reinterpret_cast<const inotify_event*>(buffer + ret); 498e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (event < end) { 499e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string event_for; 500e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (event->len > 0) 501e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event_for = event->name; 502e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 503e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (event->mask & (IN_CREATE | IN_MOVED_TO)) { 504e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // See if this is the droid we're looking for. 505e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (next == event_for) { 506e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko exit_poll = true; 507e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 508e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 509e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (event->mask & (IN_DELETE_SELF | IN_MOVE_SELF)) { 510e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Restart at the beginning if our watch dir is deleted. 511e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko links = 0; 512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko current.clear(); 513e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pos = 0; 514e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko exit_poll = true; 515e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 516e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 517e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 518e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event = reinterpret_cast<const inotify_event*>(AdvancePointer( 519e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event, sizeof(struct inotify_event) + event->len)); 520e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } // while (event < end) 521e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } // while (!exit_poll) 522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } // Current dir doesn't exist. 523e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = inotify_rm_watch(fd.Get(), wd); 524e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0 && errno != EINVAL) 525e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 526e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } // if (access(current.c_str(), F_OK) < 0) 527e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 528e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Check for symbolic link and update link count. 529e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko struct stat stat_buf; 530e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ret = lstat(current.c_str(), &stat_buf); 531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (ret < 0 && errno != ENOENT) 532e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ErrorStatus(errno); 533e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else if (ret == 0 && S_ISLNK(stat_buf.st_mode)) 534e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko links++; 535e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pos++; 536e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } // while (pos < separators.size() && links <= MAXSYMLINKS) 537e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 538e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return {}; 539e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 540e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 541e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace uds 542e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace pdx 543e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 544