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. 39namespace android { 40namespace base { 41 42struct DefaultCloser { 43 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 52template <typename Closer> 53class unique_fd_impl final { 54 public: 55 unique_fd_impl() : value_(-1) {} 56 57 explicit unique_fd_impl(int value) : value_(value) {} 58 ~unique_fd_impl() { reset(); } 59 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 73 int get() const { return value_; } 74 operator int() const { return get(); } 75 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 89using unique_fd = unique_fd_impl<DefaultCloser>; 90 91} // namespace base 92} // namespace android 93 94template <typename T> 95int 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