FileBase.cpp revision 48cd745480738c026312931877ecb8ebecb1c64e
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 19331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include "bcc/Support/Log.h" 20331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines 214f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <sys/file.h> 224f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <sys/stat.h> 234f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <unistd.h> 244f94c520f8d699a5973956a1716272146be17128Zonr Chang 254f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <cerrno> 26331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines#include <cstring> 274f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <new> 284f94c520f8d699a5973956a1716272146be17128Zonr Chang 294f94c520f8d699a5973956a1716272146be17128Zonr Chang#include <utils/FileMap.h> 304f94c520f8d699a5973956a1716272146be17128Zonr Chang 314f94c520f8d699a5973956a1716272146be17128Zonr Changusing namespace bcc; 324f94c520f8d699a5973956a1716272146be17128Zonr Chang 3348cd745480738c026312931877ecb8ebecb1c64eStephen Hines#ifdef _WIN32 3448cd745480738c026312931877ecb8ebecb1c64eStephen Hines// TODO: Fix flock usage under windows 3548cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define LOCK_SH 0 3648cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define LOCK_EX 0 3748cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define LOCK_NB 0 3848cd745480738c026312931877ecb8ebecb1c64eStephen Hines#define LOCK_UN 0 3948cd745480738c026312931877ecb8ebecb1c64eStephen Hines 4048cd745480738c026312931877ecb8ebecb1c64eStephen Hinesint flock(int fd, int operation) { 4148cd745480738c026312931877ecb8ebecb1c64eStephen Hines return 0; 4248cd745480738c026312931877ecb8ebecb1c64eStephen Hines} 4348cd745480738c026312931877ecb8ebecb1c64eStephen Hines#endif // _WIN32 4448cd745480738c026312931877ecb8ebecb1c64eStephen Hines 454f94c520f8d699a5973956a1716272146be17128Zonr ChangFileBase::FileBase(const std::string &pFilename, 464f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned pOpenFlags, 474f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned pFlags) 484f94c520f8d699a5973956a1716272146be17128Zonr Chang : mFD(-1), 494f94c520f8d699a5973956a1716272146be17128Zonr Chang mError(), 504f94c520f8d699a5973956a1716272146be17128Zonr Chang mName(pFilename), mOpenFlags(pOpenFlags), 51331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines mShouldUnlock(false), 52331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines mShouldDelete(false) { 534f94c520f8d699a5973956a1716272146be17128Zonr Chang // Process pFlags 544f94c520f8d699a5973956a1716272146be17128Zonr Chang#ifdef O_BINARY 554f94c520f8d699a5973956a1716272146be17128Zonr Chang if (pFlags & kBinary) { 564f94c520f8d699a5973956a1716272146be17128Zonr Chang mOpenFlags |= O_BINARY; 574f94c520f8d699a5973956a1716272146be17128Zonr Chang } 584f94c520f8d699a5973956a1716272146be17128Zonr Chang#endif 59c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao if (pFlags & kTruncate) { 60c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao mOpenFlags |= O_TRUNC; 61c02eae6f35de7dfd92233d591b27c05f15c2a6a1Shih-wei Liao } 624f94c520f8d699a5973956a1716272146be17128Zonr Chang 63b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao if (pFlags & kAppend) { 64b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao mOpenFlags |= O_APPEND; 65b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao } 66b2b8c64cd0524f9210218df4738f40409631ea26Shih-wei Liao 67331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines if (pFlags & kDeleteOnClose) { 68331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines mShouldDelete = true; 69331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines } 70331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines 714f94c520f8d699a5973956a1716272146be17128Zonr Chang // Open the file. 724f94c520f8d699a5973956a1716272146be17128Zonr Chang open(); 734f94c520f8d699a5973956a1716272146be17128Zonr Chang 744f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 754f94c520f8d699a5973956a1716272146be17128Zonr Chang} 764f94c520f8d699a5973956a1716272146be17128Zonr Chang 774f94c520f8d699a5973956a1716272146be17128Zonr ChangFileBase::~FileBase() { 784f94c520f8d699a5973956a1716272146be17128Zonr Chang close(); 794f94c520f8d699a5973956a1716272146be17128Zonr Chang} 804f94c520f8d699a5973956a1716272146be17128Zonr Chang 814f94c520f8d699a5973956a1716272146be17128Zonr Changbool FileBase::open() { 824f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 834f94c520f8d699a5973956a1716272146be17128Zonr Chang // FIXME: Hard-coded permissions (0644) for newly created file should be 844f94c520f8d699a5973956a1716272146be17128Zonr Chang // removed and provide a way to let the user configure the value. 854f94c520f8d699a5973956a1716272146be17128Zonr Chang mFD = ::open(mName.c_str(), mOpenFlags, 0644); 864f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD > 0) { 874f94c520f8d699a5973956a1716272146be17128Zonr Chang return true; 884f94c520f8d699a5973956a1716272146be17128Zonr Chang } 894f94c520f8d699a5973956a1716272146be17128Zonr Chang 904f94c520f8d699a5973956a1716272146be17128Zonr Chang // Some errors occurred ... 914f94c520f8d699a5973956a1716272146be17128Zonr Chang if (errno != EINTR) { 924f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 934f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 944f94c520f8d699a5973956a1716272146be17128Zonr Chang } 954f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 964f94c520f8d699a5973956a1716272146be17128Zonr Chang // unreachable 974f94c520f8d699a5973956a1716272146be17128Zonr Chang} 984f94c520f8d699a5973956a1716272146be17128Zonr Chang 994f94c520f8d699a5973956a1716272146be17128Zonr Chang 1004f94c520f8d699a5973956a1716272146be17128Zonr Changbool FileBase::checkFileIntegrity() { 1014f94c520f8d699a5973956a1716272146be17128Zonr Chang // Check the file integrity by examining whether the inode referring to the mFD 1024f94c520f8d699a5973956a1716272146be17128Zonr Chang // and to the file mName are the same. 1034f94c520f8d699a5973956a1716272146be17128Zonr Chang struct stat fd_stat, file_stat; 1044f94c520f8d699a5973956a1716272146be17128Zonr Chang 1054f94c520f8d699a5973956a1716272146be17128Zonr Chang // Get the file status of file descriptor mFD. 1064f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 1074f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::fstat(mFD, &fd_stat) == 0) { 1084f94c520f8d699a5973956a1716272146be17128Zonr Chang break; 1094f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno != EINTR) { 1104f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 1114f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1124f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1134f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 1144f94c520f8d699a5973956a1716272146be17128Zonr Chang 1154f94c520f8d699a5973956a1716272146be17128Zonr Chang // Get the file status of file mName. 1164f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 1174f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::stat(mName.c_str(), &file_stat) == 0) { 1184f94c520f8d699a5973956a1716272146be17128Zonr Chang break; 1194f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno != EINTR) { 1204f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 1214f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1224f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1234f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 1244f94c520f8d699a5973956a1716272146be17128Zonr Chang 1254f94c520f8d699a5973956a1716272146be17128Zonr Chang return ((fd_stat.st_dev == file_stat.st_dev) && 1264f94c520f8d699a5973956a1716272146be17128Zonr Chang (fd_stat.st_ino == file_stat.st_ino)); 1274f94c520f8d699a5973956a1716272146be17128Zonr Chang} 1284f94c520f8d699a5973956a1716272146be17128Zonr Chang 1294f94c520f8d699a5973956a1716272146be17128Zonr Changvoid FileBase::detectError() { 1304f94c520f8d699a5973956a1716272146be17128Zonr Chang // Read error from errno. 1314f94c520f8d699a5973956a1716272146be17128Zonr Chang mError.assign(errno, llvm::posix_category()); 1324f94c520f8d699a5973956a1716272146be17128Zonr Chang} 1334f94c520f8d699a5973956a1716272146be17128Zonr Chang 1344f94c520f8d699a5973956a1716272146be17128Zonr Changbool FileBase::lock(enum LockModeEnum pMode, 1354f94c520f8d699a5973956a1716272146be17128Zonr Chang bool pNonblocking, 1364f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned pMaxRetry, 1374f94c520f8d699a5973956a1716272146be17128Zonr Chang useconds_t pRetryInterval) { 1384f94c520f8d699a5973956a1716272146be17128Zonr Chang int lock_operation; 1394f94c520f8d699a5973956a1716272146be17128Zonr Chang unsigned retry = 0; 1404f94c520f8d699a5973956a1716272146be17128Zonr Chang 1414f94c520f8d699a5973956a1716272146be17128Zonr Chang // Check the state. 1424f94c520f8d699a5973956a1716272146be17128Zonr Chang if ((mFD < 0) || hasError()) { 1434f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1444f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1454f94c520f8d699a5973956a1716272146be17128Zonr Chang 1464f94c520f8d699a5973956a1716272146be17128Zonr Chang // Return immediately if it's already locked. 1474f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mShouldUnlock) { 1484f94c520f8d699a5973956a1716272146be17128Zonr Chang return true; 1494f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1504f94c520f8d699a5973956a1716272146be17128Zonr Chang 1514f94c520f8d699a5973956a1716272146be17128Zonr Chang // Determine the lock operation (2nd argument) to the flock(). 1524f94c520f8d699a5973956a1716272146be17128Zonr Chang if (pMode == kReadLock) { 1534f94c520f8d699a5973956a1716272146be17128Zonr Chang lock_operation = LOCK_SH; 1544f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (pMode == kWriteLock) { 1554f94c520f8d699a5973956a1716272146be17128Zonr Chang lock_operation = LOCK_EX; 1564f94c520f8d699a5973956a1716272146be17128Zonr Chang } else { 1574f94c520f8d699a5973956a1716272146be17128Zonr Chang mError.assign(llvm::errc::invalid_argument, llvm::posix_category()); 1584f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1594f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1604f94c520f8d699a5973956a1716272146be17128Zonr Chang 1614f94c520f8d699a5973956a1716272146be17128Zonr Chang if (pNonblocking) { 1624f94c520f8d699a5973956a1716272146be17128Zonr Chang lock_operation |= LOCK_NB; 1634f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1644f94c520f8d699a5973956a1716272146be17128Zonr Chang 1654f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 1664f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::flock(mFD, lock_operation) == 0) { 1674f94c520f8d699a5973956a1716272146be17128Zonr Chang mShouldUnlock = true; 1684f94c520f8d699a5973956a1716272146be17128Zonr Chang // Here we got a lock but we need to check whether the mFD still 1694f94c520f8d699a5973956a1716272146be17128Zonr Chang // "represents" the filename (mName) we opened in the contructor. This 1704f94c520f8d699a5973956a1716272146be17128Zonr Chang // check may failed when another process deleted the original file mFD 1714f94c520f8d699a5973956a1716272146be17128Zonr Chang // mapped when we were trying to obtain the lock on the file. 1724f94c520f8d699a5973956a1716272146be17128Zonr Chang if (!checkFileIntegrity()) { 1734f94c520f8d699a5973956a1716272146be17128Zonr Chang if (hasError() || !reopen()) { 1744f94c520f8d699a5973956a1716272146be17128Zonr Chang // Error occurred when check the file integrity or re-open the file. 1754f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 1764f94c520f8d699a5973956a1716272146be17128Zonr Chang } else { 1774f94c520f8d699a5973956a1716272146be17128Zonr Chang // Wait a while before the next try. 1784f94c520f8d699a5973956a1716272146be17128Zonr Chang ::usleep(pRetryInterval); 1794f94c520f8d699a5973956a1716272146be17128Zonr Chang retry++; 1804f94c520f8d699a5973956a1716272146be17128Zonr Chang continue; 1814f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1824f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1834f94c520f8d699a5973956a1716272146be17128Zonr Chang 1844f94c520f8d699a5973956a1716272146be17128Zonr Chang return true; 1854f94c520f8d699a5973956a1716272146be17128Zonr Chang } 1864f94c520f8d699a5973956a1716272146be17128Zonr Chang 1874f94c520f8d699a5973956a1716272146be17128Zonr Chang // flock() was not performed successfully. Check the errno to see whether 1884f94c520f8d699a5973956a1716272146be17128Zonr Chang // it's retry-able. 1894f94c520f8d699a5973956a1716272146be17128Zonr Chang if (errno == EINTR) { 1904f94c520f8d699a5973956a1716272146be17128Zonr Chang // flock() was interrupted by delivery of a signal. Restart without 1914f94c520f8d699a5973956a1716272146be17128Zonr Chang // decrement the retry counter. 1924f94c520f8d699a5973956a1716272146be17128Zonr Chang continue; 1934f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno == EWOULDBLOCK) { 1944f94c520f8d699a5973956a1716272146be17128Zonr Chang // The file descriptor was locked by others, wait for a while before next 1954f94c520f8d699a5973956a1716272146be17128Zonr Chang // retry. 1964f94c520f8d699a5973956a1716272146be17128Zonr Chang retry++; 1974f94c520f8d699a5973956a1716272146be17128Zonr Chang ::usleep(pRetryInterval); 1984f94c520f8d699a5973956a1716272146be17128Zonr Chang } else { 1994f94c520f8d699a5973956a1716272146be17128Zonr Chang // There's a fatal error occurs when perform flock(). Return immediately 2004f94c520f8d699a5973956a1716272146be17128Zonr Chang // without further retry. 2014f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2024f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 2034f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2044f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (retry <= pMaxRetry); 2054f94c520f8d699a5973956a1716272146be17128Zonr Chang 2064f94c520f8d699a5973956a1716272146be17128Zonr Chang return false; 2074f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2084f94c520f8d699a5973956a1716272146be17128Zonr Chang 2094f94c520f8d699a5973956a1716272146be17128Zonr Changvoid FileBase::unlock() { 2104f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD < 0) { 2114f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 2124f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2134f94c520f8d699a5973956a1716272146be17128Zonr Chang 2144f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2154f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::flock(mFD, LOCK_UN) == 0) { 2164f94c520f8d699a5973956a1716272146be17128Zonr Chang mShouldUnlock = false; 2174f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 2184f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2194f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (errno == EINTR); 2204f94c520f8d699a5973956a1716272146be17128Zonr Chang 2214f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2224f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 2234f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2244f94c520f8d699a5973956a1716272146be17128Zonr Chang 2254f94c520f8d699a5973956a1716272146be17128Zonr Changandroid::FileMap *FileBase::createMap(off_t pOffset, size_t pLength, 2264f94c520f8d699a5973956a1716272146be17128Zonr Chang bool pIsReadOnly) { 2274f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD < 0 || hasError()) { 2284f94c520f8d699a5973956a1716272146be17128Zonr Chang return NULL; 2294f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2304f94c520f8d699a5973956a1716272146be17128Zonr Chang 2314f94c520f8d699a5973956a1716272146be17128Zonr Chang android::FileMap *map = new (std::nothrow) android::FileMap(); 2324f94c520f8d699a5973956a1716272146be17128Zonr Chang if (map == NULL) { 2334f94c520f8d699a5973956a1716272146be17128Zonr Chang mError.assign(llvm::errc::not_enough_memory, llvm::system_category()); 2344f94c520f8d699a5973956a1716272146be17128Zonr Chang return NULL; 2354f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2364f94c520f8d699a5973956a1716272146be17128Zonr Chang 2374f94c520f8d699a5973956a1716272146be17128Zonr Chang if (!map->create(NULL, mFD, pOffset, pLength, pIsReadOnly)) { 2384f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2394f94c520f8d699a5973956a1716272146be17128Zonr Chang map->release(); 2404f94c520f8d699a5973956a1716272146be17128Zonr Chang return NULL; 2414f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2424f94c520f8d699a5973956a1716272146be17128Zonr Chang 2434f94c520f8d699a5973956a1716272146be17128Zonr Chang return map; 2444f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2454f94c520f8d699a5973956a1716272146be17128Zonr Chang 2464f94c520f8d699a5973956a1716272146be17128Zonr Changsize_t FileBase::getSize() { 2474f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD < 0 || hasError()) { 2484f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<size_t>(-1); 2494f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2504f94c520f8d699a5973956a1716272146be17128Zonr Chang 2514f94c520f8d699a5973956a1716272146be17128Zonr Chang struct stat file_stat; 2524f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2534f94c520f8d699a5973956a1716272146be17128Zonr Chang if (::fstat(mFD, &file_stat) == 0) { 2544f94c520f8d699a5973956a1716272146be17128Zonr Chang break; 2554f94c520f8d699a5973956a1716272146be17128Zonr Chang } else if (errno != EINTR) { 2564f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2574f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<size_t>(-1); 2584f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2594f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (true); 2604f94c520f8d699a5973956a1716272146be17128Zonr Chang 2614f94c520f8d699a5973956a1716272146be17128Zonr Chang return file_stat.st_size; 2624f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2634f94c520f8d699a5973956a1716272146be17128Zonr Chang 2644f94c520f8d699a5973956a1716272146be17128Zonr Changoff_t FileBase::seek(off_t pOffset) { 2654f94c520f8d699a5973956a1716272146be17128Zonr Chang if ((mFD < 0) || hasError()) { 2664f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2674f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2684f94c520f8d699a5973956a1716272146be17128Zonr Chang 2694f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2704f94c520f8d699a5973956a1716272146be17128Zonr Chang off_t result = ::lseek(mFD, pOffset, SEEK_SET); 2714f94c520f8d699a5973956a1716272146be17128Zonr Chang if (result == pOffset) { 2724f94c520f8d699a5973956a1716272146be17128Zonr Chang return result; 2734f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2744f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (errno == EINTR); 2754f94c520f8d699a5973956a1716272146be17128Zonr Chang 2764f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2774f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2784f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2794f94c520f8d699a5973956a1716272146be17128Zonr Chang 2804f94c520f8d699a5973956a1716272146be17128Zonr Changoff_t FileBase::tell() { 2814f94c520f8d699a5973956a1716272146be17128Zonr Chang if ((mFD < 0) || hasError()) { 2824f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2834f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2844f94c520f8d699a5973956a1716272146be17128Zonr Chang 2854f94c520f8d699a5973956a1716272146be17128Zonr Chang do { 2864f94c520f8d699a5973956a1716272146be17128Zonr Chang off_t result = ::lseek(mFD, 0, SEEK_CUR); 2874f94c520f8d699a5973956a1716272146be17128Zonr Chang if (result != static_cast<off_t>(-1)) { 2884f94c520f8d699a5973956a1716272146be17128Zonr Chang return result; 2894f94c520f8d699a5973956a1716272146be17128Zonr Chang } 2904f94c520f8d699a5973956a1716272146be17128Zonr Chang } while (errno == EINTR); 2914f94c520f8d699a5973956a1716272146be17128Zonr Chang 2924f94c520f8d699a5973956a1716272146be17128Zonr Chang detectError(); 2934f94c520f8d699a5973956a1716272146be17128Zonr Chang return static_cast<off_t>(-1); 2944f94c520f8d699a5973956a1716272146be17128Zonr Chang} 2954f94c520f8d699a5973956a1716272146be17128Zonr Chang 2964f94c520f8d699a5973956a1716272146be17128Zonr Changvoid FileBase::close() { 2974f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mShouldUnlock) { 2984f94c520f8d699a5973956a1716272146be17128Zonr Chang unlock(); 2994f94c520f8d699a5973956a1716272146be17128Zonr Chang mShouldUnlock = false; 3004f94c520f8d699a5973956a1716272146be17128Zonr Chang } 3014f94c520f8d699a5973956a1716272146be17128Zonr Chang if (mFD > 0) { 3024f94c520f8d699a5973956a1716272146be17128Zonr Chang ::close(mFD); 3034f94c520f8d699a5973956a1716272146be17128Zonr Chang mFD = -1; 3044f94c520f8d699a5973956a1716272146be17128Zonr Chang } 305331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines if (mShouldDelete) { 306331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines int res = ::remove(mName.c_str()); 307331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines if (res != 0) { 308331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines ALOGE("Failed to remove file: %s - %s", mName.c_str(), ::strerror(res)); 309331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines } 310331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines } 3114f94c520f8d699a5973956a1716272146be17128Zonr Chang return; 3124f94c520f8d699a5973956a1716272146be17128Zonr Chang} 313