/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "common/libs/fs/shared_buf.h" #include "common/libs/fs/shared_fd.h" namespace cuttlefish { namespace { const size_t BUFF_SIZE = 1 << 14; } // namespace ssize_t WriteAll(SharedFD fd, const char* buf, size_t size) { size_t total_written = 0; ssize_t written = 0; while ((written = fd->Write((void*)&(buf[total_written]), size - total_written)) > 0) { if (written < 0) { errno = fd->GetErrno(); return written; } total_written += written; if (total_written == size) { break; } } return total_written; } ssize_t ReadExact(SharedFD fd, char* buf, size_t size) { size_t total_read = 0; ssize_t read = 0; while ((read = fd->Read((void*)&(buf[total_read]), size - total_read)) > 0) { if (read < 0) { errno = fd->GetErrno(); return read; } total_read += read; if (total_read == size) { break; } } return total_read; } ssize_t ReadAll(SharedFD fd, std::string* buf) { char buff[BUFF_SIZE]; std::stringstream ss; ssize_t read; while ((read = fd->Read(buff, BUFF_SIZE - 1)) > 0) { // this is necessary to avoid problems with having a '\0' in the middle of the buffer ss << std::string(buff, read); } if (read < 0) { errno = fd->GetErrno(); return read; } *buf = ss.str(); return buf->size(); } ssize_t ReadExact(SharedFD fd, std::string* buf) { return ReadExact(fd, buf->data(), buf->size()); } ssize_t ReadExact(SharedFD fd, std::vector* buf) { return ReadExact(fd, buf->data(), buf->size()); } ssize_t WriteAll(SharedFD fd, const std::string& buf) { return WriteAll(fd, buf.data(), buf.size()); } ssize_t WriteAll(SharedFD fd, const std::vector& buf) { return WriteAll(fd, buf.data(), buf.size()); } bool SendAll(SharedFD sock, const std::string& msg) { ssize_t total_written{}; if (!sock->IsOpen()) { return false; } while (total_written < static_cast(msg.size())) { auto just_written = sock->Send(msg.c_str() + total_written, msg.size() - total_written, MSG_NOSIGNAL); if (just_written <= 0) { return false; } total_written += just_written; } return true; } std::string RecvAll(SharedFD sock, const size_t count) { size_t total_read{}; if (!sock->IsOpen()) { return {}; } std::unique_ptr data(new char[count]); while (total_read < count) { auto just_read = sock->Read(data.get() + total_read, count - total_read); if (just_read <= 0) { return {}; } total_read += just_read; } return {data.get(), count}; } } // namespace cuttlefish