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 PreadFully(void* buffer, size_t byte_count, size_t offset) WARN_UNUSED; 78 bool WriteFully(const void* buffer, size_t byte_count) WARN_UNUSED; 79 80 // This enum is public so that we can define the << operator over it. 81 enum class GuardState { 82 kBase, // Base, file has not been flushed or closed. 83 kFlushed, // File has been flushed, but not closed. 84 kClosed, // File has been flushed and closed. 85 kNoCheck // Do not check for the current file instance. 86 }; 87 88 // WARNING: Only use this when you know what you're doing! 89 void MarkUnchecked(); 90 91 protected: 92 // If the guard state indicates checking (!=kNoCheck), go to the target state "target". Print the 93 // given warning if the current state is or exceeds warn_threshold. 94 void moveTo(GuardState target, GuardState warn_threshold, const char* warning); 95 96 // If the guard state indicates checking (<kNoCheck), and is below the target state "target", go 97 // to "target." If the current state is higher (excluding kNoCheck) than the trg state, print the 98 // warning. 99 void moveUp(GuardState target, const char* warning); 100 101 // Forcefully sets the state to the given one. This can overwrite kNoCheck. resetGuard(GuardState new_state)102 void resetGuard(GuardState new_state) { 103 if (kCheckSafeUsage) { 104 guard_state_ = new_state; 105 } 106 } 107 108 GuardState guard_state_; 109 110 private: 111 int fd_; 112 std::string file_path_; 113 bool auto_close_; 114 115 DISALLOW_COPY_AND_ASSIGN(FdFile); 116 }; 117 118 std::ostream& operator<<(std::ostream& os, const FdFile::GuardState& kind); 119 120 } // namespace unix_file 121 122 #endif // ART_RUNTIME_BASE_UNIX_FILE_FD_FILE_H_ 123