Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Process connected to separate pty for stdout and stderr

Tags:

linux

posix

pty

I'm writing a terminal logging program - think the script command but a bit more featureful. One of the differences is that, whereas script captures stdout, stdin and stderr as one big character stream, I would like to keep them separate and record them as such.

In order to do this, I use the standard approach of running a child shell connected to a pty, but instead of using a single pty with stdin, stdout and stderr all connected to it, I use two ptys - with stdin and stderr connected to one pty, and stdout on the other. This way, the master process can tell what is coming from stdout and what from stderr.

This has, so far, worked fine. However, I'm starting to run into a few issues. For example, when trying to set the number of columns, I get the following:

$stty cols 169

stty: stdout appears redirected, but stdin is the control descriptor

This seems to be a result of this piece of code, which seems to check whether stdout and stderr are both ttys, but complains if they are not the same.

My question, therefore, is this: am I violating any fundamental assumptions about how Posix processes behave by acting in this way? If not, any idea why I'm seeing errors such as this? If so, is there any way I can get around this and still manage to separate stdout and stderr nicely?

like image 766
Impredicative Avatar asked Feb 14 '14 12:02

Impredicative


People also ask

What is the difference between stdout and stderr in a running process?

The Linux Standard Streams Text output from the command to the shell is delivered via the stdout (standard out) stream. Error messages from the command are sent through the stderr (standard error) stream.

Is stdout shared between processes?

Yes they share the same location.


1 Answers

One idea I had about this is to use a process directly on the pty which then runs the target program, e.g.

(wrapper) -> pty -> (controller) -> script

The controller would be responsible for running the script and capturing the stdout and stderr separately, feeding them back to the wrapper, perhaps by some non-std fd, or alternatively, serialising the data before shipping it back, e.g. prefixing output from stderr with stderr: and stdout with stdout: - then in the wrapper deserialize this and feed it back upstream or whatever you want to do with it.

like image 144
ioquatix Avatar answered Oct 19 '22 00:10

ioquatix