[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: ncurses on pipes
Re: ncurses on pipes
Wed, 13 Jun 2007 10:41:44 -0400
On Wed, Jun 13, 2007 at 03:44:34PM +0200, Robert Lemmen wrote:
> hi bob! cool to see you again!
> On Wed, Jun 13, 2007 at 09:22:09AM -0400, Bob Rossi wrote:
> > I'm wondering if there is a different way to solve this problem. This isn't
> > an attempt to change your program, but perhaps a different way to look
> > at the problem. If someone is using a telnet client, they already have a
> > working pty on there end.
> > On the server side, you also have a pty (stdin,stdout). If you fork/exec
> > a child process (which could be the ncurses application) to deal with
> > the request, wouldn't that just do what you want without involving the
> > pipe or socket?
> > I've seen this done before several times. For instance, the
> > sourceforge.net compile farm does this. Also, take a look at
> > ascii star wars, 'telnet towel.blinkenlights.nl'. I believe that's how
> > they must have solved this problem. Is that what you are looking to
> > achieve?
> this is very basically what i want to schieve, but i don't really
> understand your approach. if you are aiming at just using a telnet
> server and running a UI client program there for each connection (as has
> been suggested off-list): i fear that this will get expensive if you
> have many clients. if you are talking about something else: please
Yes, this is mostly what I was suggesting. What solution do you have
that would be less expensive?
> apart from the "how do i..." part of this, i really don't understand why
> a tty is needed here. is this only because of the mechanism that
> determines the capabilities of the terminal?
I believe that interactive applications look at what they are connected
to using the isatty system call. If they are talking to a pipe or
socket, they consider the communication to be non interactive and behave
differently than if they are talking to a tty.
> if this is so: is there a
> way to supply these capabilities myself so it will work with a non-tty?
> or is there something else involved? somewhere on the net i found a text
> that gave the hint that output buffering might be a part of the problem
> as well...
Buffering will behave different when you are talking to a pipe or to a
tty. When talking to a tty, the data is line buffered. When talking to
a pipe, the data will be page buffered. This is from memory, hopefully
it is true. If you use stderr, you will avoid the buffering problem, as
stderr isn't bufferred.
So, I believe if you want ncurses or readline or other interactive
programs to look and act interactively, you will need to give them a
Now, this next part is going to be long and ugly, and may have some
misinformation, but this is off the top of my head. Think about how a
normal client/server telnet scenario works. The client is somewhere on a
terminal. The client connects to a telnet server.
The telnet server has a pty for stdin/stdout/stderr, because it was
most provided one by the system on startup. The server binds to a port
and listens for connections. When a connection is made, it will allocate
a new pty for the child process. It will then fork and exec the child
process. The child process is normally the users shell, let's say bash.
Now, bash behaves different if it is talking to a pty or to a pipe. The
server knows this. So, before it exec's bash, it connects the client
side of the pty to the child process and then execs it. Bash is quite
happy when it is started, and waits for input/output on the client side
of the pty. As far as bash knows, it's connected to a terminal, just
like it would be if you opened an xterm.
When the server receives data over the socket, it parses the telnet
protocol and determines what data is necessary to give to the child.
It writes to the server side of the pty pair, which the child then gets.
If the child wants to write data back, it write to it's stdout, which
gets funneled back to the server. The server then sends this data over
the socket which it then gets to the client.
So, what I and others are suggesting is that you change the program
the telnet server is starting from /bin/bash to whatever you would like.
This will make everything "just work" very quickly.
Hope that helps,