1affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===- FileHandle.cpp -----------------------------------------------------===// 2affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 3affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// The MCLinker Project 4affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 5affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// This file is distributed under the University of Illinois Open Source 6affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// License. See LICENSE.TXT for details. 7affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 8affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 96f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include "mcld/Config/Config.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileHandle.h" 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileSystem.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <errno.h> 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#if defined(HAVE_UNISTD_H) 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <unistd.h> 1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#endif 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#if defined(HAVE_FCNTL_H) 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <fcntl.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#endif 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <sys/stat.h> 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 27affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// FileHandle 28f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 29affc150dc44fab1911775a49636d0ce85333b634Zonr ChangFileHandle::FileHandle() 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_Path(), 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Handler(-1), 3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Size(0), 3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_State(GoodBit), 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_OpenMode(NotOpen) { 35affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 36affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 3737b74a387bb3993387029859c2d9d051c41c724eStephen HinesFileHandle::~FileHandle() { 38affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (isOpened()) 39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang close(); 40affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 4237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline static int oflag(FileHandle::OpenMode pMode) { 43affc150dc44fab1911775a49636d0ce85333b634Zonr Chang int result = 0x0; 44affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (FileHandle::Unknown == pMode) 45affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return result; 46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 47affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (FileHandle::ReadWrite == (pMode & FileHandle::ReadWrite)) 48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang result |= O_RDWR; 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (FileHandle::ReadOnly == (pMode & FileHandle::ReadOnly)) 50affc150dc44fab1911775a49636d0ce85333b634Zonr Chang result |= O_RDONLY; 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (FileHandle::WriteOnly == (pMode & FileHandle::WriteOnly)) 52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang result |= O_WRONLY; 53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (FileHandle::Append == (pMode & FileHandle::Append)) 55affc150dc44fab1911775a49636d0ce85333b634Zonr Chang result |= O_APPEND; 56affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (FileHandle::Create == (pMode & FileHandle::Create)) 58affc150dc44fab1911775a49636d0ce85333b634Zonr Chang result |= O_CREAT; 59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (FileHandle::Truncate == (pMode & FileHandle::Truncate)) 61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang result |= O_TRUNC; 62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return result; 64affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 6637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline static bool get_size(int pHandler, unsigned int& pSize) { 67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang struct ::stat file_stat; 68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (-1 == ::fstat(pHandler, &file_stat)) { 69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSize = 0; 70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pSize = file_stat.st_size; 73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 76affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool FileHandle::open(const sys::fs::Path& pPath, 77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang FileHandle::OpenMode pMode, 7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileHandle::Permission pPerm) { 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (isOpened() || Unknown == pMode) { 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(BadBit); 81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_OpenMode = pMode; 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (System == pPerm) 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Handler = sys::fs::detail::open(pPath, oflag(pMode)); 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Handler = sys::fs::detail::open(pPath, oflag(pMode), 8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines static_cast<int>(pPerm)); 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Path = pPath; 9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_Handler == -1) { 9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_OpenMode = OpenMode(NotOpen); 94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(FailBit); 95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 97affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!get_size(m_Handler, m_Size)) { 99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(FailBit); 100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 10637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::delegate(int pFD, FileHandle::OpenModeEnum pMode) { 107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (isOpened()) { 108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(BadBit); 109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Handler = pFD; 11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_OpenMode = OpenMode(pMode); 1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_State = (GoodBit | DeputedBit); 115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!get_size(m_Handler, m_Size)) { 117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(FailBit); 118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 12437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::close() { 125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!isOpened()) { 126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(BadBit); 127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 129affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (isOwned()) { 13137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (::close(m_Handler) == -1) { 1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines setState(FailBit); 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 135affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Path.native().clear(); 138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Size = 0; 13937b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_OpenMode = OpenMode(NotOpen); 140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang cleanState(); 141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 14437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::truncate(size_t pSize) { 145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!isOpened() || !isWritable()) { 146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(BadBit); 147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (sys::fs::detail::ftruncate(m_Handler, pSize) == -1) { 151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(FailBit); 152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Size = pSize; 156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 15937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::read(void* pMemBuffer, size_t pStartOffset, size_t pLength) { 160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!isOpened() || !isReadable()) { 161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(BadBit); 162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 163affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 16537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pLength == 0) 166affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 167affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 16837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ssize_t read_bytes = 16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines sys::fs::detail::pread(m_Handler, pMemBuffer, pLength, pStartOffset); 170affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 17137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (read_bytes == -1) { 172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(FailBit); 173affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 174affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 175affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 176affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 177affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 178affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 17937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::write(const void* pMemBuffer, 18037b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t pStartOffset, 18137b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t pLength) { 182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!isOpened() || !isWritable()) { 183affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(BadBit); 184affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 185affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 18737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pLength == 0) 188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 19037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ssize_t write_bytes = 19137b74a387bb3993387029859c2d9d051c41c724eStephen Hines sys::fs::detail::pwrite(m_Handler, pMemBuffer, pLength, pStartOffset); 192affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 19337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (write_bytes == -1) { 194affc150dc44fab1911775a49636d0ce85333b634Zonr Chang setState(FailBit); 195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 20137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid FileHandle::setState(FileHandle::IOState pState) { 202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_State |= pState; 203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 204affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 20537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid FileHandle::cleanState(FileHandle::IOState pState) { 206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_State = pState; 207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 20937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::isOpened() const { 21037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_Handler != -1 && m_OpenMode != NotOpen && isGood()) 211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 213affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Assume Unknown OpenMode is readable 21737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::isReadable() const { 218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (m_OpenMode & ReadOnly); 219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Assume Unknown OpenMode is writable 22237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::isWritable() const { 223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (m_OpenMode & WriteOnly); 224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Assume Unknown OpenMode is both readable and writable 22737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::isReadWrite() const { 228affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (FileHandle::ReadWrite == (m_OpenMode & FileHandle::ReadWrite)); 229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 230affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 23137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::isGood() const { 232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return !(m_State & (BadBit | FailBit)); 233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 23537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::isBad() const { 236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (m_State & BadBit); 237affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 23937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::isFailed() const { 240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (m_State & (BadBit | FailBit)); 241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 24337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool FileHandle::isOwned() const { 2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return !(m_State & DeputedBit); 2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 24737b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 248