1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "core/fxcrt/cfx_fileaccess_posix.h" 8 9 #include <memory> 10 11 #include "third_party/base/ptr_util.h" 12 13 #ifndef O_BINARY 14 #define O_BINARY 0 15 #endif // O_BINARY 16 17 #ifndef O_LARGEFILE 18 #define O_LARGEFILE 0 19 #endif // O_LARGEFILE 20 21 #if _FX_PLATFORM_ == _FX_PLATFORM_LINUX_ || \ 22 _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ || \ 23 _FX_PLATFORM_ == _FX_PLATFORM_ANDROID_ 24 25 namespace { 26 27 void GetFileMode(uint32_t dwModes, int32_t& nFlags, int32_t& nMasks) { 28 nFlags = O_BINARY | O_LARGEFILE; 29 if (dwModes & FX_FILEMODE_ReadOnly) { 30 nFlags |= O_RDONLY; 31 nMasks = 0; 32 } else { 33 nFlags |= O_RDWR | O_CREAT; 34 if (dwModes & FX_FILEMODE_Truncate) { 35 nFlags |= O_TRUNC; 36 } 37 nMasks = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 38 } 39 } 40 41 } // namespace 42 43 // static 44 std::unique_ptr<IFX_FileAccess> IFX_FileAccess::Create() { 45 return pdfium::MakeUnique<CFX_FileAccess_Posix>(); 46 } 47 48 CFX_FileAccess_Posix::CFX_FileAccess_Posix() : m_nFD(-1) {} 49 50 CFX_FileAccess_Posix::~CFX_FileAccess_Posix() { 51 Close(); 52 } 53 54 bool CFX_FileAccess_Posix::Open(const ByteStringView& fileName, 55 uint32_t dwMode) { 56 if (m_nFD > -1) 57 return false; 58 59 int32_t nFlags; 60 int32_t nMasks; 61 GetFileMode(dwMode, nFlags, nMasks); 62 63 // TODO(tsepez): check usage of c_str() below. 64 m_nFD = open(fileName.unterminated_c_str(), nFlags, nMasks); 65 return m_nFD > -1; 66 } 67 68 bool CFX_FileAccess_Posix::Open(const WideStringView& fileName, 69 uint32_t dwMode) { 70 return Open(FX_UTF8Encode(fileName).AsStringView(), dwMode); 71 } 72 73 void CFX_FileAccess_Posix::Close() { 74 if (m_nFD < 0) { 75 return; 76 } 77 close(m_nFD); 78 m_nFD = -1; 79 } 80 FX_FILESIZE CFX_FileAccess_Posix::GetSize() const { 81 if (m_nFD < 0) { 82 return 0; 83 } 84 struct stat s; 85 memset(&s, 0, sizeof(s)); 86 fstat(m_nFD, &s); 87 return s.st_size; 88 } 89 FX_FILESIZE CFX_FileAccess_Posix::GetPosition() const { 90 if (m_nFD < 0) { 91 return (FX_FILESIZE)-1; 92 } 93 return lseek(m_nFD, 0, SEEK_CUR); 94 } 95 FX_FILESIZE CFX_FileAccess_Posix::SetPosition(FX_FILESIZE pos) { 96 if (m_nFD < 0) { 97 return (FX_FILESIZE)-1; 98 } 99 return lseek(m_nFD, pos, SEEK_SET); 100 } 101 size_t CFX_FileAccess_Posix::Read(void* pBuffer, size_t szBuffer) { 102 if (m_nFD < 0) { 103 return 0; 104 } 105 return read(m_nFD, pBuffer, szBuffer); 106 } 107 size_t CFX_FileAccess_Posix::Write(const void* pBuffer, size_t szBuffer) { 108 if (m_nFD < 0) { 109 return 0; 110 } 111 return write(m_nFD, pBuffer, szBuffer); 112 } 113 size_t CFX_FileAccess_Posix::ReadPos(void* pBuffer, 114 size_t szBuffer, 115 FX_FILESIZE pos) { 116 if (m_nFD < 0) { 117 return 0; 118 } 119 if (pos >= GetSize()) { 120 return 0; 121 } 122 if (SetPosition(pos) == (FX_FILESIZE)-1) { 123 return 0; 124 } 125 return Read(pBuffer, szBuffer); 126 } 127 size_t CFX_FileAccess_Posix::WritePos(const void* pBuffer, 128 size_t szBuffer, 129 FX_FILESIZE pos) { 130 if (m_nFD < 0) { 131 return 0; 132 } 133 if (SetPosition(pos) == (FX_FILESIZE)-1) { 134 return 0; 135 } 136 return Write(pBuffer, szBuffer); 137 } 138 139 bool CFX_FileAccess_Posix::Flush() { 140 if (m_nFD < 0) 141 return false; 142 143 return fsync(m_nFD) > -1; 144 } 145 146 bool CFX_FileAccess_Posix::Truncate(FX_FILESIZE szFile) { 147 if (m_nFD < 0) 148 return false; 149 150 return !ftruncate(m_nFD, szFile); 151 } 152 153 #endif 154