Search code examples
cpipencursescurses

how to make ncurses program working with other linux utils?


Suppose I have a ncurses program which does some job on curses screen, and finally print something to stdout. Call this program c.c, compiled to a.out.

I expect cat $(./a.out) first fire up ncurses, after some action, a.out quits and print c.c to stdout, which is read by cat, and thus print content of file c.c.

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

int main() {
    initscr();
    noecho();
    cbreak();
    printw("hello world");
    refresh();
    getch();
    endwin();
    fprintf(stdout, "c.c");
    return 0;
}

I also expect ./a.out | xargs vim, ls | ./a.out | xargs less to work.

But when I type ./a.out | xargs vim, hello world never shows up. The command seems not executed in order, vim does not open c.c.

What is the correct way to make a ncurses program to work with other linux utils?


Solution

  • Pipes use the standard output (stdout) and standard input (stdin).

    The simplest way - rather than using initscr, which initializes the output to use the standard output, use newterm, which allows you to choose the file descriptors, e.g.,

    newterm(NULL, stderr, stdin);
    

    rather than

    initscr();
    

    which is (almost) the same as

    newterm(NULL, stdout, stdin);
    

    By the way, when you include <ncurses.h> (or <curses.h>), there is no need to include <stdio.h>.

    If you wanted to use your program in the middle of a pipe, that is more complicated: you would have to drain the standard input and open the actual terminal device. But that's another question (and has already been answered).

    Further reading: