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