1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef LIBMEMUNREACHABLE_SCOPED_PIPE_H_ 18 #define LIBMEMUNREACHABLE_SCOPED_PIPE_H_ 19 20 #include <unistd.h> 21 22 #include "log.h" 23 24 namespace android { 25 26 class ScopedPipe { 27 public: ScopedPipe()28 ScopedPipe() : pipefd_{-1, -1} { 29 int ret = pipe2(pipefd_, O_CLOEXEC); 30 if (ret < 0) { 31 MEM_LOG_ALWAYS_FATAL("failed to open pipe"); 32 } 33 } ~ScopedPipe()34 ~ScopedPipe() { Close(); } 35 ScopedPipe(ScopedPipe && other)36 ScopedPipe(ScopedPipe&& other) noexcept { 37 SetReceiver(other.ReleaseReceiver()); 38 SetSender(other.ReleaseSender()); 39 } 40 41 ScopedPipe& operator=(ScopedPipe&& other) noexcept { 42 SetReceiver(other.ReleaseReceiver()); 43 SetSender(other.ReleaseSender()); 44 return *this; 45 } 46 CloseReceiver()47 void CloseReceiver() { close(ReleaseReceiver()); } 48 CloseSender()49 void CloseSender() { close(ReleaseSender()); } 50 Close()51 void Close() { 52 CloseReceiver(); 53 CloseSender(); 54 } 55 Receiver()56 int Receiver() { return pipefd_[0]; } Sender()57 int Sender() { return pipefd_[1]; } 58 ReleaseReceiver()59 int ReleaseReceiver() { 60 int ret = Receiver(); 61 SetReceiver(-1); 62 return ret; 63 } 64 ReleaseSender()65 int ReleaseSender() { 66 int ret = Sender(); 67 SetSender(-1); 68 return ret; 69 } 70 71 private: SetReceiver(int fd)72 void SetReceiver(int fd) { pipefd_[0] = fd; }; SetSender(int fd)73 void SetSender(int fd) { pipefd_[1] = fd; }; 74 75 int pipefd_[2]; 76 }; 77 78 } // namespace android 79 80 #endif 81