• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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