blob: 0aab526e66e04db5698e15f0ff8df980481c0b99 [file] [log] [blame]
btolsch50905ba2018-07-25 14:12:32 -07001// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_SCOPED_PIPE_
6#define BASE_SCOPED_PIPE_
7
8#include <unistd.h>
9
10#include <utility>
11
12namespace openscreen {
13
14struct IntFdTraits {
15 using PipeType = int;
16 static constexpr int kInvalidValue = -1;
17
18 static void Close(PipeType pipe) { close(pipe); }
19};
20
21// This class wraps file descriptor and uses RAII to ensure it is closed
22// properly when control leaves its scope. It is parameterized by a traits type
23// which defines the value type of the file descriptor, an invalid value, and a
24// closing function.
25//
26// This class is move-only as it represents ownership of the wrapped file
27// descriptor. It is not thread-safe.
28template <typename Traits>
29class ScopedPipe {
30 public:
31 using PipeType = typename Traits::PipeType;
32
33 ScopedPipe() : pipe_(Traits::kInvalidValue) {}
34 explicit ScopedPipe(PipeType pipe) : pipe_(pipe) {}
35 ScopedPipe(const ScopedPipe&) = delete;
36 ScopedPipe(ScopedPipe&& other) : pipe_(other.release()) {}
37 ~ScopedPipe() {
38 if (pipe_ != Traits::kInvalidValue)
39 Traits::Close(release());
40 }
41
42 ScopedPipe& operator=(ScopedPipe&& other) {
43 if (pipe_ != Traits::kInvalidValue)
44 Traits::Close(release());
45 pipe_ = other.release();
46 return *this;
47 }
48
49 PipeType get() { return pipe_; }
50 PipeType release() {
51 PipeType pipe = pipe_;
52 pipe_ = Traits::kInvalidValue;
53 return pipe;
54 }
55
56 bool operator==(const ScopedPipe& other) const {
57 return pipe_ == other.pipe_;
58 }
59 bool operator!=(const ScopedPipe& other) const { return !(*this == other); }
60
61 explicit operator bool() const { return pipe_ != Traits::kInvalidValue; }
62
63 private:
64 PipeType pipe_;
65};
66
67using ScopedFd = ScopedPipe<IntFdTraits>;
68
69} // namespace openscreen
70
71#endif