| /* | |
| * Copyright (C) 2022 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 "interprocess_fifo.h" | |
| #include <android-base/logging.h> | |
| #include <unistd.h> | |
| using ::android::base::ErrnoError; | |
| using ::android::base::Error; | |
| using ::android::base::Result; | |
| namespace android { | |
| namespace init { | |
| InterprocessFifo::InterprocessFifo() noexcept : fds_({-1, -1}) {} | |
| InterprocessFifo::InterprocessFifo(InterprocessFifo&& orig) noexcept : fds_({-1, -1}) { | |
| std::swap(fds_, orig.fds_); | |
| } | |
| InterprocessFifo::~InterprocessFifo() noexcept { | |
| Close(); | |
| } | |
| void InterprocessFifo::CloseFd(int& fd) noexcept { | |
| if (fd >= 0) { | |
| close(fd); | |
| fd = -1; | |
| } | |
| } | |
| void InterprocessFifo::CloseReadFd() noexcept { | |
| CloseFd(fds_[0]); | |
| } | |
| void InterprocessFifo::CloseWriteFd() noexcept { | |
| CloseFd(fds_[1]); | |
| } | |
| void InterprocessFifo::Close() noexcept { | |
| CloseReadFd(); | |
| CloseWriteFd(); | |
| } | |
| Result<void> InterprocessFifo::Initialize() noexcept { | |
| if (fds_[0] >= 0) { | |
| return Error() << "already initialized"; | |
| } | |
| if (pipe(fds_.data()) < 0) { // NOLINT(android-cloexec-pipe) | |
| return ErrnoError() << "pipe()"; | |
| } | |
| return {}; | |
| } | |
| Result<uint8_t> InterprocessFifo::Read() noexcept { | |
| uint8_t byte; | |
| ssize_t count = read(fds_[0], &byte, 1); | |
| if (count < 0) { | |
| return ErrnoError() << "read()"; | |
| } | |
| if (count == 0) { | |
| return Error() << "read() EOF"; | |
| } | |
| DCHECK_EQ(count, 1); | |
| return byte; | |
| } | |
| Result<void> InterprocessFifo::Write(uint8_t byte) noexcept { | |
| ssize_t written = write(fds_[1], &byte, 1); | |
| if (written < 0) { | |
| return ErrnoError() << "write()"; | |
| } | |
| if (written == 0) { | |
| return Error() << "write() EOF"; | |
| } | |
| DCHECK_EQ(written, 1); | |
| return {}; | |
| } | |
| } // namespace init | |
| } // namespace android |