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