[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#287824: libc6: fseek() fails and returns -1 without setting errno



At Thu, 30 Dec 2004 12:42:18 +0100,
Johan Walles wrote:
> The output of the following program is:
> johan@foo:~/src/test$ ./a.out
> fseek: Unknown error 12345
> 
> Since I set errno to 12345 before making the (failing) fseek() call,
> fseek() itself apparently fails without setting errno.
>
> Here's the strace output between opening the file and failing:
> open("/proc/self/mem", O_RDONLY)        = 3
> fstat64(3, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
> mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe8000
> _llseek(3, 18446744072635807744, [3526037055030344891], SEEK_SET) = -1073743872
...
> write(4, "fseek: Unknown error 12345\n", 27fseek: Unknown error 12345
> ) = 27
...
> int main(int argc, char *argv[])
> {
>   int variable = 42;
>   int readvalue = 0;
>   FILE *mem = fopen("/proc/self/mem", "r");
>   
>   errno = 12345;
>   if (fseek(mem, (size_t)&variable, SEEK_SET) != 0) {
>     perror("fseek");
>     exit(EXIT_FAILURE);
>   }

In first, your program has some bugs.

1. Use fseeko instead of fseek.
2. You want to use variable instead of &variable.
3. (size_t) is invalid.  When fseeko is used, (off_t) should be used.
4. compile option -D_FILE_OFFSET_BITS=64 helps you for a large file
   like /proc/self/mem.


BTW, this issue is very special case.  If you pass such &variable ==
0xbffff800, offset of _llseek becomes 18446744072635807744 ==
0xffffffffbffff800.  But kernel mem_lseek() in proc.c simply sets
file->f_pos and it does not return any errors when offset is even
(long long)-1 on 32bit architecture.  In this case, file->f_pos always
becomes minus values.  Return value from lseek() and fseek() functions
are negative, but from POSIX or ANSI point of view, those are
interpreted as error condition.

I think mem_lseek() (thus lseek for /proc/self/mem) is special case
because sometimes memory is existed in all 32 or 64 bit space.
It's not compatible with POSIX's lseek/fseek interface.  So I think
even if it shows error, it's not bug of either glibc or kernel.

I send my interpretation to debian-kernel to make sure.  Debian-kernel
guys, if you don't agree with my thought, please let me know.
Otherwise, I'll close this bug.

Regards,
-- gotom



Reply to: