Maintaining message boundaries in redirected stdout/stderr
- From: Dom Fulton <wes104@xxxxxxxxx>
- Date: Mon, 04 Feb 2008 15:37:27 +0000
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
.
- Follow-Ups:
- Re: Maintaining message boundaries in redirected stdout/stderr
- From: David Mathog
- Re: Maintaining message boundaries in redirected stdout/stderr
- From: Henry Townsend
- Re: Maintaining message boundaries in redirected stdout/stderr
- Prev by Date: Re: using getenv,putenv even before main()
- Next by Date: Re: disable help page
- Previous by thread: Discovering file descriptor number available
- Next by thread: Re: Maintaining message boundaries in redirected stdout/stderr
- Index(es):
Relevant Pages
|