• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 PLATFORM_IMPL_SCOPED_PIPE_H_
6 #define PLATFORM_IMPL_SCOPED_PIPE_H_
7 
8 #include <unistd.h>
9 
10 #include <utility>
11 
12 namespace openscreen {
13 
14 struct IntFdTraits {
15   using PipeType = int;
16   static constexpr int kInvalidValue = -1;
17 
CloseIntFdTraits18   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.
28 template <typename Traits>
29 class ScopedPipe {
30  public:
31   using PipeType = typename Traits::PipeType;
32 
ScopedPipe()33   ScopedPipe() : pipe_(Traits::kInvalidValue) {}
ScopedPipe(PipeType pipe)34   explicit ScopedPipe(PipeType pipe) : pipe_(pipe) {}
35   ScopedPipe(const ScopedPipe&) = delete;
ScopedPipe(ScopedPipe && other)36   ScopedPipe(ScopedPipe&& other) : pipe_(other.release()) {}
~ScopedPipe()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 
get()49   PipeType get() const { return pipe_; }
release()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 
67 using ScopedFd = ScopedPipe<IntFdTraits>;
68 
69 }  // namespace openscreen
70 
71 #endif  // PLATFORM_IMPL_SCOPED_PIPE_H_
72