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