【发布时间】:2020-04-18 03:11:39
【问题描述】:
我有一个程序使用https://github.com/creack/pty 创建伪终端。它是如何工作的,我给出了一个命令——在这种情况下是bash -i——它创建了一个文件对象,你可以在其中读写,它将作为stdin和stdout工作,我不断地阅读文件并将数据发送给客户端。这工作正常,但是当另一个客户端连接时,它只会在她连接后接收数据,这是不可取的。
正常的客户端行为:
computer:~$
computer:~$
computer:~$
computer:~$
computer:~$ echo "a"
a
computer:~$
第二个客户端在客户端 1 键入 c: 后连接:
ho "a"
a
computer:~$
如您所见,这是有问题的,因为客户端 2 将截断输入,所需的行为是发送所有历史记录或缓存状态。
我尝试使用file.ReadAt(b, 0) 读取文件,它从偏移量0 开始读取文件并将结果存储在b 但我得到ENXIO: 6 - No such device or address 我认为这是因为文件不是真正的文件。我目前正在做的是将所有输出数据存储到缓冲区中,当新客户端连接时,我发送存储的缓冲区,但这不是一个完整的解决方案,因为如果客户端使用 clear 或者它使用的命令与像vi 或nano 这样的终端,缓冲区不适应它只存储输出。
我正在使用 GO,但我认为这个问题与特定语言没有太大关系,所以如果你有 C 或其他东西的答案,我可以看到它并尝试在 GO 中找到等价物。无论如何,这是我正在使用的 GO 代码。
初始化:
c := exec.Command("bash", "-i")
// Start the command with a pty.
ptmx, err := pty.Start(c) // ptmx is of type *os.File
阅读:
// this gets called in a while true loop
func (t *Terminal) Read(b []byte) (int, error) {
n, e := t.ptmx.Read(b)
for _, byt := range b {
t.buffer.Insert(byt)
}
return n, e
}
【问题讨论】:
标签: go unix terminal pty terminal-emulator