在伪终端中进行Ncurses程序

Irr*_*ewb 8 c linux

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

问题是,我的突破似乎是关闭的.(仅在我按回车键后才显示shell提示.)

此外,我仍然无法正常使用ncurses程序,如vi.谁能告诉我如何为此设置伪终端?

我写得很糟糕的程序可以在这里找到,我鼓励你编译它.操作系统是GNU/Linux,谢谢.

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

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

thk*_*ala 6

你的程序有几个问题。有些相对容易修复 - 其他则不然:

  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 的程序无法正常工作的原因:线路模式和终端的本地回声控制。至少这些必须在父/主和从终端之间匹配,以避免各种奇怪的工件。

    • 终端的控制接口可以通过来回传递字节来传递:并非总是如此。现代的虚拟终端允许通过一定程度的外的带外控制的ioctl()呼叫,用于Linux描述这里

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

您可能想看看这个似乎运行良好的程序。它来自The Linux Programming Interface一书,完整的源代码在这里免责声明:我没有读过这本书,也没有宣传它 - 我只是使用 Google 找到了该程序。

  • TLPI 由 Michael Kerrisk 编写,他在维护 Linux 手册页方面做得非常出色。 (2认同)