1 // Copyright 2020 The Android Open Source Project 2 // 3 // 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 6 // 7 // 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. 14 15 #pragma once 16 17 #include "aemu/base/Compiler.h" 18 19 #include <errno.h> 20 #ifdef _MSC_VER 21 #include "aemu/base/msvc.h" 22 #else 23 #include <unistd.h> 24 #endif 25 26 namespace android { 27 namespace 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. 32 class ScopedFd { 33 public: 34 // Default constructor will hold an invalid descriptor. ScopedFd()35 ScopedFd() : fd_(-1) {} 36 37 // Constructor takes ownership of |fd|. ScopedFd(int fd)38 explicit ScopedFd(int fd) : fd_(fd) {} 39 40 // Make it movable. ScopedFd(ScopedFd && other)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(). ~ScopedFd()51 ~ScopedFd() { close(); } 52 53 // Return the file descriptor value, does _not_ transfer ownership. get()54 int get() const { return fd_; } 55 56 // Return the file descriptor value, transfers ownership to the caller. release()57 int release() { 58 int fd = fd_; 59 fd_ = -1; 60 return fd; 61 } 62 63 // Return true iff the file descriptor is valid. valid()64 bool valid() const { return fd_ >= 0; } 65 66 // Close the file descriptor (and make the wrapped value invalid). close()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. swap(ScopedFd * other)77 void swap(ScopedFd* other) { 78 int fd = fd_; 79 fd_ = other->fd_; 80 other->fd_ = fd; 81 } 82 83 private: 84 DISALLOW_COPY_AND_ASSIGN(ScopedFd); 85 86 int fd_; 87 }; 88 89 } // namespace base 90 } // namespace android 91