1 /* 2 * Copyright (C) 2009 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 ART_RUNTIME_BASE_UNIX_FILE_FD_FILE_H_ 18 #define ART_RUNTIME_BASE_UNIX_FILE_FD_FILE_H_ 19 20 #include <fcntl.h> 21 #include <string> 22 #include "base/unix_file/random_access_file.h" 23 #include "base/macros.h" 24 25 namespace unix_file { 26 27 // If true, check whether Flush and Close are called before destruction. 28 static constexpr bool kCheckSafeUsage = true; 29 30 // A RandomAccessFile implementation backed by a file descriptor. 31 // 32 // Not thread safe. 33 class FdFile : public RandomAccessFile { 34 public: 35 FdFile(); 36 // Creates an FdFile using the given file descriptor. Takes ownership of the 37 // file descriptor. (Use DisableAutoClose to retain ownership.) 38 explicit FdFile(int fd, bool checkUsage); 39 explicit FdFile(int fd, const std::string& path, bool checkUsage); 40 41 // Destroys an FdFile, closing the file descriptor if Close hasn't already 42 // been called. (If you care about the return value of Close, call it 43 // yourself; this is meant to handle failure cases and read-only accesses. 44 // Note though that calling Close and checking its return value is still no 45 // guarantee that data actually made it to stable storage.) 46 virtual ~FdFile(); 47 48 // Opens file 'file_path' using 'flags' and 'mode'. 49 bool Open(const std::string& file_path, int flags); 50 bool Open(const std::string& file_path, int flags, mode_t mode); 51 52 // RandomAccessFile API. 53 virtual int Close() WARN_UNUSED; 54 virtual int64_t Read(char* buf, int64_t byte_count, int64_t offset) const WARN_UNUSED; 55 virtual int SetLength(int64_t new_length) WARN_UNUSED; 56 virtual int64_t GetLength() const; 57 virtual int64_t Write(const char* buf, int64_t byte_count, int64_t offset) WARN_UNUSED; 58 virtual int Flush() WARN_UNUSED; 59 60 // Short for SetLength(0); Flush(); Close(); 61 void Erase(); 62 63 // Try to Flush(), then try to Close(); If either fails, call Erase(). 64 int FlushCloseOrErase() WARN_UNUSED; 65 66 // Try to Flush and Close(). Attempts both, but returns the first error. 67 int FlushClose() WARN_UNUSED; 68 69 // Bonus API. 70 int Fd() const; 71 bool IsOpened() const; GetPath()72 const std::string& GetPath() const { 73 return file_path_; 74 } 75 void DisableAutoClose(); 76 bool ReadFully(void* buffer, size_t byte_count) WARN_UNUSED; 77 bool WriteFully(const void* buffer, size_t byte_count) WARN_UNUSED; 78 79 // This enum is public so that we can define the << operator over it. 80 enum class GuardState { 81 kBase, // Base, file has not been flushed or closed. 82 kFlushed, // File has been flushed, but not closed. 83 kClosed, // File has been flushed and closed. 84 kNoCheck // Do not check for the current file instance. 85 }; 86 87 // WARNING: Only use this when you know what you're doing! 88 void MarkUnchecked(); 89 90 protected: 91 // If the guard state indicates checking (!=kNoCheck), go to the target state "target". Print the 92 // given warning if the current state is or exceeds warn_threshold. 93 void moveTo(GuardState target, GuardState warn_threshold, const char* warning); 94 95 // If the guard state indicates checking (<kNoCheck), and is below the target state "target", go 96 // to "target." If the current state is higher (excluding kNoCheck) than the trg state, print the 97 // warning. 98 void moveUp(GuardState target, const char* warning); 99 100 // Forcefully sets the state to the given one. This can overwrite kNoCheck. resetGuard(GuardState new_state)101 void resetGuard(GuardState new_state) { 102 if (kCheckSafeUsage) { 103 guard_state_ = new_state; 104 } 105 } 106 107 GuardState guard_state_; 108 109 private: 110 int fd_; 111 std::string file_path_; 112 bool auto_close_; 113 114 DISALLOW_COPY_AND_ASSIGN(FdFile); 115 }; 116 117 std::ostream& operator<<(std::ostream& os, const FdFile::GuardState& kind); 118 119 } // namespace unix_file 120 121 #endif // ART_RUNTIME_BASE_UNIX_FILE_FD_FILE_H_ 122