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