1 /* 2 * Copyright (C) 2015 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 ANDROID_BASE_UNIQUE_FD_H 18 #define ANDROID_BASE_UNIQUE_FD_H 19 20 #include <unistd.h> 21 22 // DO NOT INCLUDE OTHER LIBBASE HEADERS! 23 // This file gets used in libbinder, and libbinder is used everywhere. 24 // Including other headers from libbase frequently results in inclusion of 25 // android-base/macros.h, which causes macro collisions. 26 27 // Container for a file descriptor that automatically closes the descriptor as 28 // it goes out of scope. 29 // 30 // unique_fd ufd(open("/some/path", "r")); 31 // if (ufd.get() == -1) return error; 32 // 33 // // Do something useful, possibly including 'return'. 34 // 35 // return 0; // Descriptor is closed for you. 36 // 37 // unique_fd is also known as ScopedFd/ScopedFD/scoped_fd; mentioned here to help 38 // you find this class if you're searching for one of those names. 39 namespace android { 40 namespace base { 41 42 struct DefaultCloser { CloseDefaultCloser43 static void Close(int fd) { 44 // Even if close(2) fails with EINTR, the fd will have been closed. 45 // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone 46 // else's fd. 47 // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html 48 ::close(fd); 49 } 50 }; 51 52 template <typename Closer> 53 class unique_fd_impl final { 54 public: unique_fd_impl()55 unique_fd_impl() : value_(-1) {} 56 unique_fd_impl(int value)57 explicit unique_fd_impl(int value) : value_(value) {} ~unique_fd_impl()58 ~unique_fd_impl() { reset(); } 59 unique_fd_impl(unique_fd_impl && other)60 unique_fd_impl(unique_fd_impl&& other) : value_(other.release()) {} 61 unique_fd_impl& operator=(unique_fd_impl&& s) { 62 reset(s.release()); 63 return *this; 64 } 65 66 void reset(int new_value = -1) { 67 if (value_ != -1) { 68 Closer::Close(value_); 69 } 70 value_ = new_value; 71 } 72 get()73 int get() const { return value_; } 74 operator int() const { return get(); } 75 release()76 int release() __attribute__((warn_unused_result)) { 77 int ret = value_; 78 value_ = -1; 79 return ret; 80 } 81 82 private: 83 int value_; 84 85 unique_fd_impl(const unique_fd_impl&); 86 void operator=(const unique_fd_impl&); 87 }; 88 89 using unique_fd = unique_fd_impl<DefaultCloser>; 90 91 } // namespace base 92 } // namespace android 93 94 template <typename T> 95 int close(const android::base::unique_fd_impl<T>&) 96 #if defined(__clang__) 97 __attribute__((__unavailable__( 98 #else 99 __attribute__((__error__( 100 #endif 101 "close called on unique_fd" 102 ))); 103 104 #endif // ANDROID_BASE_UNIQUE_FD_H 105