14f94c520f8d699a5973956a1716272146be17128Zonr Chang/* 24f94c520f8d699a5973956a1716272146be17128Zonr Chang * Copyright 2012, The Android Open Source Project 34f94c520f8d699a5973956a1716272146be17128Zonr Chang * 44f94c520f8d699a5973956a1716272146be17128Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 54f94c520f8d699a5973956a1716272146be17128Zonr Chang * you may not use this file except in compliance with the License. 64f94c520f8d699a5973956a1716272146be17128Zonr Chang * You may obtain a copy of the License at 74f94c520f8d699a5973956a1716272146be17128Zonr Chang * 84f94c520f8d699a5973956a1716272146be17128Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 94f94c520f8d699a5973956a1716272146be17128Zonr Chang * 104f94c520f8d699a5973956a1716272146be17128Zonr Chang * Unless required by applicable law or agreed to in writing, software 114f94c520f8d699a5973956a1716272146be17128Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 124f94c520f8d699a5973956a1716272146be17128Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f94c520f8d699a5973956a1716272146be17128Zonr Chang * See the License for the specific language governing permissions and 144f94c520f8d699a5973956a1716272146be17128Zonr Chang * limitations under the License. 154f94c520f8d699a5973956a1716272146be17128Zonr Chang */ 164f94c520f8d699a5973956a1716272146be17128Zonr Chang 17c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/FileBase.h" 184f94c520f8d699a5973956a1716272146be17128Zonr Chang 194f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <sys/file.h> 204f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <sys/stat.h> 214f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <unistd.h> 224f94c520f8d699a5973956a1716272146be17128Zonr Chang 234f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <cerrno> 244f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <new> 254f94c520f8d699a5973956a1716272146be17128Zonr Chang 264f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <utils/FileMap.h> 274f94c520f8d699a5973956a1716272146be17128Zonr Chang 284f94c520f8d699a5973956a1716272146be17128Zonr Changusing namespace bcc; 294f94c520f8d699a5973956a1716272146be17128Zonr Chang 304f94c520f8d699a5973956a1716272146be17128Zonr ChangFileBase::FileBase(const std::string &pFilename, 314f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned pOpenFlags, 324f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned pFlags) 334f94c520f8d699a5973956a1716272146be17128Zonr Chang : mFD(-1), 344f94c520f8d699a5973956a1716272146be17128Zonr Chang mError(), 354f94c520f8d699a5973956a1716272146be17128Zonr Chang mName(pFilename), mOpenFlags(pOpenFlags), 364f94c520f8d699a5973956a1716272146be17128Zonr Chang mShouldUnlock(false) { 374f94c520f8d699a5973956a1716272146be17128Zonr Chang // Process pFlags 384f94c520f8d699a5973956a1716272146be17128Zonr Chang#ifdef O_BINARY 394f94c520f8d699a5973956a1716272146be17128Zonr Chang if (pFlags & kBinary) { 404f94c520f8d699a5973956a1716272146be17128Zonr Chang mOpenFlags |= O_BINARY; 414f94c520f8d699a5973956a1716272146be17128Zonr Chang } 424f94c520f8d699a5973956a1716272146be17128Zonr Chang#endif 43c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao if (pFlags & kTruncate) { 44c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao mOpenFlags |= O_TRUNC; 45c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao } 464f94c520f8d699a5973956a1716272146be17128Zonr Chang 47b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao if (pFlags & kAppend) { 48b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao mOpenFlags |= O_APPEND; 49b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao } 50b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao 514f94c520f8d699a5973956a1716272146be17128Zonr Chang // Open the file. 524f94c520f8d699a5973956a1716272146be17128Zonr Chang open(); 534f94c520f8d699a5973956a1716272146be17128Zonr Chang 544f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 554f94c520f8d699a5973956a1716272146be17128Zonr Chang} 564f94c520f8d699a5973956a1716272146be17128Zonr Chang 574f94c520f8d699a5973956a1716272146be17128Zonr ChangFileBase::~FileBase() { 584f94c520f8d699a5973956a1716272146be17128Zonr Chang close(); 594f94c520f8d699a5973956a1716272146be17128Zonr Chang} 604f94c520f8d699a5973956a1716272146be17128Zonr Chang 614f94c520f8d699a5973956a1716272146be17128Zonr Changbool FileBase::open() { 624f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 634f94c520f8d699a5973956a1716272146be17128Zonr Chang // FIXME: Hard-coded permissions (0644) for newly created file should be 644f94c520f8d699a5973956a1716272146be17128Zonr Chang // removed and provide a way to let the user configure the value. 654f94c520f8d699a5973956a1716272146be17128Zonr Chang mFD = ::open(mName.c_str(), mOpenFlags, 0644); 664f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD > 0) { 674f94c520f8d699a5973956a1716272146be17128Zonr Chang return true; 684f94c520f8d699a5973956a1716272146be17128Zonr Chang } 694f94c520f8d699a5973956a1716272146be17128Zonr Chang 704f94c520f8d699a5973956a1716272146be17128Zonr Chang // Some errors occurred ... 714f94c520f8d699a5973956a1716272146be17128Zonr Chang if (errno != EINTR) { 724f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 734f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 744f94c520f8d699a5973956a1716272146be17128Zonr Chang } 754f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 764f94c520f8d699a5973956a1716272146be17128Zonr Chang // unreachable 774f94c520f8d699a5973956a1716272146be17128Zonr Chang} 784f94c520f8d699a5973956a1716272146be17128Zonr Chang 794f94c520f8d699a5973956a1716272146be17128Zonr Chang 804f94c520f8d699a5973956a1716272146be17128Zonr Changbool FileBase::checkFileIntegrity() { 814f94c520f8d699a5973956a1716272146be17128Zonr Chang // Check the file integrity by examining whether the inode referring to the mFD 824f94c520f8d699a5973956a1716272146be17128Zonr Chang // and to the file mName are the same. 834f94c520f8d699a5973956a1716272146be17128Zonr Chang struct stat fd_stat, file_stat; 844f94c520f8d699a5973956a1716272146be17128Zonr Chang 854f94c520f8d699a5973956a1716272146be17128Zonr Chang // Get the file status of file descriptor mFD. 864f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 874f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::fstat(mFD, &fd_stat) == 0) { 884f94c520f8d699a5973956a1716272146be17128Zonr Chang break; 894f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno != EINTR) { 904f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 914f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 924f94c520f8d699a5973956a1716272146be17128Zonr Chang } 934f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 944f94c520f8d699a5973956a1716272146be17128Zonr Chang 954f94c520f8d699a5973956a1716272146be17128Zonr Chang // Get the file status of file mName. 964f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 974f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::stat(mName.c_str(), &file_stat) == 0) { 984f94c520f8d699a5973956a1716272146be17128Zonr Chang break; 994f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno != EINTR) { 1004f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 1014f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1024f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1034f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 1044f94c520f8d699a5973956a1716272146be17128Zonr Chang 1054f94c520f8d699a5973956a1716272146be17128Zonr Chang return ((fd_stat.st_dev == file_stat.st_dev) && 1064f94c520f8d699a5973956a1716272146be17128Zonr Chang (fd_stat.st_ino == file_stat.st_ino)); 1074f94c520f8d699a5973956a1716272146be17128Zonr Chang} 1084f94c520f8d699a5973956a1716272146be17128Zonr Chang 1094f94c520f8d699a5973956a1716272146be17128Zonr Changvoid FileBase::detectError() { 1104f94c520f8d699a5973956a1716272146be17128Zonr Chang // Read error from errno. 1114f94c520f8d699a5973956a1716272146be17128Zonr Chang mError.assign(errno, llvm::posix_category()); 1124f94c520f8d699a5973956a1716272146be17128Zonr Chang} 1134f94c520f8d699a5973956a1716272146be17128Zonr Chang 1144f94c520f8d699a5973956a1716272146be17128Zonr Changbool FileBase::lock(enum LockModeEnum pMode, 1154f94c520f8d699a5973956a1716272146be17128Zonr Chang bool pNonblocking, 1164f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned pMaxRetry, 1174f94c520f8d699a5973956a1716272146be17128Zonr Chang useconds_t pRetryInterval) { 1184f94c520f8d699a5973956a1716272146be17128Zonr Chang int lock_operation; 1194f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned retry = 0; 1204f94c520f8d699a5973956a1716272146be17128Zonr Chang 1214f94c520f8d699a5973956a1716272146be17128Zonr Chang // Check the state. 1224f94c520f8d699a5973956a1716272146be17128Zonr Chang if ((mFD < 0) || hasError()) { 1234f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1244f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1254f94c520f8d699a5973956a1716272146be17128Zonr Chang 1264f94c520f8d699a5973956a1716272146be17128Zonr Chang // Return immediately if it's already locked. 1274f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mShouldUnlock) { 1284f94c520f8d699a5973956a1716272146be17128Zonr Chang return true; 1294f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1304f94c520f8d699a5973956a1716272146be17128Zonr Chang 1314f94c520f8d699a5973956a1716272146be17128Zonr Chang // Determine the lock operation (2nd argument) to the flock(). 1324f94c520f8d699a5973956a1716272146be17128Zonr Chang if (pMode == kReadLock) { 1334f94c520f8d699a5973956a1716272146be17128Zonr Chang lock_operation = LOCK_SH; 1344f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (pMode == kWriteLock) { 1354f94c520f8d699a5973956a1716272146be17128Zonr Chang lock_operation = LOCK_EX; 1364f94c520f8d699a5973956a1716272146be17128Zonr Chang } else { 1374f94c520f8d699a5973956a1716272146be17128Zonr Chang mError.assign(llvm::errc::invalid_argument, llvm::posix_category()); 1384f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1394f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1404f94c520f8d699a5973956a1716272146be17128Zonr Chang 1414f94c520f8d699a5973956a1716272146be17128Zonr Chang if (pNonblocking) { 1424f94c520f8d699a5973956a1716272146be17128Zonr Chang lock_operation |= LOCK_NB; 1434f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1444f94c520f8d699a5973956a1716272146be17128Zonr Chang 1454f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 1464f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::flock(mFD, lock_operation) == 0) { 1474f94c520f8d699a5973956a1716272146be17128Zonr Chang mShouldUnlock = true; 1484f94c520f8d699a5973956a1716272146be17128Zonr Chang // Here we got a lock but we need to check whether the mFD still 1494f94c520f8d699a5973956a1716272146be17128Zonr Chang // "represents" the filename (mName) we opened in the contructor. This 1504f94c520f8d699a5973956a1716272146be17128Zonr Chang // check may failed when another process deleted the original file mFD 1514f94c520f8d699a5973956a1716272146be17128Zonr Chang // mapped when we were trying to obtain the lock on the file. 1524f94c520f8d699a5973956a1716272146be17128Zonr Chang if (!checkFileIntegrity()) { 1534f94c520f8d699a5973956a1716272146be17128Zonr Chang if (hasError() || !reopen()) { 1544f94c520f8d699a5973956a1716272146be17128Zonr Chang // Error occurred when check the file integrity or re-open the file. 1554f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1564f94c520f8d699a5973956a1716272146be17128Zonr Chang } else { 1574f94c520f8d699a5973956a1716272146be17128Zonr Chang // Wait a while before the next try. 1584f94c520f8d699a5973956a1716272146be17128Zonr Chang ::usleep(pRetryInterval); 1594f94c520f8d699a5973956a1716272146be17128Zonr Chang retry++; 1604f94c520f8d699a5973956a1716272146be17128Zonr Chang continue; 1614f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1624f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1634f94c520f8d699a5973956a1716272146be17128Zonr Chang 1644f94c520f8d699a5973956a1716272146be17128Zonr Chang return true; 1654f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1664f94c520f8d699a5973956a1716272146be17128Zonr Chang 1674f94c520f8d699a5973956a1716272146be17128Zonr Chang // flock() was not performed successfully. Check the errno to see whether 1684f94c520f8d699a5973956a1716272146be17128Zonr Chang // it's retry-able. 1694f94c520f8d699a5973956a1716272146be17128Zonr Chang if (errno == EINTR) { 1704f94c520f8d699a5973956a1716272146be17128Zonr Chang // flock() was interrupted by delivery of a signal. Restart without 1714f94c520f8d699a5973956a1716272146be17128Zonr Chang // decrement the retry counter. 1724f94c520f8d699a5973956a1716272146be17128Zonr Chang continue; 1734f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno == EWOULDBLOCK) { 1744f94c520f8d699a5973956a1716272146be17128Zonr Chang // The file descriptor was locked by others, wait for a while before next 1754f94c520f8d699a5973956a1716272146be17128Zonr Chang // retry. 1764f94c520f8d699a5973956a1716272146be17128Zonr Chang retry++; 1774f94c520f8d699a5973956a1716272146be17128Zonr Chang ::usleep(pRetryInterval); 1784f94c520f8d699a5973956a1716272146be17128Zonr Chang } else { 1794f94c520f8d699a5973956a1716272146be17128Zonr Chang // There's a fatal error occurs when perform flock(). Return immediately 1804f94c520f8d699a5973956a1716272146be17128Zonr Chang // without further retry. 1814f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 1824f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1834f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1844f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (retry <= pMaxRetry); 1854f94c520f8d699a5973956a1716272146be17128Zonr Chang 1864f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1874f94c520f8d699a5973956a1716272146be17128Zonr Chang} 1884f94c520f8d699a5973956a1716272146be17128Zonr Chang 1894f94c520f8d699a5973956a1716272146be17128Zonr Changvoid FileBase::unlock() { 1904f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD < 0) { 1914f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 1924f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1934f94c520f8d699a5973956a1716272146be17128Zonr Chang 1944f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 1954f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::flock(mFD, LOCK_UN) == 0) { 1964f94c520f8d699a5973956a1716272146be17128Zonr Chang mShouldUnlock = false; 1974f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 1984f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1994f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (errno == EINTR); 2004f94c520f8d699a5973956a1716272146be17128Zonr Chang 2014f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2024f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 2034f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2044f94c520f8d699a5973956a1716272146be17128Zonr Chang 2054f94c520f8d699a5973956a1716272146be17128Zonr Changandroid::FileMap *FileBase::createMap(off_t pOffset, size_t pLength, 2064f94c520f8d699a5973956a1716272146be17128Zonr Chang bool pIsReadOnly) { 2074f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD < 0 || hasError()) { 2084f94c520f8d699a5973956a1716272146be17128Zonr Chang return NULL; 2094f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2104f94c520f8d699a5973956a1716272146be17128Zonr Chang 2114f94c520f8d699a5973956a1716272146be17128Zonr Chang android::FileMap *map = new (std::nothrow) android::FileMap(); 2124f94c520f8d699a5973956a1716272146be17128Zonr Chang if (map == NULL) { 2134f94c520f8d699a5973956a1716272146be17128Zonr Chang mError.assign(llvm::errc::not_enough_memory, llvm::system_category()); 2144f94c520f8d699a5973956a1716272146be17128Zonr Chang return NULL; 2154f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2164f94c520f8d699a5973956a1716272146be17128Zonr Chang 2174f94c520f8d699a5973956a1716272146be17128Zonr Chang if (!map->create(NULL, mFD, pOffset, pLength, pIsReadOnly)) { 2184f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2194f94c520f8d699a5973956a1716272146be17128Zonr Chang map->release(); 2204f94c520f8d699a5973956a1716272146be17128Zonr Chang return NULL; 2214f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2224f94c520f8d699a5973956a1716272146be17128Zonr Chang 2234f94c520f8d699a5973956a1716272146be17128Zonr Chang return map; 2244f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2254f94c520f8d699a5973956a1716272146be17128Zonr Chang 2264f94c520f8d699a5973956a1716272146be17128Zonr Changsize_t FileBase::getSize() { 2274f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD < 0 || hasError()) { 2284f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<size_t>(-1); 2294f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2304f94c520f8d699a5973956a1716272146be17128Zonr Chang 2314f94c520f8d699a5973956a1716272146be17128Zonr Chang struct stat file_stat; 2324f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2334f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::fstat(mFD, &file_stat) == 0) { 2344f94c520f8d699a5973956a1716272146be17128Zonr Chang break; 2354f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno != EINTR) { 2364f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2374f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<size_t>(-1); 2384f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2394f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 2404f94c520f8d699a5973956a1716272146be17128Zonr Chang 2414f94c520f8d699a5973956a1716272146be17128Zonr Chang return file_stat.st_size; 2424f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2434f94c520f8d699a5973956a1716272146be17128Zonr Chang 2444f94c520f8d699a5973956a1716272146be17128Zonr Changoff_t FileBase::seek(off_t pOffset) { 2454f94c520f8d699a5973956a1716272146be17128Zonr Chang if ((mFD < 0) || hasError()) { 2464f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2474f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2484f94c520f8d699a5973956a1716272146be17128Zonr Chang 2494f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2504f94c520f8d699a5973956a1716272146be17128Zonr Chang off_t result = ::lseek(mFD, pOffset, SEEK_SET); 2514f94c520f8d699a5973956a1716272146be17128Zonr Chang if (result == pOffset) { 2524f94c520f8d699a5973956a1716272146be17128Zonr Chang return result; 2534f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2544f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (errno == EINTR); 2554f94c520f8d699a5973956a1716272146be17128Zonr Chang 2564f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2574f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2584f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2594f94c520f8d699a5973956a1716272146be17128Zonr Chang 2604f94c520f8d699a5973956a1716272146be17128Zonr Changoff_t FileBase::tell() { 2614f94c520f8d699a5973956a1716272146be17128Zonr Chang if ((mFD < 0) || hasError()) { 2624f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2634f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2644f94c520f8d699a5973956a1716272146be17128Zonr Chang 2654f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2664f94c520f8d699a5973956a1716272146be17128Zonr Chang off_t result = ::lseek(mFD, 0, SEEK_CUR); 2674f94c520f8d699a5973956a1716272146be17128Zonr Chang if (result != static_cast<off_t>(-1)) { 2684f94c520f8d699a5973956a1716272146be17128Zonr Chang return result; 2694f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2704f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (errno == EINTR); 2714f94c520f8d699a5973956a1716272146be17128Zonr Chang 2724f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2734f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2744f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2754f94c520f8d699a5973956a1716272146be17128Zonr Chang 2764f94c520f8d699a5973956a1716272146be17128Zonr Changvoid FileBase::close() { 2774f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mShouldUnlock) { 2784f94c520f8d699a5973956a1716272146be17128Zonr Chang unlock(); 2794f94c520f8d699a5973956a1716272146be17128Zonr Chang mShouldUnlock = false; 2804f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2814f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD > 0) { 2824f94c520f8d699a5973956a1716272146be17128Zonr Chang ::close(mFD); 2834f94c520f8d699a5973956a1716272146be17128Zonr Chang mFD = -1; 2844f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2854f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 2864f94c520f8d699a5973956a1716272146be17128Zonr Chang} 287