伪terminal中的Ncurses程序

在我继续尝试了解伪terminal如何工作的时候,我写了一个小程序来尝试运行bash。

问题是,我的断线似乎是closures的。 (只有在按下Enter后,才会显示shell提示符。)

此外,我仍然不能正确使用ncurses程序,如vi。 谁能告诉我如何设置这个伪terminal?

我可以在这里find我写得不好的程序,我鼓励你编译它 。 操作系统是GNU / Linux,谢谢。

编辑:像这样编译:gcc program.c -lutil -o程序

再次编辑:它看起来像奇怪的间距问题是由于使用printf(),但仍然不解决与ncurses程序的问题,虽然。

Solutions Collecting From Web of "伪terminal中的Ncurses程序"

你的程序有几个问题。 有些比较容易修复 – 其他的不是很多:

  1. forkpty()和它的朋友来自BSD, 不是POSIX兼容的 。 他们应该避免新的方案。 从pty(7) manual page

    历史上,两个伪终端API已经发展:BSD和System V. SUSv1基于System V API对伪终端API进行了标准化,并且该API应该用于所有使用伪终端的新程序中。

    你应该使用posix_openpt()来代替。 这个问题可能并不重要,但你应该意识到这一点。

  2. 您正在调用原始系统调用( read()write() )和file-stream( printf()fgets() )函数。 这是迷惑自己的好方法。 一般来说,你应该选择一种方法并坚持下去。 在这种情况下,最好使用低级系统调用( read()write() )来避免由于C库函数使用的I / O缓冲区而引起的任何问题。

  3. 你正在为你的终端设定一个基于行的范例,使用printf()fgets() 。 这并不总是如此,尤其是在处理像vim这样的交互式程序时。

  4. 您假设一个C风格的单字节以null结尾的字符串范例。 终端通常处理字符和字节 – 不是字符串。 虽然大多数字符集编码避免使用零字节,但并非全部都是这样

  5. 由于上面的(2),(3)和(4),你没有正确使用read()write() 。 您应该使用它们的返回值来确定它们处理的字节数,而不是像strlen()那样的基于字符串的函数。

  6. 这是我认为最难解决的问题:你隐含地认为:

    • 终端(或其驱动程序)是无状态的:不是。 期。 至少有两个有状态的控件,我怀疑是基于ncurses的程序无法正常工作的原因:终端的线路模式和本地回声控制 。 至少这些必须在父/主和从终端之间匹配以避免各种奇怪的伪像。

    • 终端的控制接口可以通过来回传递字节来传递:并不总是如此。 现在的虚拟终端允许通过ioctl()调用进行一定程度的带外控制,如Linux所述。

    处理这个问题最简单的方法可能是将父终端设置为原始模式,并让从属伪终端驱动程序处理棘手的细节。

你可能想看看这个程序似乎工作正常。 它来自“Linux编程接口 ”一书,完整的源代码在这里 。 免责声明:我没有阅读这本书,也没有宣传 – 我刚刚找到了使用Google的程序。