This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
strange behavior with fread, fseek
- From: Joe Maimon <jmaimon at ttec dot com>
- To: bug-coreutils at gnu dot org
- Cc: glibc-bugs at sources dot redhat dot com
- Date: Thu, 26 Jan 2006 14:11:30 -0500
- Subject: strange behavior with fread, fseek
Strange to me that is.
Why am I asking here? Perhaps I should make a fool of myself to the
kernel or glibc people?
Well I know geniuses hang out here. Plus coreutils must have dealt with
issues like this if it is indeed normal.
$ ls -la fread-fseek.c
-rw-r--r-- 1 joe joe 1155 Jan 26 13:37 fread-fseek.c
$ cat fread-fseek.c | wc -l
56
$ cat fread-fseek.c | while ./fread-fseek 1156; do true ; done | wc -l
1
$ cat fread-fseek.c | while ./fread-fseek 1155; do true ; done | wc -l
1
$ cat fread-fseek.c | while ./fread-fseek 1; do true ; done | wc -l
1
$ while ./fread-fseek 1156; do true ; done < fread-fseek.c | wc -l
56
$ while ./fread-fseek 1155; do true ; done < fread-fseek.c | wc -l
1
$ while ./fread-fseek 1; do true ; done < fread-fseek.c | wc -l
1
where the numeric arg is the number of bytes that fread should read per
call.
Strace shows reads are done in 4096 and _llseek calls look strange.
here is an example
read(0, "#include <stdio.h>\n#include <lib"..., 4096) = 1155
fstat64(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0xb7f2c000
_llseek(0, 1155, [1155], SEEK_SET) = 0
write(1, "#include <stdio.h>\n", 19#include <stdio.h>
and this is the one where things perform as expected
read(0, "#include <stdio.h>\n#include <lib"..., 4096) = 1155
read(0, "", 4096) = 0
fstat64(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0xb7f6e000
_llseek(0, 0, [0], SEEK_SET) = 0
read(0, "#include <stdio.h>\n", 19) = 19
write(1, "#include <stdio.h>\n", 19#include <stdio.h>
) = 19
Linux nameserver3 2.6.12.3686-smp-0.1.0 #1 SMP Wed Aug 3 21:18:13 EDT
2005 i686 GNU/Linux
Debian testing
#include <stdio.h>
#include <libgen.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char ** argv)
{
char *buf;
int len = BUFSIZ;
int bytes_to_read = 32;
int bytes_read = 0;
char *line_end = NULL;
long file_offset = ftell(stdin);
if (argv[1])
bytes_to_read = atoi(argv[1]);
if (argv[1] && argv[2])
len = atoi(argv[2]);
if (!bytes_to_read || !len)
{
fprintf(stderr, "Not reading any bytes, bytes_to_read = %d , len = %d\n"
, bytes_to_read, len);
exit(1);
}
if (bytes_to_read > len)
len = bytes_to_read + 1;
buf = malloc(len);
if (!buf)
{
fprintf(stderr, "No buf\n");
exit(1);
}
*(buf+len) = '\0';
do {
bytes_read += fread(buf+bytes_read, 1, bytes_to_read, stdin);
line_end = memchr(buf, '\n', bytes_read);
} while (!feof(stdin) && !ferror(stdin) && !line_end && bytes_read < len);
if (line_end && bytes_read < len)
*(line_end) = '\0';
else
*(buf+bytes_read) = '\0';
if (bytes_read)
fprintf(stdout, "%s\n", buf);
if (file_offset > -1 && line_end)
fseek(stdin, file_offset + (line_end - buf) + 1, SEEK_SET);
exit(bytes_read == 0 ? 1 : 0);
return (bytes_read == 0 ? 1 : 0);
}