Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

printf()/puts() after use of ncurses

Tags:

c

ncurses

I'm using the ncurses library in a C project, and encountered a problem with the use of printf()/puts() after curses was initialized and de-initialized. Here's a simplified illustration:

initscr();
endwin();

puts("first");
usleep(1e6);
puts("second");

Both first and second will appear on the screen only after the containing executable exits (after a little over one second), instead of printing first first, and then, a second later, second. ncurses seems to be buffering stdout somehow and only flushing it on exit. fflush(stdout) seems to solve the problem:

initscr();
endwin();

puts("First.");
fflush(stdout);
usleep(1e6);
puts("Second");

When stdout is manually flushed, output is displayed as expected (with a second gap). If I were to add more puts() statements afterwards with usleep()s in between, though, I'd need to repeat the calls to fflush(stdout) after each one, and I'm wondering if there's a better solution that, say, permanently resets the program to pre-curses mode.

like image 238
sevko Avatar asked Sep 30 '22 11:09

sevko


1 Answers

ncurses calls setvbuf, putting streams to a full buffered mode. Either specify the environment variable NCURSES_NO_SETBUF to instruct it to not change buffering, or restore the buffer mode by calling setvbuf again, although man 3 setvbuf advises against this:

The setvbuf() function may be used at any time, but may have peculiar side effects (such as discarding input or flushing output) if the stream is ``active''. Portable applications should call it only once on any given stream, and before any I/O is performed.

Here is how to restore stdout to line-buffering and stderr to no buffering again:

#include <stdio.h>
#include <unistd.h>
#include <ncurses.h>

int main() {
  initscr();
  endwin();

  setvbuf(stdout, NULL, _IOLBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);

  puts("First.");
  usleep(1e6);
  puts("Second");
  return 0;
}
like image 67
nmaier Avatar answered Oct 19 '22 04:10

nmaier