在伪终端中进行Ncurses程序

时间:2011-12-07 01:29:57

标签: c linux

在我不断尝试理解伪终端如何工作的过程中,我编写了一个小程序来尝试运行bash。

问题是,我的突破似乎是关闭的。 (仅当我按下回车键时才显示shell提示。)

此外,我还是无法正常使用ncurses程序,比如vi。谁能告诉我如何为此设置伪终端?

My badly written program can be found here, I encourage you to compile it。操作系统是GNU / Linux,谢谢。

编辑:编译如下:gcc program.c -lutil -o program

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

1 个答案:

答案 0 :(得分:4)

您的计划中有几个问题。有些相对容易修复 - 其他则不是很多:

  1. forkpty()及其朋友来自BSD且与POSIX不兼容。新程序应该避免使用它们。来自pty(7) manual page

      

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

    您应该使用posix_openpt()代替。这个问题可能并不重要,但您应该了解它。

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

  3. 您假设使用printf()fgets()为您的终端设置了基于行的范例。这并非总是如此,尤其是在处理vim等交互式程序时。

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

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

  6. 在我看来,这个问题最难以解决:你隐含地假设:

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

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

    处理此问题的最简单方法可能是将父终端设置为原始模式,让slave伪终端驱动程序处理尴尬的细节。

  7. 你可能想看看this program似乎工作正常。它来自书籍The Linux Programming Interface,完整的源代码是here免责声明:我没有看过这本书,也没有推广它 - 我刚刚使用Google找到了这个程序。