I'm currently having a small fight involving seek
with a C program running on a 32-bit (x86) box.
Specifically, I don't seem to be able to seek beyond a seemingly rather arbitrary file offset.
If I do:
unsigned long long pos = 15032385535LLU;
int r = fseek(fd, pos, SEEK_SET);
then I'll get
fstat64(3, {st_mode=S_IFREG|0644, st_size=1000000000000, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77c3000
_llseek(3, 2147479552, [2147479552], SEEK_SET) = 0
read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4095) = 4095
TL;DR it works.
However, if I increment pos
by just 1...
unsigned long long pos = 15032385536LLU;
int r = fseek(fd, pos, SEEK_SET);
...then everything falls apart spectacularly:
fstat64(3, {st_mode=S_IFREG|0644, st_size=1000000000000, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb771e000
_llseek(3, 18446744071562067968, 0xbfd0f5f8, SEEK_SET) = -1 EINVAL (Invalid argument)
I'm completely lost as to why. What am I doing wrong?
The only significant tidbits I can come up with is that 15032385535
is 37FFFFFFF
which seems interesting-ish, along with the fact that the number seems to be related to time wraparound.
The program in question is being compiled with -D_FILE_OFFSET_BITS=64
, which proved helpful with actually getting the large files I'm working on open in the first place, but doesn't seem to be making a useful difference here. I stumbled on -DLARGEFILES -D_LARGEFILE_SOURCE
and tried adding that but that doesn't seem to have had any discernible effect.
For context (because trivia is fun): I created a large sparse file with truncate
to reproduce the issue on a separate 32-bit machine (perfectly) with; and the program in question is a small webserver - I'm trying to copy some data off a spare computer, and I've discovered that it's surprisingly hard to find a compact web server that can handle Range:
requests and simultaneous downloads. nginx is throwing Perl errors I'm not going to investigate (Slackware packaging issues - nope), Python's SimpleHTTPServer is uselessly simple, and thttpd dissolved into a puddle of mmap errors. Fun day...