blob: ec10e6d1894ee9857386ee07dfd1734684b9958a [file] [log] [blame]
Lingfeng Yang43459932020-10-31 01:34:58 -07001// Copyright 2020 The Android Open Source Project
Lingfeng Yangab677722020-10-30 19:38:10 -07002//
Lingfeng Yang43459932020-10-31 01:34:58 -07003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
Lingfeng Yangab677722020-10-30 19:38:10 -07006//
Lingfeng Yang43459932020-10-31 01:34:58 -07007// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Lingfeng Yangab677722020-10-30 19:38:10 -070014
15#pragma once
16
17#include "base/Compiler.h"
18
19#include <errno.h>
20#ifdef _MSC_VER
21#include "msvc-posix.h"
22#else
23#include <unistd.h>
24#endif
25
26namespace android {
27namespace base {
28
29// Helper class to hold an integer file descriptor, and have the 'close'
30// function called automatically on scope exit, unless the 'release'
31// method was called previously.
32class ScopedFd {
33public:
34 // Default constructor will hold an invalid descriptor.
35 ScopedFd() : fd_(-1) {}
36
37 // Constructor takes ownership of |fd|.
38 explicit ScopedFd(int fd) : fd_(fd) {}
39
40 // Make it movable.
41 ScopedFd(ScopedFd&& other) : fd_(other.fd_) {
42 other.fd_ = -1;
43 }
44
45 ScopedFd& operator=(ScopedFd&& other) {
46 swap(&other);
47 return *this;
48 }
49
50 // Destructor calls close().
51 ~ScopedFd() { close(); }
52
53 // Return the file descriptor value, does _not_ transfer ownership.
54 int get() const { return fd_; }
55
56 // Return the file descriptor value, transfers ownership to the caller.
57 int release() {
58 int fd = fd_;
59 fd_ = -1;
60 return fd;
61 }
62
63 // Return true iff the file descriptor is valid.
64 bool valid() const { return fd_ >= 0; }
65
66 // Close the file descriptor (and make the wrapped value invalid).
67 void close() {
68 if (fd_ != -1) {
69 int save_errno = errno;
70 ::close(fd_);
71 fd_ = -1;
72 errno = save_errno;
73 }
74 }
75
76 // Swap two ScopedFd instances.
77 void swap(ScopedFd* other) {
78 int fd = fd_;
79 fd_ = other->fd_;
80 other->fd_ = fd;
81 }
82
83private:
84 DISALLOW_COPY_AND_ASSIGN(ScopedFd);
85
86 int fd_;
87};
88
89} // namespace base
90} // namespace android