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 class ScopedPipe {
25  public:
ScopedPipe()26   ScopedPipe() : pipefd_{-1, -1} {
27     int ret = pipe2(pipefd_, O_CLOEXEC);
28     if (ret < 0) {
29       LOG_ALWAYS_FATAL("failed to open pipe");
30     }
31   }
~ScopedPipe()32   ~ScopedPipe() {
33     Close();
34   }
35 
ScopedPipe(ScopedPipe && other)36   ScopedPipe(ScopedPipe&& other) {
37     SetReceiver(other.ReleaseReceiver());
38     SetSender(other.ReleaseSender());
39   }
40 
41   ScopedPipe& operator = (ScopedPipe&& other) {
42     SetReceiver(other.ReleaseReceiver());
43     SetSender(other.ReleaseSender());
44     return *this;
45   }
46 
CloseReceiver()47   void CloseReceiver() {
48     close(ReleaseReceiver());
49   }
50 
CloseSender()51   void CloseSender() {
52     close(ReleaseSender());
53   }
54 
Close()55   void Close() {
56     CloseReceiver();
57     CloseSender();
58   }
59 
Receiver()60   int Receiver() { return pipefd_[0]; }
Sender()61   int Sender() { return pipefd_[1]; }
62 
ReleaseReceiver()63   int ReleaseReceiver() {
64     int ret = Receiver();
65     SetReceiver(-1);
66     return ret;
67   }
68 
ReleaseSender()69   int ReleaseSender() {
70     int ret = Sender();
71     SetSender(-1);
72     return ret;
73   }
74 
75  private:
SetReceiver(int fd)76   void SetReceiver(int fd) { pipefd_[0] = fd; };
SetSender(int fd)77   void SetSender(int fd) { pipefd_[1] = fd; };
78 
79   int pipefd_[2];
80 };
81 #endif
82