首页 > 其他分享 >模拟终端学习

模拟终端学习

时间:2023-06-10 23:22:31浏览次数:48  
标签:term slave xterm vim 学习 fd 终端 进程 模拟

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.

标签:term,slave,xterm,vim,学习,fd,终端,进程,模拟
From: https://www.cnblogs.com/zwlwf/p/17472168.html

相关文章

  • 编程学习感觉困难怎么办?
    当你感觉编程学习困难时,以下是一些可以帮助你的建议:保持积极心态:编程是一项复杂的技能,学习过程中可能会遇到挑战。重要的是保持积极的心态,相信自己能够克服困难并取得进步。分解问题:有时候一个看似复杂的编程问题可以被分解为更小、更容易解决的子问题。尝试将问题分解......
  • JavaScript学习笔记:客户端编程之异常处理
    未被捕获的异常在程序中,往往会出现异常。虽然主动捕获这些异常是保证程序健壮的必要做法,但是难免会漏掉一些。对于未被捕获的异常,浏览器会在控制台显示一条错误信息,该信息包含异常信息和其在代码中出现的位置。window.onerrorWindow对象有一个onerror属性,将其指定为一个函数,可......
  • 4.15学习总结
    androidstdio中marqueeRepeatLimit无法循环播放 首先,这个控件需要得到焦点,因此来实现循环播放,因此我们要 等我们再次启动虚拟机时,我们能够发现再次点击文字,就能够使控件文字循环播放。 但是这样点击文字循环会让整个页面看起来很傻逼,弄得就好像我们故意跟它显摆似的,......
  • 4.14学习总结
    androidstdio中button的按下与松开实现图标转换 图片:首先在res目录下的drawable文件夹下创建select功能的.xml文件,然后下载两张图片drawable文件夹(图片名称开头不可以是数字),第二步,在.xml文件中添加如下两行代码<itemandroid:drawable="@drawable/图片名称"android:stat......
  • 4.17学习总结
    sql的常用语句 增加表中数据:insertinto表名(列名1,列名2,...,列名n)values(值1,值2,...,值n);//按列名插入全部数据insertinto表名values(值1,值2,...,值n);//按列名顺序插入数据insertinto表名(列名1,列名2)values(值1,值2);//按列名插入部分数据删除表中数据:de......
  • 2023冲刺国赛模拟 15.1
    T1计数首先考虑计数有标号可重叠的方案数,容易发现此时\(x,y\)两维独立,因此考虑其中\(1\)维,设\(f_{i,j}\)表示此时考虑到第\(i\)对左右边界\((x_{i,1},x_{i,2})\),离散化后的\(x\)坐标形成了\(j\)个点时的方案数,容易发现此时数轴上存在\(j\)个点,以及\(j+1\)个空......
  • 4.1学习总结
    HTML 全局属性New :HTML5新属性。属性描述accesskey设置访问元素的键盘快捷键。class规定元素的类名(classname)contenteditableNew规定是否可编辑元素的内容。contextmenuNew指定一个元素的上下文菜单。当用户右击该元素,出现上下文菜单data-*New用于存......
  • 4.3学习总结
    加密//Copyright(c)2006DamienMiller<[email protected]>////Permissiontouse,copy,modify,anddistributethissoftwareforany//purposewithorwithoutfeeisherebygranted,providedthattheabove//copyrightnoticeandthispermissionnotice......
  • 4.2学习总结
    <%--CreatedbyIntelliJIDEA.User:绿波亭Date:2023/5/29Time:14:51TochangethistemplateuseFile|Settings|FileTemplates.--%><%@pagecontentType="text/html;charset=UTF-8"language="java"%><!DOCTYPEhtml&g......
  • 4.7学习总结
    关于post传值乱码问题 由于get传值跟在网址后,post在特定的区域需要字符编译(大概意思,不准确),需要对编码进行设置request.setCharacterEncoding("UTF-8");......