Fransebas
Fransebas

Reputation: 341

Get previous input form a pseudo terminal

I have a program that uses https://github.com/creack/pty to create pseudo terminals. How it works it's that I given a command - in this case is bash -i - it creates a file object where you can read and write and it will work as stdin and stdout, with that I'm continuously reading the file and sending the data to a client. This works fine but when another client connects, it will only receive the data after she connects which is not desirable.

Normal client behavior:

computer:~$ 
computer:~$
computer:~$
computer:~$
computer:~$ echo "a"
a
computer:~$

Second client connects after client 1 typed c:

ho "a"
a
computer:~$

As you can see this is problematic because client 2 it's going to have truncated input, the desired behavior would be to send all the history or cache state.

I tried reading the file using file.ReadAt(b, 0) which read the file starting at offset 0 and stores the result in b but I get ENXIO: 6 - No such device or address I think this happens because the file is not really a file. What I'm currently doing is storing all output data into a buffer and when a new client connects I send the stored buffer but It's not a complete solution because if client one uses clear or if it uses a command that messed up with the terminal like vi or nano the buffer doesn't adapts it only stores the output.

I'm using GO but I think this problem is not related that much with a specific language so if you have an answer in C or something, I can see it and try to find the equivalent in GO. In any case here is the GO code I'm using.

Initialization:

c := exec.Command("bash", "-i")

// Start the command with a pty.
ptmx, err := pty.Start(c) // ptmx is of type *os.File

Reading:

// 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
}

Upvotes: 1

Views: 413

Answers (1)

torek
torek

Reputation: 487983

Offsets will not help you. The problem is that a pty is a channel-like device with no memory: once data have flowed through the pty, from one end to the other, and been consumed by a reader, those data are gone. The OS's seek offset is not relevant.

If you want to maintain a log of all data exchanged, you'll have to do that yourself.

Upvotes: 2

Related Questions