3/18 Has anyone (else) encountered a bug where after using lseek with
a negative offset read stops working on that fd, even though a
valid off_t was returned? In particular, I have a file with two
binary unsigned longs at the end, and when I do an lseek(fd,
-2*sizeof(unsigned long), SEEK_END); the reads then fail. -mel
\_ Use PERL.
\_ Did you try seeking to the beginning to the file, then a forward
seek to where you want to read as a work-around?
\_ The file is full of longs and I had wanted to read the two
longs at the end of it. The workaround I found was:
end_offset = lseek(fd, 0, SEEK_END);
lseek(fd, end_offset-2*sizeof(long), SEEK_SET);
which is ugly but it works. Throw in a few error checks
on the return codes and it should work for you too. -mel
\_ mel you ugly squint, get off the motd
\_ And now, the right answer: You are specifying a seek relative to
SEEK_END... Such a seek is implicitly in the negative direction,
since it's impossible to seek past the end of the file. The minus
sign in front of the 2 is unnecessary. So you should be doing:
lseek(fd, 2*sizeof(unsigned long), SEEK_END);
I tried looking for an example of this in K&R, but in each instance
where SEEK_END is used, they demonstrate with an offset of 0, which
is not too instructive. WHY HAST THOU FORSAKEN ME, K&R? I TOOK
THY WORD AS GOSPEL ONLY TO FIND A HALF-TRUTH LYING IN WAIT TO SNARE
THE UNWARY! -mogul (hey, it's 3:15am, fuck off!)
\_ Not quite. A seek from SEEK_END is not implcitly negative;
just like SEEK_CUR and SEEK_SET, positive offsets go forwards
and negative offsets go backwards (see lseek(2)). The problem
with your code (and it's not really your fault) is that sizeof
returns a size_t, which (on freebsd) is an unsigned int; when
you multiply that by -2, you get another unsigned int (K&R 2.0,
p. 198); and the unsigned int (0xfffffff8) then gets promoted
to a signed long long (0x00000000fffffff8).
This is not what you want. The Right Way to fix it would be
for freebsd to make size_t an unsigned long long, but that
would break a lot of stuff and probably won't happen soon; in
the meantime, you can cast the return value of sizeof to a
signed int and your code will work. --mconst |