blob: 830988ca5dcf3f5e88fe73fdfff50198952b953c [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
btolscha21e8ed2018-08-30 15:13:48 -07005#ifndef BASE_SCOPED_PIPE_H_
6#define BASE_SCOPED_PIPE_H_
btolsch50905ba2018-07-25 14:12:32 -07007
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
Yuri Wiitala43392b92018-10-31 17:47:19 -070049 PipeType get() const { return pipe_; }
btolsch50905ba2018-07-25 14:12:32 -070050 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
btolscha21e8ed2018-08-30 15:13:48 -070071#endif // BASE_SCOPED_PIPE_H_