1761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes/* 2761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * Copyright (C) 2009 The Android Open Source Project 3761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * 4761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * you may not use this file except in compliance with the License. 6761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * You may obtain a copy of the License at 7761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * 8761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * 10761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * See the License for the specific language governing permissions and 14761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes * limitations under the License. 15761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes */ 16761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_BASE_UNIX_FILE_FD_FILE_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_BASE_UNIX_FILE_FD_FILE_H_ 19761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 20761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include <fcntl.h> 21761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include <string> 22761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/random_access_file.h" 23761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h" 24761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 25761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesnamespace unix_file { 26761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 279433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe// If true, check whether Flush and Close are called before destruction. 289433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampestatic constexpr bool kCheckSafeUsage = true; 299433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe 30761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes// A RandomAccessFile implementation backed by a file descriptor. 31761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes// 32761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes// Not thread safe. 33761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughesclass FdFile : public RandomAccessFile { 34761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes public: 35761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes FdFile(); 36761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes // Creates an FdFile using the given file descriptor. Takes ownership of the 37761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes // file descriptor. (Use DisableAutoClose to retain ownership.) 389433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe explicit FdFile(int fd, bool checkUsage); 399433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe explicit FdFile(int fd, const std::string& path, bool checkUsage); 40761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 41761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes // Destroys an FdFile, closing the file descriptor if Close hasn't already 42761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes // been called. (If you care about the return value of Close, call it 43761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes // yourself; this is meant to handle failure cases and read-only accesses. 44761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes // Note though that calling Close and checking its return value is still no 45761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes // guarantee that data actually made it to stable storage.) 46761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes virtual ~FdFile(); 47761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 48761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes // Opens file 'file_path' using 'flags' and 'mode'. 49761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes bool Open(const std::string& file_path, int flags); 50761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes bool Open(const std::string& file_path, int flags, mode_t mode); 51761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 52761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes // RandomAccessFile API. 539433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe virtual int Close() WARN_UNUSED; 549433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe virtual int64_t Read(char* buf, int64_t byte_count, int64_t offset) const WARN_UNUSED; 559433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe virtual int SetLength(int64_t new_length) WARN_UNUSED; 56761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes virtual int64_t GetLength() const; 579433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe virtual int64_t Write(const char* buf, int64_t byte_count, int64_t offset) WARN_UNUSED; 589433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe virtual int Flush() WARN_UNUSED; 599433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe 609433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe // Short for SetLength(0); Flush(); Close(); 619433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe void Erase(); 629433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe 639433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe // Try to Flush(), then try to Close(); If either fails, call Erase(). 649433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe int FlushCloseOrErase() WARN_UNUSED; 659433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe 669433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe // Try to Flush and Close(). Attempts both, but returns the first error. 679433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe int FlushClose() WARN_UNUSED; 68761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 69761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes // Bonus API. 70761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes int Fd() const; 71761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes bool IsOpened() const; 728d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const std::string& GetPath() const { 738d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers return file_path_; 748d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 75761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes void DisableAutoClose(); 769433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe bool ReadFully(void* buffer, size_t byte_count) WARN_UNUSED; 779433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe bool WriteFully(const void* buffer, size_t byte_count) WARN_UNUSED; 789433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe 799433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe // This enum is public so that we can define the << operator over it. 809433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe enum class GuardState { 819433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe kBase, // Base, file has not been flushed or closed. 829433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe kFlushed, // File has been flushed, but not closed. 839433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe kClosed, // File has been flushed and closed. 849433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe kNoCheck // Do not check for the current file instance. 859433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe }; 869433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe 8762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe // WARNING: Only use this when you know what you're doing! 8862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe void MarkUnchecked(); 8962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe 909433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe protected: 919433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe // If the guard state indicates checking (!=kNoCheck), go to the target state "target". Print the 929433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe // given warning if the current state is or exceeds warn_threshold. 939433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe void moveTo(GuardState target, GuardState warn_threshold, const char* warning); 949433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe 959433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe // If the guard state indicates checking (<kNoCheck), and is below the target state "target", go 969433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe // to "target." If the current state is higher (excluding kNoCheck) than the trg state, print the 979433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe // warning. 989433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe void moveUp(GuardState target, const char* warning); 999433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe 1009433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe // Forcefully sets the state to the given one. This can overwrite kNoCheck. 1019433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe void resetGuard(GuardState new_state) { 1029433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe if (kCheckSafeUsage) { 1039433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe guard_state_ = new_state; 1049433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe } 1059433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe } 1069433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe 1079433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe GuardState guard_state_; 108761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 109761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes private: 110761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes int fd_; 111761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes std::string file_path_; 112761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes bool auto_close_; 113761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 114761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes DISALLOW_COPY_AND_ASSIGN(FdFile); 115761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes}; 116761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 1179433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampestd::ostream& operator<<(std::ostream& os, const FdFile::GuardState& kind); 1189433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe 119761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes} // namespace unix_file 120761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes 121fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_BASE_UNIX_FILE_FD_FILE_H_ 122