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