<html><head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
</head><body bgcolor="#FFFFFF" text="#000000">Rob Landley wrote:
<blockquote cite="mid:542AAE91.80400@landley.net" type="cite">
  <pre wrap="">In theory I can implement my own get_line() on top of FILE * using fgetc,
but this is again looping over single bytes (because with ungetc only one
pushback is guaranteed). A function call is cheaper than
a system call, but still not exactly ideal. Unfortunately, I can't ask stdio
"how many bytes of readahead are in your internal buffer" because it wants to
hide those details. (Under strace, most actual fgetc() loops I actually
watched did the darn one syscall per byte thing anyway.)
</pre>
</blockquote>
Is the file/stdin appropriately buffered? (i.e. is your implementation 
being conservative and making stdin _IONBF for no good reason?)<br>
<br>
More concretely: what libc was this tested with? If uclibc, I'm inclined
 to believe uclibc is a pile of crap. If musl, WTF. <br>
<br>
glibc gets this right, FWIW:<br>
<div style="margin-left: 40px; font-family: monospace;">oshepherd@Shinji:~$
 cat testbuf.c<br>
#include <stdio.h><br>
  <br>
int main()<br>
{<br>
    int c;<br>
    while((c = fgetc(stdin)) != EOF)<br>
        fputc(c, stdout);<br>
    return 1;<br>
}<br>
oshepherd@Shinji:~$ strace ./testbuf < testbuf.c<br>
execve("./testbuf", ["./testbuf"], [/* 21 vars */]) = 0<br>
/* dynamic linker noise excised */<br>
read(0, "#include <stdio.h>\n\nint main()\n{"..., 4096) = 123<br>
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0<br>
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
 = 0x7f93b7e9b000<br>
write(1, "#include <stdio.h>\n", 19#include <stdio.h><br>
)    = 19<br>
write(1, "\n", 1<br>
)                       = 1<br>
write(1, "int main()\n", 11int main()<br>
)            = 11<br>
write(1, "{\n", 2{<br>
)                      = 2<br>
write(1, "    int c;\n", 11    int c;<br>
)            = 11<br>
write(1, "    while((c = fgetc(stdin)) != "..., 37    while((c = 
fgetc(stdin)) != EOF)<br>
) = 37<br>
write(1, "        fputc(c, stdout);\n", 26        fputc(c, stdout);<br>
) = 26<br>
write(1, "    return 1;\n", 14    return 1;<br>
)         = 14<br>
write(1, "}\n", 2}<br>
)                      = 2<br>
read(0, "", 4096)                       = 0<br>
exit_group(1)                           = ?<br>
</div>
<br>
For best performance, make sure that stdin is fully buffered and then<br>
<ol>
  <li>flockfile(stdin), because POSIX says to do so</li>
  <li>Use getc_unlocked, which may be a macro, and should be the fastest
 way to grab a character</li>
</ol>
The cost of all those function calls should be much less than the cost 
of a system call per line, especially if you give stdio a big buffer to 
work with. Whatever you do, give stdio a big buffer <br>
<br>
</body></html>