模拟终端学习

xterm

xterm,一个模拟出来的终端,解决的是真实机器的输入和输出模拟问题。xterm本质上是应用程序,是个软件,它不同于硬件的输入-键盘、输出-显示器。他是怎么做到模拟的?

这个问题到底难在哪?可以通过一个具体的case来体会。
假设有一个进程A,作为进程B,进程B怎么向进程A的标准输入一串字符串。

首先我做了一个简单的尝试。为了简单起见,进程B为当前使用的bash进程,在bash中通过

cat > /proc/pid_of_A/fd/0 <<EOF
xxx
yyy
EOF

可以看到进程A所在的shell有输出xxx\nyyy,但进程A中的read函数并没有起到作用。所以到底是哪里出了问题?
问题单纯写入到文件并不能触发操作系统处理真实输入终端(键盘)敲击键盘的处理函数。

参考
https://unix.stackexchange.com/questions/48103/construct-a-command-by-putting-a-string-into-a-tty/48221

vim的term_sendkeys源码阅读

vim中term可以开启一个term(term应该不算进程),在term中fork执行bash进程,vim的term_sendkeys()函数可以向term中的bash进程发送命令,并有执行的效果,这里就读读vim的源码来学习一下term。

脚本中的term_sendkeys调用的是vim/src/terminal.c中的f_term_sendkeys()函数。该函数中将msg中字符串解析为一个个字符int c,通过send_keys_to_term(term, c, 0, FALSE)一个个发给term。
term和具体的某个进程绑定。然后通过channel_send将vim当前的结果发送给term绑定的进程。

  channel_send(term->tl_job->jv_channel, get_tty_part(term),
              (char_u *)msg, (int)len, NULL);
//函数细节
channel_send( ) { 
...
f (part == PART_SOCK)
  res = sock_write(fd, (char *)buf, len);
else
{
  res = fd_write(fd, (char *)buf, len); //实测下来,走的都是这一条分支,上面的分支可能是vim远程编辑走的分支。
}

上面源码中fd指向的是/dev/ptmx设备。下面的文章描述了ptmx设备,这是xterm实现的一个重要基础。文章提到这是一个虚拟终端的字符文件,当一个进程open这个文件的时候,进程可以得到一个虚拟终端的master描述符,使用stdlib.h中的ptsname(3)可以得到一个slave描述符。从而xterm中的
https://linux.die.net/man/4/ptmx

Once both the pseudoterminal master and slave are open, the slave provides processes with an interface that is identical to that of a real terminal.
Data written to the slave is presented on the master descriptor as input. Data written to the master is presented to the slave as input.

posted @   zwlwf  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示