unique_fd.h revision 2a7b86337f7b149887588e4df532272abe3e931c
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 42class unique_fd final { 43 public: 44 unique_fd() : value_(-1) {} 45 46 explicit unique_fd(int value) : value_(value) {} 47 ~unique_fd() { clear(); } 48 49 unique_fd(unique_fd&& other) : value_(other.release()) {} 50 unique_fd& operator=(unique_fd&& s) { 51 reset(s.release()); 52 return *this; 53 } 54 55 void reset(int new_value) { 56 if (value_ != -1) { 57 // Even if close(2) fails with EINTR, the fd will have been closed. 58 // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone else's fd. 59 // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html 60 close(value_); 61 } 62 value_ = new_value; 63 } 64 65 void clear() { 66 reset(-1); 67 } 68 69 int get() const { return value_; } 70 operator int() const { return get(); } 71 72 int release() __attribute__((warn_unused_result)) { 73 int ret = value_; 74 value_ = -1; 75 return ret; 76 } 77 78 private: 79 int value_; 80 81 unique_fd(const unique_fd&); 82 void operator=(const unique_fd&); 83}; 84 85} // namespace base 86} // namespace android 87 88#endif // ANDROID_BASE_UNIQUE_FD_H 89