Skip to content

Commit a59ee18

Browse files
committed
fix read/write big files on linux
1 parent ded1582 commit a59ee18

File tree

1 file changed

+44
-22
lines changed

1 file changed

+44
-22
lines changed

sources/libcore/filesystem/realFiles.cpp

+44-22
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22
#include <vector> // wide characters
33
#include "../incWin.h"
44
#include <io.h> // _get_osfhandle
5-
#define fseek _fseeki64
6-
#define ftell _ftelli64
5+
#define fseek64 _fseeki64
6+
#define ftell64 _ftelli64
7+
#define fseek invalidFunctionFseek
8+
#define ftell invalidFunctionFtell
79
#else
810
#define _FILE_OFFSET_BITS 64
911
#include <dirent.h>
1012
#include <sys/stat.h>
1113
#include <unistd.h>
14+
#define fseek64 fseeko64
15+
#define ftell64 ftello64
1216
#endif
1317
#ifdef CAGE_SYSTEM_MAC
1418
#include <mach-o/dyld.h>
@@ -179,53 +183,71 @@ namespace cage
179183
{
180184
CAGE_ASSERT(f);
181185
#ifdef CAGE_SYSTEM_WINDOWS
182-
HANDLE handle = (HANDLE)_get_osfhandle(_fileno(f));
186+
const HANDLE handle = (HANDLE)_get_osfhandle(_fileno(f));
183187
uint64 off = 0;
184188
uint64 s = buffer.size();
185189
while (s > 0)
186190
{
187191
OVERLAPPED o;
188192
detail::memset(&o, 0, sizeof(o));
189-
uint64 p = at + off;
193+
const uint64 p = at + off;
190194
o.Offset = (DWORD)p;
191195
o.OffsetHigh = (DWORD)((uint64)p >> 32);
192-
uint64 k = min(s, (uint64)1024 * 1024 * 1024); // write in chunks of 1 GB
196+
const uint64 k = min(s, (uint64)1024 * 1024 * 1024); // read in chunks of 1 GB
193197
DWORD r = 0;
194198
if (!ReadFile(handle, buffer.data() + off, numeric_cast<DWORD>(k), &r, &o) || r != k)
195199
CAGE_THROW_ERROR(SystemError, "ReadFile", GetLastError());
196200
off += k;
197201
s -= k;
198202
}
199203
#else
200-
if (pread(fileno(f), buffer.data(), buffer.size(), at) != buffer.size())
201-
CAGE_THROW_ERROR(SystemError, "pread", errno);
204+
const int handle = fileno(f);
205+
uint64 off = 0;
206+
uint64 s = buffer.size();
207+
while (s > 0)
208+
{
209+
const uint64 k = min(s, (uint64)1024 * 1024 * 1024); // read in chunks of 1 GB
210+
if (pread(handle, buffer.data() + off, k, at) != k)
211+
CAGE_THROW_ERROR(SystemError, "pread", errno);
212+
off += k;
213+
s -= k;
214+
}
202215
#endif
203216
}
204217

205218
void writeAtImpl(PointerRange<const char> buffer, const uint64 at, FILE *f)
206219
{
207220
CAGE_ASSERT(f);
208221
#ifdef CAGE_SYSTEM_WINDOWS
209-
HANDLE handle = (HANDLE)_get_osfhandle(_fileno(f));
222+
const HANDLE handle = (HANDLE)_get_osfhandle(_fileno(f));
210223
uint64 off = 0;
211224
uint64 s = buffer.size();
212225
while (s > 0)
213226
{
214227
OVERLAPPED o;
215228
detail::memset(&o, 0, sizeof(o));
216-
uint64 p = at + off;
229+
const uint64 p = at + off;
217230
o.Offset = (DWORD)p;
218231
o.OffsetHigh = (DWORD)((uint64)p >> 32);
219-
uint64 k = min(s, (uint64)1024 * 1024 * 1024); // write in chunks of 1 GB
232+
const uint64 k = min(s, (uint64)1024 * 1024 * 1024); // write in chunks of 1 GB
220233
DWORD r = 0;
221234
if (!WriteFile(handle, buffer.data() + off, numeric_cast<DWORD>(k), &r, &o) || r != k)
222235
CAGE_THROW_ERROR(SystemError, "WriteFile", GetLastError());
223236
off += k;
224237
s -= k;
225238
}
226239
#else
227-
if (pwrite(fileno(f), buffer.data(), buffer.size(), at) != buffer.size())
228-
CAGE_THROW_ERROR(SystemError, "pwrite", errno);
240+
const int handle = fileno(f);
241+
uint64 off = 0;
242+
uint64 s = buffer.size();
243+
while (s > 0)
244+
{
245+
const uint64 k = min(s, (uint64)1024 * 1024 * 1024); // write in chunks of 1 GB
246+
if (pwrite(handle, buffer.data() + off, k, at) != k)
247+
CAGE_THROW_ERROR(SystemError, "pwrite", errno);
248+
off += k;
249+
s -= k;
250+
}
229251
#endif
230252
}
231253

@@ -300,7 +322,7 @@ namespace cage
300322
{
301323
CAGE_ASSERT(f);
302324
CAGE_ASSERT(position <= size());
303-
if (fseek(f, position, 0) != 0)
325+
if (fseek64(f, position, 0) != 0)
304326
CAGE_THROW_ERROR(SystemError, "fseek", errno);
305327
}
306328

@@ -316,16 +338,16 @@ namespace cage
316338
uint64 tell() override
317339
{
318340
CAGE_ASSERT(f);
319-
return ftell(f);
341+
return ftell64(f);
320342
}
321343

322344
uint64 size() override
323345
{
324346
CAGE_ASSERT(f);
325-
uint64 pos = ftell(f);
326-
fseek(f, 0, 2);
327-
uint64 siz = ftell(f);
328-
fseek(f, pos, 0);
347+
const uint64 pos = ftell64(f);
348+
fseek64(f, 0, 2);
349+
const uint64 siz = ftell64(f);
350+
fseek64(f, pos, 0);
329351
return siz;
330352
}
331353

@@ -381,8 +403,8 @@ namespace cage
381403
CAGE_ASSERT(f);
382404
CAGE_ASSERT(myMode.read);
383405
ff = f;
384-
at = ftell(f);
385-
if (fseek(f, at + buffer.size(), 0) != 0)
406+
at = ftell64(f);
407+
if (fseek64(f, at + buffer.size(), 0) != 0)
386408
CAGE_THROW_ERROR(SystemError, "fseek", errno);
387409
}
388410
readAtImpl(buffer, at, ff);
@@ -399,8 +421,8 @@ namespace cage
399421
CAGE_ASSERT(f);
400422
CAGE_ASSERT(myMode.write);
401423
ff = f;
402-
at = ftell(f);
403-
if (fseek(f, at + buffer.size(), 0) != 0)
424+
at = ftell64(f);
425+
if (fseek64(f, at + buffer.size(), 0) != 0)
404426
CAGE_THROW_ERROR(SystemError, "fseek", errno);
405427
}
406428
writeAtImpl(buffer, at, ff);

0 commit comments

Comments
 (0)