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