1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef NETUTILS_UNIQUEFD_H
18 #define NETUTILS_UNIQUEFD_H
19 
20 #include <unistd.h>
21 #include <ostream>
22 
23 #include "netdutils/Fd.h"
24 
25 namespace android {
26 namespace netdutils {
27 
28 // Stricter unique_fd implementation that:
29 // *) Does not implement release()
30 // *) Does not implicitly cast to int
31 // *) Uses a strongly typed wrapper (Fd) for the underlying file descriptor
32 //
33 // Users of UniqueFd should endeavor to treat this as a completely
34 // opaque object. The only code that should interpret the wrapped
35 // value is in Syscalls.h
36 class UniqueFd {
37   public:
38     UniqueFd() = default;
39 
UniqueFd(Fd fd)40     UniqueFd(Fd fd) : mFd(fd) {}
41 
~UniqueFd()42     ~UniqueFd() { reset(); }
43 
44     // Disallow copy
45     UniqueFd(const UniqueFd&) = delete;
46     UniqueFd& operator=(const UniqueFd&) = delete;
47 
48     // Allow move
UniqueFd(UniqueFd && other)49     UniqueFd(UniqueFd&& other) { std::swap(mFd, other.mFd); }
50     UniqueFd& operator=(UniqueFd&& other) {
51         std::swap(mFd, other.mFd);
52         return *this;
53     }
54 
55     // Cleanup any currently owned Fd, replacing it with the optional
56     // parameter fd
57     void reset(Fd fd = Fd());
58 
59     // Implict cast to Fd
Fd()60     const operator Fd() const { return mFd; }
61 
62   private:
63     Fd mFd;
64 };
65 
66 std::ostream& operator<<(std::ostream& os, const UniqueFd& fd);
67 
68 }  // namespace netdutils
69 }  // namespace android
70 
71 #endif /* NETUTILS_UNIQUEFD_H */
72