1 /* 2 * Copyright 2012, 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 BCC_SUPPORT_FILE_BASE_H 18 #define BCC_SUPPORT_FILE_BASE_H 19 20 #include <fcntl.h> 21 22 #include <string> 23 24 #include <llvm/Support/system_error.h> 25 26 namespace android { 27 class FileMap; 28 } 29 30 namespace bcc { 31 32 class FileBase { 33 public: 34 enum OpenModeEnum { 35 kReadMode = 1 << 0, 36 kWriteMode = 1 << 1, 37 kReadWriteMode = (kReadMode | kWriteMode), 38 }; 39 40 enum FlagEnum { 41 kBinary = 1 << 0, 42 kTruncate = 1 << 1, 43 kAppend = 1 << 2, 44 kDeleteOnClose = 1 << 3 45 }; 46 47 enum LockModeEnum { 48 // The shared resource behind the Stream locked in ReadLock mode can be 49 // locked by other processes at the same time. 50 kReadLock, 51 52 // The shared resource behind the Stream locked in WriteLock mode can only 53 // be locked by one process. It's exclusive. That is, the shared resource 54 // cannot have both ReadLock and WriteLock simultaneously. 55 kWriteLock 56 }; 57 58 // Default configuration to the lock(). 59 enum { 60 kDefaultMaxRetryLock = 4, 61 kDefaultRetryLockInterval = 200000UL, 62 }; 63 64 protected: 65 // Grant direct access of the internal file descriptor to the sub-class and 66 // error message such that they can implement their own I/O functionality. 67 int mFD; 68 69 llvm::error_code mError; 70 71 private: 72 std::string mName; 73 74 // The 2nd argument to the POSIX open(). 75 unsigned mOpenFlags; 76 77 // True true if we should call unlock() in destructor. 78 bool mShouldUnlock; 79 80 // True if file should be deleted in destructor. 81 bool mShouldDelete; 82 83 // Open mName with flag mOpenFlags (using POSIX open().) 84 bool open(); 85 86 // Return true if mFD is the corresponded file descriptor to the file named 87 // mName on the filesystem. This check may returns failed, for example, 88 // someone re-create the file with the same name after we openning the file. 89 bool checkFileIntegrity(); 90 91 inline bool reopen() { 92 // It's a private method, and all its callers are the few that can invoke it. 93 // That is, the pre-condition will be checked by the caller. Therefore, we don't 94 // need to check it again in reopen(). 95 close(); 96 return open(); 97 } 98 99 private: 100 FileBase(FileBase &); // Do not implement. 101 void operator=(const FileBase &); // Do not implement. 102 103 protected: 104 // pOpenFlags is the 2nd argument to the POSIX open(). pFlags are the flags to 105 // FileBase. It's a bit set composed by the value defined in 106 // FileBase::FlagEnum. 107 FileBase(const std::string &pFilename, unsigned pOpenFlags, unsigned pFlags); 108 109 void detectError(); 110 111 public: 112 // Lock the file descriptor in given pMode. If pNonblocking is true, the lock 113 // request issued will return immediately when the shared resource is locked. 114 // In this case, it retries pMaxRetry times, each wait pRetryInterval (in 115 // usecs) before the previous retry getting done. 116 // 117 // Only file is allowed to use this API. 118 bool lock(enum LockModeEnum pMode, bool pNonblocking = true, 119 unsigned pMaxRetry = kDefaultMaxRetryLock, 120 useconds_t pRetryInterval = kDefaultRetryLockInterval); 121 122 void unlock(); 123 124 // Map the file content to the memory. 125 // 126 // One who gets non-null android::FileMap returned from this API is responsible 127 // for destroying it after the use. 128 android::FileMap *createMap(off_t pOffset, size_t pLength, bool pIsReadOnly); 129 130 size_t getSize(); 131 132 off_t seek(off_t pOffset); 133 off_t tell(); 134 135 inline bool hasError() const 136 { return (mError.value() != llvm::errc::success); } 137 138 inline const llvm::error_code &getError() const 139 { return mError; } 140 141 // The return value of llvm::error_code::message() is obtained upon the call 142 // and is passed by value (that is, it's not a member of llvm::error_code.) 143 inline std::string getErrorMessage() const 144 { return mError.message(); } 145 146 inline const std::string &getName() const 147 { return mName; } 148 149 void close(); 150 151 virtual ~FileBase(); 152 }; 153 154 } // end namespace bcc 155 156 #endif // BCC_SUPPORT_FILE_BASE_H 157