1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 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 16 #ifndef OHOS_FILEMGMT_FDSAN_H 17 #define OHOS_FILEMGMT_FDSAN_H 18 19 #include <cstdio> 20 21 struct fdsan_fd { 22 fdsan_fd() = default; 23 fdsan_fdfdsan_fd24 explicit fdsan_fd(int fd) 25 { 26 reset(fd); 27 } 28 29 fdsan_fd(const fdsan_fd& copy) = delete; fdsan_fdfdsan_fd30 fdsan_fd(fdsan_fd&& move) 31 { 32 *this = std::move(move); 33 } 34 ~fdsan_fdfdsan_fd35 ~fdsan_fd() 36 { 37 reset(); 38 } 39 40 fdsan_fd& operator=(const fdsan_fd& copy) = delete; 41 fdsan_fd& operator=(fdsan_fd&& move) 42 { 43 if (this == &move) { 44 return *this; 45 } 46 reset(); 47 if (move.fd_ != -1) { 48 fd_ = move.fd_; 49 move.fd_ = -1; 50 // Acquire ownership from the moved-from object. 51 exchange_tag(fd_, move.tag(), tag()); 52 } 53 return *this; 54 } 55 getfdsan_fd56 int get() 57 { 58 return fd_; 59 } 60 61 void reset(int new_fd = -1) 62 { 63 if (fd_ != -1) { 64 close(fd_, tag()); 65 fd_ = -1; 66 } 67 if (new_fd != -1) { 68 fd_ = new_fd; 69 // Acquire ownership of the presumably unowned fd. 70 exchange_tag(fd_, 0, tag()); 71 } 72 } 73 74 private: 75 int fd_ = -1; 76 77 // Use the address of object as the file tag tagfdsan_fd78 uint64_t tag() 79 { 80 return reinterpret_cast<uint64_t>(this); 81 } 82 exchange_tagfdsan_fd83 static void exchange_tag(int fd, uint64_t old_tag, uint64_t new_tag) 84 { 85 if (&fdsan_exchange_owner_tag) { 86 fdsan_exchange_owner_tag(fd, old_tag, new_tag); 87 } 88 } 89 closefdsan_fd90 static int close(int fd, uint64_t tag) 91 { 92 if (&fdsan_close_with_tag) { 93 return fdsan_close_with_tag(fd, tag); 94 } 95 } 96 }; 97 #endif // OHOS_FILEMGMT_FDSAN_H