Why is the output of this program not getting underlined
int main() {
tgetent(NULL, getenv("TERM"));
tputs(tgetstr("us", NULL), 1, &putchar);
write(1, "Hello world!\n", 13);
tputs(tgetstr("ue", NULL), 1, &putchar);
}
but this is?
int main() {
tgetent(NULL, getenv("TERM"));
tputs(tgetstr("us", NULL), 1, &putchar);
puts("Hello world!");
tputs(tgetstr("ue", NULL), 1, &putchar);
}
EDIT
The issue is, indeed, about buffer management! If I add fflush
, the string is properly underlined
int main() {
tgetent(NULL, getenv("TERM"));
tputs(tgetstr("us", NULL), 1, &putchar);
fflush(stdout);
write(1, "Hello world!\n", 13);
tputs(tgetstr("ue", NULL), 1, &putchar);
}
The reason for the difference is that
putchar
andputs
are buffered, whilewrite
is not. In this examplethe characters written by
are likely to get to the screen first, because (unlike the
tputs
calls) they are written immediately. The characters written by thetputs
calls are stored in a buffer (which generally is much larger than the strings returned fromtgetstr
), and since you provided no other way to flush the buffer, those are written by the runtime's cleanup as it exits.Without an explicit return statement, the C standard guarantees that it has the same effect as calling
exit
(which does anfflush
on each open file—including streams such as stdout).While you could in principle construct a termcap which had extremely long strings, termcap descriptions are supposed to be limited to 1023 bytes (and even terminfo descriptions are generally limited to 4096 bytes), while the standard I/O buffer size is generally several times that limit, so you wouldn't see those
tputs
calls written out without a lot of work (i.e., changing the runtime...).