通过fifo将curses输入发送到C中的另一个终端

我的C程序在终端中运行多个线程,异步打印消息。 我想要一个显示curses输出的线程,但由于它是异步的,它必须在另一个终端中。

我的想法是将curses输出写入fifo并使用cat fifo打开终端。

但是我如何才能恢复输出诅咒并将其输出到文件中?

谢谢。

curses使用终端输入和输出,所以如果你想截取它并使它去除终端之外的某个地方,最简单的方法(尽管非常重要)是使用伪终端。 你可以通过调用posix_openpt来实现,它会为你提供一个伪终端主设备。 然后,您可以调用grantptunlockptptsname来获取终端设备的名称,然后您可以将其fopen并传递给cuterm newterm以初始化终端。

完成后,curses写入终端的所有内容都将从主服务器读取,写入主服务器的所有内容都将输入到curses中。 它就像一个fifo,只是具有curses所期望的所有额外终端function。

curses需要直接访问终端,以便查找转义代码,检测分辨率等。你应该尝试在当前(主)终端中有一个专用于curses输出的线程,并将所有调试消息从其他线程重定向到日志文件/管道/日志记录工具(如果你愿意,可以在curses中显示)

ncurses需要一个终端,因为它初始化了I / O连接。 FIFO不合适,因为它是单向的(例如, 如果重定向输入,请参见执行操作 )可能无法初始化为终端 。 ncurses使用TERM环境变量来查找终端描述(在这个问题上不咨询实际的终端 )。

有一个简单的例子, ncurses-examples中的 ditto ,它使用xterm作为多个输入/输出屏幕。 那使用pty接口,例如,

 #ifdef USE_XTERM_PTY int amaster; int aslave; char slave_name[1024]; char s_option[sizeof(slave_name) + 80]; const char *xterm_prog = 0; if ((xterm_prog = getenv("XTERM_PROG")) == 0) xterm_prog = "xterm"; if (openpty(&amaster, &aslave, slave_name, 0, 0) != 0 || strlen(slave_name) > sizeof(slave_name) - 1) failed("openpty"); if (strrchr(slave_name, '/') == 0) { errno = EISDIR; failed(slave_name); } sprintf(s_option, "-S%s/%d", slave_name, aslave); if (fork()) { execlp(xterm_prog, xterm_prog, s_option, "-title", path, (char *) 0); _exit(0); } fp = fdopen(amaster, "r+"); if (fp == 0) failed(path); #else 

newterm将该文件描述符传递给ncurses:

 static void open_screen(DITTO * target, char **source, int length, int which1) { if (which1 != 0) { target->input = target->output = open_tty(source[which1]); } else { target->input = stdin; target->output = stdout; } target->which1 = which1; target->titles = source; target->length = length; target->fifo.head = -1; target->screen = newterm((char *) 0, /* assume $TERM is the same */ target->output, target->input); if (target->screen == 0) failed("newterm"); (void) USING_SCREEN(target->screen, init_screen, target); } 

如果您阅读ditto的第一个引用部分,您会注意到它使用xterm选项 ,允许应用程序将文件描述符传递给它:

  -Sccn This option allows xterm to be used as an input and output channel for an existing program and is sometimes used in spe- cialized applications. The option value specifies the last few letters of the name of a pseudo-terminal to use in slave mode, plus the number of the inherited file descriptor. If the option contains a "/" character, that delimits the characters used for the pseudo-terminal name from the file descriptor. Otherwise, exactly two characters are used from the option for the pseudo-terminal name, the remainder is the file descriptor. Examples (the first two are equivalent since the descriptor follows the last "/"): -S/dev/pts/123/45 -S123/45 -Sab34 Note that xterm does not close any file descriptor which it did not open for its own use. It is possible (though probably not portable) to have an application which passes an open file descriptor down to xterm past the initialization or the -S option to a process running in the xterm. 

这是一个显示ditto的屏幕截图:

在此处输入图像描述