在ncurses窗口中使用Shell?

6
我目前正在尝试使用ncurses编写一个最小化的终端复用器。然而,当我尝试使用execv来运行shell时,它不会在窗口中打印输出,并且启动了一个新的子进程来控制窗口(即忽略了ncurses)。
如何防止这种情况发生并让ncurses控制它?有没有一种方法可以获取tty并对其进行控制?
编辑
感谢评论中的Ross Ridge,我现在知道我需要创建一个伪终端,然后将其读入到ncurses窗口中。但是,我无法弄清楚如何在ncurses窗口中打印stdout。是否有一个ncurses函数可以读取文件描述符?还是我必须使用read()printw()来实现?

5
您需要使用一个伪终端。这并不会像您希望的那么容易。 - Ross Ridge
看看GNU mc(午夜指挥官)的功能。它实现了类似于你想要的东西。 - fuz
1个回答

9
您需要大致执行以下操作:
  • 创建一个pty(伪终端)。您没有提到使用的操作系统,但如果它基于POSIX,则可以使用man pty进行帮助。还可以查看openpty
  • 必须将pty的从端连接到运行的任何内容(例如shell),而主端则需要连接到您的终端仿真器。
  • 因此,您需要进行fork(),并在子进程中将slave fd复制到stdinstdoutstderr
  • 然后,您需要将父进程中的主fd连接到ncurses环境(用于输出)和键盘处理(用于输入)。

这个答案, 这个答案这个答案可能会有用,但我特别推荐第一个,因为它涉及到 Stephens 的UNIX环境高级编程(我链接的是更现代的版本),并且源代码可下载。买这本书,因为它是一份宝贵的资源,但如果你在那里查看pty目录(出于版权原因,我不会复制和粘贴),你会发现一个很好的forkpty示例。

这就留下了一个问题,如何从正在运行的进程的输出数据到ncurses。你需要编写终端仿真器。选择要仿真的终端,了解其使用的所有控制序列,并实现所有这些序列。
如果听起来很困难(确实很困难),我建议你考虑使用tmuxscreen;后者可以完全满足你的需求,包括完整的VT100 / ANSI终端仿真器;前者几乎一样完整。tmux是一个BSD许可的程序,这意味着在极少数情况下,你可以简单地调整源代码以满足你的需求。 screen是GPL,因此除非你的程序也是GPL,否则仅供参考。

Stephen的UNIX书绝对是必备之物。在它和BSD的手册之间,你可以找到编写UNIX程序所需的一切。 - D'Nabre
3
libvterm 是一个很好的选择,这也是 Neovim 用于其终端窗口的工具。 - s4y

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接