文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

node.js怎么实现伪终端

2023-07-04 16:07

关注

这篇“node.js怎么实现伪终端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“node.js怎么实现伪终端”文章吧。

伪终端

伪终端不是真正的终端,而是内核提供的一个“服务”。终端服务通常包括三层:

最顶层提供给字符设备的输入输出接口中间层的线路规程(line discipline)底层的硬件驱动

其中,最顶层的接口往往通过系统调用函数实现,如(read,write);而底层的硬件驱动程序则负责伪终端的主从设备通信,它由内核提供;线路规程看起来则比较抽象,但是实际上从功能上说它负责输入输出信息的“加工”,如处理输入过程中的中断字符(ctrl + c)以及一些回退字符(backspace 和 delete)等,同时转换输出的换行符n为rn等。

一个伪终端分为两部分:主设备和从设备,他们底层通过实现默认线路规程的双向管道连接(硬件驱动)。伪终端主设备的任何输入都会反映到从设备上,反之亦然。从设备的输出信息也通过管道发送给主设备,这样可以在伪终端的从设备中执行shell,完成终端的功能。

伪终端的从设备中,可以真实的模拟终端的tab补全和其他的shell特殊命令,因此在node原生模块不能满足需求的前提下,我们需要把目光放到底层,看看OS提供了什么功能。目前,glibc库提供了posix_openpt接口,不过流程有些繁琐:

使用posix_openpt打开一个伪终端主设备 grantpt设置从设备的权限 unlockpt解锁对应的从设备获取从设备名称(类似 /dev/pts/123)主(从)设备读写,执行操作

因此出现了封装更好的pty库,仅仅通过一个forkpty函数便可以实现上述所有功能。通过编写一个node的c++扩展模块,搭配pty库实现一个在伪终端从设备执行命令行的terminal。

关于伪终端安全性的问题,我们在文章的最后在进行讨论。

伪终端实现思路

根据伪终端的主从设备的特性,我们在主设备所在的父进程中管理伪终端的生命周期及其资源,在从设备所在的子进程中执行shell,执行过程中的信息及结果通过双向管道传输给主设备,由主设备所在的进程向外提供stdout。

在此处借鉴pty.js的实现思路:

pid_t pid = pty_forkpty(&master, name, NULL, &winp); switch (pid) { case -1:  return Nan::ThrowError("forkpty(3) failed."); case 0:  if (strlen(cwd)) chdir(cwd);  if (uid != -1 && gid != -1) {  if (setgid(gid) == -1) {   perror("setgid(2) failed.");   _exit(1);  }  if (setuid(uid) == -1) {   perror("setuid(2) failed.");   _exit(1);  }  }  pty_execvpe(argv[0], argv, env);  perror("execvp(3) failed.");  _exit(1); default:  if (pty_nonblock(master) == -1) {  return Nan::ThrowError("Could not set master fd to nonblocking.");  }  Local<Object> obj = Nan::New<Object>();  Nan::Set(obj,  Nan::New<String>("fd").ToLocalChecked(),  Nan::New<Number>(master));  Nan::Set(obj,  Nan::New<String>("pid").ToLocalChecked(),  Nan::New<Number>(pid));  Nan::Set(obj,  Nan::New<String>("pty").ToLocalChecked(),  Nan::New<String>(name).ToLocalChecked());  pty_baton *baton = new pty_baton();  baton->exit_code = 0;  baton->signal_code = 0;  baton->cb.Reset(Local<Function>::Cast(info[8]));  baton->pid = pid;  baton->async.data = baton;  uv_async_init(uv_default_loop(), &baton->async, pty_after_waitpid);  uv_thread_create(&baton->tid, pty_waitpid, static_cast<void*>(baton));  return info.GetReturnValue().Set(obj); }

以上就是关于“node.js怎么实现伪终端”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯