xref: /aosp_15_r20/external/pdfium/core/fxcrt/cfx_fileaccess_posix.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2014 The PDFium Authors
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 <fcntl.h>
10 #include <sys/stat.h>
11 #include <unistd.h>
12 
13 #include <memory>
14 
15 #include "core/fxcrt/fx_stream.h"
16 #include "third_party/base/numerics/safe_conversions.h"
17 
18 #ifndef O_BINARY
19 #define O_BINARY 0
20 #endif  // O_BINARY
21 
22 #ifndef O_LARGEFILE
23 #define O_LARGEFILE 0
24 #endif  // O_LARGEFILE
25 
26 // static
Create()27 std::unique_ptr<FileAccessIface> FileAccessIface::Create() {
28   return std::make_unique<CFX_FileAccess_Posix>();
29 }
30 
CFX_FileAccess_Posix()31 CFX_FileAccess_Posix::CFX_FileAccess_Posix() : m_nFD(-1) {}
32 
~CFX_FileAccess_Posix()33 CFX_FileAccess_Posix::~CFX_FileAccess_Posix() {
34   Close();
35 }
36 
Open(ByteStringView fileName)37 bool CFX_FileAccess_Posix::Open(ByteStringView fileName) {
38   if (m_nFD > -1)
39     return false;
40 
41   // TODO(tsepez): check usage of c_str() below.
42   m_nFD =
43       open(fileName.unterminated_c_str(), O_BINARY | O_LARGEFILE | O_RDONLY);
44   return m_nFD > -1;
45 }
46 
Close()47 void CFX_FileAccess_Posix::Close() {
48   if (m_nFD < 0) {
49     return;
50   }
51   close(m_nFD);
52   m_nFD = -1;
53 }
GetSize() const54 FX_FILESIZE CFX_FileAccess_Posix::GetSize() const {
55   if (m_nFD < 0) {
56     return 0;
57   }
58   struct stat s;
59   memset(&s, 0, sizeof(s));
60   fstat(m_nFD, &s);
61   return pdfium::base::checked_cast<FX_FILESIZE>(s.st_size);
62 }
GetPosition() const63 FX_FILESIZE CFX_FileAccess_Posix::GetPosition() const {
64   if (m_nFD < 0) {
65     return (FX_FILESIZE)-1;
66   }
67   return lseek(m_nFD, 0, SEEK_CUR);
68 }
SetPosition(FX_FILESIZE pos)69 FX_FILESIZE CFX_FileAccess_Posix::SetPosition(FX_FILESIZE pos) {
70   if (m_nFD < 0) {
71     return (FX_FILESIZE)-1;
72   }
73   return lseek(m_nFD, pos, SEEK_SET);
74 }
Read(void * pBuffer,size_t szBuffer)75 size_t CFX_FileAccess_Posix::Read(void* pBuffer, size_t szBuffer) {
76   if (m_nFD < 0) {
77     return 0;
78   }
79   return read(m_nFD, pBuffer, szBuffer);
80 }
Write(const void * pBuffer,size_t szBuffer)81 size_t CFX_FileAccess_Posix::Write(const void* pBuffer, size_t szBuffer) {
82   if (m_nFD < 0) {
83     return 0;
84   }
85   return write(m_nFD, pBuffer, szBuffer);
86 }
ReadPos(void * pBuffer,size_t szBuffer,FX_FILESIZE pos)87 size_t CFX_FileAccess_Posix::ReadPos(void* pBuffer,
88                                      size_t szBuffer,
89                                      FX_FILESIZE pos) {
90   if (m_nFD < 0) {
91     return 0;
92   }
93   if (pos >= GetSize()) {
94     return 0;
95   }
96   if (SetPosition(pos) == (FX_FILESIZE)-1) {
97     return 0;
98   }
99   return Read(pBuffer, szBuffer);
100 }
WritePos(const void * pBuffer,size_t szBuffer,FX_FILESIZE pos)101 size_t CFX_FileAccess_Posix::WritePos(const void* pBuffer,
102                                       size_t szBuffer,
103                                       FX_FILESIZE pos) {
104   if (m_nFD < 0) {
105     return 0;
106   }
107   if (SetPosition(pos) == (FX_FILESIZE)-1) {
108     return 0;
109   }
110   return Write(pBuffer, szBuffer);
111 }
112 
Flush()113 bool CFX_FileAccess_Posix::Flush() {
114   if (m_nFD < 0)
115     return false;
116 
117   return fsync(m_nFD) > -1;
118 }
119 
Truncate(FX_FILESIZE szFile)120 bool CFX_FileAccess_Posix::Truncate(FX_FILESIZE szFile) {
121   if (m_nFD < 0)
122     return false;
123 
124   return !ftruncate(m_nFD, szFile);
125 }
126