1918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin/* 2918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * Copyright (C) 2015 The Android Open Source Project 3918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * 4918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * Licensed under the Apache License, Version 2.0 (the "License"); 5918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * you may not use this file except in compliance with the License. 6918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * You may obtain a copy of the License at 7918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * 8918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * http://www.apache.org/licenses/LICENSE-2.0 9918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * 10918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * Unless required by applicable law or agreed to in writing, software 11918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * distributed under the License is distributed on an "AS IS" BASIS, 12918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * See the License for the specific language governing permissions and 14918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin * limitations under the License. 15918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin */ 16918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 17918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin#ifndef ANDROID_BASE_UNIQUE_FD_H 18918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin#define ANDROID_BASE_UNIQUE_FD_H 19918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 20918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin#include <unistd.h> 21918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 222a7b86337f7b149887588e4df532272abe3e931cChristopher Wiley// DO NOT INCLUDE OTHER LIBBASE HEADERS! 232a7b86337f7b149887588e4df532272abe3e931cChristopher Wiley// This file gets used in libbinder, and libbinder is used everywhere. 242a7b86337f7b149887588e4df532272abe3e931cChristopher Wiley// Including other headers from libbase frequently results in inclusion of 252a7b86337f7b149887588e4df532272abe3e931cChristopher Wiley// android-base/macros.h, which causes macro collisions. 26918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 27c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// Container for a file descriptor that automatically closes the descriptor as 28c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// it goes out of scope. 29c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// 30c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// unique_fd ufd(open("/some/path", "r")); 31c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// if (ufd.get() == -1) return error; 32c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// 33c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// // Do something useful, possibly including 'return'. 34c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// 35c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// return 0; // Descriptor is closed for you. 36c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// 37c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// unique_fd is also known as ScopedFd/ScopedFD/scoped_fd; mentioned here to help 38c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes// you find this class if you're searching for one of those names. 39918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlinnamespace android { 40918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlinnamespace base { 41918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 4213ea01db451b3993d175110a3336a58482be883dJosh Gaostruct DefaultCloser { 4313ea01db451b3993d175110a3336a58482be883dJosh Gao static void Close(int fd) { 4413ea01db451b3993d175110a3336a58482be883dJosh Gao // Even if close(2) fails with EINTR, the fd will have been closed. 4513ea01db451b3993d175110a3336a58482be883dJosh Gao // Using TEMP_FAILURE_RETRY will either lead to EBADF or closing someone 4613ea01db451b3993d175110a3336a58482be883dJosh Gao // else's fd. 4713ea01db451b3993d175110a3336a58482be883dJosh Gao // http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html 4813ea01db451b3993d175110a3336a58482be883dJosh Gao ::close(fd); 4913ea01db451b3993d175110a3336a58482be883dJosh Gao } 5013ea01db451b3993d175110a3336a58482be883dJosh Gao}; 5113ea01db451b3993d175110a3336a58482be883dJosh Gao 5213ea01db451b3993d175110a3336a58482be883dJosh Gaotemplate <typename Closer> 5313ea01db451b3993d175110a3336a58482be883dJosh Gaoclass unique_fd_impl final { 54918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin public: 5513ea01db451b3993d175110a3336a58482be883dJosh Gao unique_fd_impl() : value_(-1) {} 56918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 5713ea01db451b3993d175110a3336a58482be883dJosh Gao explicit unique_fd_impl(int value) : value_(value) {} 585d1b1a8b91a35f465e5af146bcfd5d7b4346854cJosh Gao ~unique_fd_impl() { reset(); } 59918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 6013ea01db451b3993d175110a3336a58482be883dJosh Gao unique_fd_impl(unique_fd_impl&& other) : value_(other.release()) {} 6113ea01db451b3993d175110a3336a58482be883dJosh Gao unique_fd_impl& operator=(unique_fd_impl&& s) { 62918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin reset(s.release()); 63918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin return *this; 64918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin } 65918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 665d1b1a8b91a35f465e5af146bcfd5d7b4346854cJosh Gao void reset(int new_value = -1) { 67c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes if (value_ != -1) { 6813ea01db451b3993d175110a3336a58482be883dJosh Gao Closer::Close(value_); 69c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes } 70918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin value_ = new_value; 71918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin } 72918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 73918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin int get() const { return value_; } 742c5d1d7cd914ec8ebf76c8a59d0889ebf5b538cdElliott Hughes operator int() const { return get(); } 75918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 76c0e6e40cc916747a0a22c2538874348cda0ef607Elliott Hughes int release() __attribute__((warn_unused_result)) { 77918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin int ret = value_; 78918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin value_ = -1; 79918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin return ret; 80918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin } 81918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 82918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin private: 83918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin int value_; 84918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 8513ea01db451b3993d175110a3336a58482be883dJosh Gao unique_fd_impl(const unique_fd_impl&); 8613ea01db451b3993d175110a3336a58482be883dJosh Gao void operator=(const unique_fd_impl&); 87918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin}; 88918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 8913ea01db451b3993d175110a3336a58482be883dJosh Gaousing unique_fd = unique_fd_impl<DefaultCloser>; 9013ea01db451b3993d175110a3336a58482be883dJosh Gao 91918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin} // namespace base 92918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin} // namespace android 93918b9e8dc6dfd7fcbb17a9ac6c4c96fd1bbf78f1Casey Dahlin 946496c4bf6f31bd0714a341d51c1cff7f15938e84Josh Gaotemplate <typename T> 956496c4bf6f31bd0714a341d51c1cff7f15938e84Josh Gaoint close(const android::base::unique_fd_impl<T>&) 966496c4bf6f31bd0714a341d51c1cff7f15938e84Josh Gao#if defined(__clang__) 976496c4bf6f31bd0714a341d51c1cff7f15938e84Josh Gao __attribute__((__unavailable__( 986496c4bf6f31bd0714a341d51c1cff7f15938e84Josh Gao#else 996496c4bf6f31bd0714a341d51c1cff7f15938e84Josh Gao __attribute__((__error__( 1006496c4bf6f31bd0714a341d51c1cff7f15938e84Josh Gao#endif 1016496c4bf6f31bd0714a341d51c1cff7f15938e84Josh Gao "close called on unique_fd" 1026496c4bf6f31bd0714a341d51c1cff7f15938e84Josh Gao ))); 1036496c4bf6f31bd0714a341d51c1cff7f15938e84Josh Gao 10454c72aaccc45edf4832cfdc5053d9ae6acc9bcdfElliott Hughes#endif // ANDROID_BASE_UNIQUE_FD_H 105