Maintaining message boundaries in redirected stdout/stderr



I've just done a telnet-like client-server app, where a user requests
the server to run an arbitrary program, and the server redirects the
child program's stderr and stdout back to the client.

This seems to work, but I've just noticed an interesting problem. If
the child outputs to both stdout and stderr, then these are likely to
get mixed up by the time that they get back to the client. So, if the
child executes something like

fprintf(stdout, "Hello world\n");
fprintf(stderr, "error\n");

then this could end up on the client terminal as

Hellerroro
world

The architecture is rather complicated, because the program has to run
on Unix and Windows, and Windows has trouble inheriting sockets. But,
in short, there's a single socket connecting the client and server,
and that carries individual stdout and stderr characters packaged up
as 4-byte packets (they have to fit into a command and status
protocol). The client creates 3 pipes to talk to the child, forks the
child program, and muxes the 3 pipes onto the single socket back out
to the client. A mutex protects packet writes out to the client, but
operates only at the single-character (4-byte packet) level.

The problem is simple - the client has no idea where the 'logical'
boundaries in the child's outgoing messages are, and so can't ensure
that the logical boundaries are preserved on the socket.

Is there a fix to this problem?

Some quick thoughts -

1 - use 2 sockets, instead of 1, but I don't think that this will
help.

2 - assume that a newline marks a logical boundary, and reserve the
socket for either stdout or stderr until a newline arrives. This
sounds dangerous, and would need a timeout.

3 - could a pty be used to fix this? But... I don't think Windows has
an equivalent.

4 - The client has some sort of hook into the child's stdout/stderr
buffers (via setvbuf?). But, again, I don't think I can get this level
of control in Windows.

5 - the simple fix - connect both the child's stdout and stderr to the
client's stdout. I'm not convinced that this will fix the problem, and
the client can no longer tell the difference between the child's
stdout and stderr.

Actually, now that I've written it down, perhaps the only logical
answer is some variation of (2), assuming that I can peek into the
outgoing pipes coming from the child.

Any thoughts?

TIA

-Dom
.



Relevant Pages

  • Re: StdOut and StdErr reading...
    ... My idea is to use the Execmethod to run the client, ... via StdIn and receive output via StdOut and StdErr. ... I was able to find a condiction (when I read "sftp>" from the buffer) ...
    (microsoft.public.scripting.vbscript)
  • Re: select + stderr
    ... > I have a client - server, but this works only for stdout. ... > file), I get the error message on server side on stderr, but on client ...
    (comp.unix.programmer)
  • Re: select + stderr
    ... What means stdout in the context of a server-client pair? ... >>file), I get the error message on server side on stderr, but on client ...
    (comp.unix.programmer)
  • select + stderr
    ... I have a client - server, but this works only for stdout. ... file), I get the error message on server side on stderr, but on client ...
    (comp.unix.programmer)
  • Re: os.popen3 hangs in Windows XP SP1, SP2. Python 2.5 & 2.4. Consistent test case.
    ... If there is output on stdout and stderr, you will get a dead lock sooner ... The child will block. ... to safely read both stdout and stderr in a way that is child program ...
    (comp.lang.python)