pipe into a curses program












1














The library ncurses provides an interactive user interface. However, I was wondering what would happen if you pipe something into the program. So i tried like this:



# echo foo | my_curses_prog


It seems there is always input pending on stdin but getch cannot read anything. So what's happening under the hood?





Updated test program:



#include <ncurses.h>

int main()
{
WINDOW *win = initscr();
nodelay(win, 0);
refresh();
FILE *fp = fopen("my_curses_prog.log", "w");
while (1) {
int ch = getch();
fprintf(fp, "%dn", ch);
fflush(fp);
}
fclose(fp);
endwin();
return 0;
}









share|improve this question





























    1














    The library ncurses provides an interactive user interface. However, I was wondering what would happen if you pipe something into the program. So i tried like this:



    # echo foo | my_curses_prog


    It seems there is always input pending on stdin but getch cannot read anything. So what's happening under the hood?





    Updated test program:



    #include <ncurses.h>

    int main()
    {
    WINDOW *win = initscr();
    nodelay(win, 0);
    refresh();
    FILE *fp = fopen("my_curses_prog.log", "w");
    while (1) {
    int ch = getch();
    fprintf(fp, "%dn", ch);
    fflush(fp);
    }
    fclose(fp);
    endwin();
    return 0;
    }









    share|improve this question



























      1












      1








      1







      The library ncurses provides an interactive user interface. However, I was wondering what would happen if you pipe something into the program. So i tried like this:



      # echo foo | my_curses_prog


      It seems there is always input pending on stdin but getch cannot read anything. So what's happening under the hood?





      Updated test program:



      #include <ncurses.h>

      int main()
      {
      WINDOW *win = initscr();
      nodelay(win, 0);
      refresh();
      FILE *fp = fopen("my_curses_prog.log", "w");
      while (1) {
      int ch = getch();
      fprintf(fp, "%dn", ch);
      fflush(fp);
      }
      fclose(fp);
      endwin();
      return 0;
      }









      share|improve this question















      The library ncurses provides an interactive user interface. However, I was wondering what would happen if you pipe something into the program. So i tried like this:



      # echo foo | my_curses_prog


      It seems there is always input pending on stdin but getch cannot read anything. So what's happening under the hood?





      Updated test program:



      #include <ncurses.h>

      int main()
      {
      WINDOW *win = initscr();
      nodelay(win, 0);
      refresh();
      FILE *fp = fopen("my_curses_prog.log", "w");
      while (1) {
      int ch = getch();
      fprintf(fp, "%dn", ch);
      fflush(fp);
      }
      fclose(fp);
      endwin();
      return 0;
      }






      terminal pipe ncurses






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 17 at 12:16

























      asked Dec 17 at 9:59









      Cyker

      1,36121429




      1,36121429






















          1 Answer
          1






          active

          oldest

          votes


















          1














          curses applications can be initialized using initscr or newterm. The former reads stdin only; the latter can be told to use a different input. If you want to have a curses application reading from a pipe, you would use newterm (dialog does this).



          curses expects its input to be a terminal. A pipe is never going to act like a terminal, since it is buffered, cannot be changed to raw mode using the standard terminal I/O calls. Since its input is buffered, you don't see much useful happening with getch until it is able to read the whole buffer (lots of characters, or until a newline, depending on how you're testing).






          share|improve this answer





















          • OK my bad. I'm only using stdin so I think initscr should work. Yeah, it actually gets those input characters when fd0 is a pipe. But the problem with a pipe is that when getch hits EOF, it keeps returning -1 instead of blocking (even if nodelay is false). So there is no input pending but EOF keeps giving getch ERR. I think this is probably due to some internal select call in ncurses which reports a fd as ready on EOF. Well, I thought I could test my curses application by piping in keystrokes, now there's a caveat.
            – Cyker
            Dec 17 at 12:15











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "106"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f489435%2fpipe-into-a-curses-program%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          curses applications can be initialized using initscr or newterm. The former reads stdin only; the latter can be told to use a different input. If you want to have a curses application reading from a pipe, you would use newterm (dialog does this).



          curses expects its input to be a terminal. A pipe is never going to act like a terminal, since it is buffered, cannot be changed to raw mode using the standard terminal I/O calls. Since its input is buffered, you don't see much useful happening with getch until it is able to read the whole buffer (lots of characters, or until a newline, depending on how you're testing).






          share|improve this answer





















          • OK my bad. I'm only using stdin so I think initscr should work. Yeah, it actually gets those input characters when fd0 is a pipe. But the problem with a pipe is that when getch hits EOF, it keeps returning -1 instead of blocking (even if nodelay is false). So there is no input pending but EOF keeps giving getch ERR. I think this is probably due to some internal select call in ncurses which reports a fd as ready on EOF. Well, I thought I could test my curses application by piping in keystrokes, now there's a caveat.
            – Cyker
            Dec 17 at 12:15
















          1














          curses applications can be initialized using initscr or newterm. The former reads stdin only; the latter can be told to use a different input. If you want to have a curses application reading from a pipe, you would use newterm (dialog does this).



          curses expects its input to be a terminal. A pipe is never going to act like a terminal, since it is buffered, cannot be changed to raw mode using the standard terminal I/O calls. Since its input is buffered, you don't see much useful happening with getch until it is able to read the whole buffer (lots of characters, or until a newline, depending on how you're testing).






          share|improve this answer





















          • OK my bad. I'm only using stdin so I think initscr should work. Yeah, it actually gets those input characters when fd0 is a pipe. But the problem with a pipe is that when getch hits EOF, it keeps returning -1 instead of blocking (even if nodelay is false). So there is no input pending but EOF keeps giving getch ERR. I think this is probably due to some internal select call in ncurses which reports a fd as ready on EOF. Well, I thought I could test my curses application by piping in keystrokes, now there's a caveat.
            – Cyker
            Dec 17 at 12:15














          1












          1








          1






          curses applications can be initialized using initscr or newterm. The former reads stdin only; the latter can be told to use a different input. If you want to have a curses application reading from a pipe, you would use newterm (dialog does this).



          curses expects its input to be a terminal. A pipe is never going to act like a terminal, since it is buffered, cannot be changed to raw mode using the standard terminal I/O calls. Since its input is buffered, you don't see much useful happening with getch until it is able to read the whole buffer (lots of characters, or until a newline, depending on how you're testing).






          share|improve this answer












          curses applications can be initialized using initscr or newterm. The former reads stdin only; the latter can be told to use a different input. If you want to have a curses application reading from a pipe, you would use newterm (dialog does this).



          curses expects its input to be a terminal. A pipe is never going to act like a terminal, since it is buffered, cannot be changed to raw mode using the standard terminal I/O calls. Since its input is buffered, you don't see much useful happening with getch until it is able to read the whole buffer (lots of characters, or until a newline, depending on how you're testing).







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 17 at 10:22









          Thomas Dickey

          52k594164




          52k594164












          • OK my bad. I'm only using stdin so I think initscr should work. Yeah, it actually gets those input characters when fd0 is a pipe. But the problem with a pipe is that when getch hits EOF, it keeps returning -1 instead of blocking (even if nodelay is false). So there is no input pending but EOF keeps giving getch ERR. I think this is probably due to some internal select call in ncurses which reports a fd as ready on EOF. Well, I thought I could test my curses application by piping in keystrokes, now there's a caveat.
            – Cyker
            Dec 17 at 12:15


















          • OK my bad. I'm only using stdin so I think initscr should work. Yeah, it actually gets those input characters when fd0 is a pipe. But the problem with a pipe is that when getch hits EOF, it keeps returning -1 instead of blocking (even if nodelay is false). So there is no input pending but EOF keeps giving getch ERR. I think this is probably due to some internal select call in ncurses which reports a fd as ready on EOF. Well, I thought I could test my curses application by piping in keystrokes, now there's a caveat.
            – Cyker
            Dec 17 at 12:15
















          OK my bad. I'm only using stdin so I think initscr should work. Yeah, it actually gets those input characters when fd0 is a pipe. But the problem with a pipe is that when getch hits EOF, it keeps returning -1 instead of blocking (even if nodelay is false). So there is no input pending but EOF keeps giving getch ERR. I think this is probably due to some internal select call in ncurses which reports a fd as ready on EOF. Well, I thought I could test my curses application by piping in keystrokes, now there's a caveat.
          – Cyker
          Dec 17 at 12:15




          OK my bad. I'm only using stdin so I think initscr should work. Yeah, it actually gets those input characters when fd0 is a pipe. But the problem with a pipe is that when getch hits EOF, it keeps returning -1 instead of blocking (even if nodelay is false). So there is no input pending but EOF keeps giving getch ERR. I think this is probably due to some internal select call in ncurses which reports a fd as ready on EOF. Well, I thought I could test my curses application by piping in keystrokes, now there's a caveat.
          – Cyker
          Dec 17 at 12:15


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Unix & Linux Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f489435%2fpipe-into-a-curses-program%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Morgemoulin

          Scott Moir

          Souastre