[comp.windows.x] Grabbing tty

howland@tolkien.helios.nd.edu (Robert Howland) (11/17/90)

I originally posted this to unix.questions 11 November.  The lack of response
has been, as they say, deafining.  So I'm going to try again, working up to
.wizards (though there doesn't seem to have been much to that newsgroup
recently), as well as to sys.sun (since the TIOCCONS ioctl call is apparently
Sun-specific).  Though it's more Unix than X, there has been traffic regarding
console programs there, so I'll try that too (I'm desparate).  I hope someone
out there can help!

A short time ago, Chuck Musciano (Harris Corp.) posted a very nice X/XView
console program, 'contool', to capture console output when running an X
session.  (It's similar to the '-C' option to 'xterm', but with various bells
and whistles, including filtering of commands and a cute console icon which
flashes when such a message comes in, allowing it to be run iconified most of
the time and save screen space.)  It sets up a pseudo-terminal which then grabs
the console with an ioctl(pseudo-slave,TIOCCONS, ) command, directing the
normal console input into the pty window.  It works very nicely when one is
running on his own workstation; unfortunately, I am not.

I am currently using an [NCD] X terminal which, in turn, runs on a cluster of
publicly-accessible workstations in our Sparc lab in the College of
Engineering.  I start the session with an initial connection to such a
machine, then immediately switch into X (making the original window
disappear).  Using 'contool' thus has two results:

   1)  Grabbing the console locks anyone else out of the machine I happen to be
       running on.  While, in a selfish way, this might not be bad, it _is_
       inconsiderate; furthermore, enough people know about how to reboot the
       machines that I am likely to be--in fact have been--interrupted in the
       middle of a session.  Very annoying.

   2)  Output sent to MY "console"--actually a tty running on the
       workstation--including error messages from X processes opened at that
       window and 'talk' requests and the like, doesn't get sent to me at all.
       This is, after all, the intent of having a console program working, and
       not getting this output pretty much defeats the purpose of the code in
       the first place.

This brings me to the question, then:  is there an easy way to connect a tty
(other than the console) to another process?  While the original program is
one-way only--it doesn't allow commands in the pty to be sent to the console,
it would seem possible to get a stream connection between the two tty's--the
original session and my X session, giving bi-directionality of communication.
Though I'm not sure, this is hardly critical, and I'd be satisfied with
mono-directional streaming.

I'm basically a [dumb] ME and have only been working with UNIX and C since
April (background in FORTRAN).  At the same time, I did go so far as to try to
go through the code to see if I could do it myself.  The ioctl( ,TIOCCONS, )
gets the console; it is common to all the "console" programs/options I
have seen.  It would seem possible that there should be some other option which
would similarly grab a tty--allow redirection of input to that already-opened
tty (from which the X session is spawned, recall) to the pty 'contool' has
established.  But ioctl has an excessive number of options (scattered all over
the man pages), and I'm not even sure if it is this or fcntl I should be
looking at.  I have looked into dup2 and even programmed it:  it doesn't grab
the console, but it doesn't do anything else, either; the problem _seems_ to be
that an 'open' to the [original, X-spawning] /dev/ttyp? doesn't return the
field descriptor of the _original_ tty--different process.  Another possibility
is to use an 'freopen'; it seems to redirect output, but there is a similar
problem getting the stream associated with the _original_ tty.  'stat' seems to
return the i-node--if this is correct from the spawned process which actually
calls 'contool'--and if I understand this correctly, that is actually what is
needed to be able to access the same file/device.  I also considered pipes, and
even brushed around the edges of sockets (scary).

At this point (probably partly due to inadequate background!), I am hopelessly
confused, as you can tell.  Obviously, my prime concern is to get the console
program to work!  At the same time, I would appreciate some minimal
understanding of what is going on, and why various other options mightn't work.
I am grateful for any help on this and thank anyone in advance for their
time/consideration.

mouse@LIGHTNING.MCRCIM.MCGILL.EDU (11/17/90)

> I originally posted this to unix.questions 11 November.  The lack of
> response has been, as they say, deafining.  So I'm going to try
> again, working up to .wizards (though there doesn't seem to have been
> much to that newsgroup recently),

Yeah, some fool[%] seems to have taken it into its silly head to rename
it to something else - comp.unix.internals sounds right.  (To make
things worse, a bunch of people got jumpy at seeing "internals" in the
name and dropped it in terror at the possibility of maybe actually
having to admit that what they've been doing all this time might have
something to do with UNIX internals.)

[%] Sorry, whoever you are, but I think this was a foolish action.
    (I've also never seen a reason for it, let alone a good reason, but
    then, I wasn't reading c.u.w for some time before the change.)

> A short time ago, Chuck Musciano (Harris Corp.) posted a very nice
> X/XView console program, 'contool', to capture console output when
> running an X session.  [...]  It works very nicely when one is
> running on his own workstation; unfortunately, I am not.

> I am currently using an [NCD] X terminal which, in turn, runs on a
> cluster of publicly-accessible workstations in our Sparc lab in the
> College of Engineering.  I start the session with an initial
> connection to such a machine, then immediately switch into X (making
> the original window disappear).  Using 'contool' thus has two
> results:

>    1)  [...it snatches the real console...]

>    2)  Output sent to MY "console"--actually a tty running on the
>        workstation--including error messages from X processes opened
>        at that window and 'talk' requests and the like, doesn't get
>        sent to me at all.
[I gather this is the stuff that would "normally" appear in the telnet
pseudo-window.]
>        This is, after all, the intent of having a console program
>        working,
Is it?  (See below.)
>        and not getting this output pretty much defeats the purpose of
>        the code in the first place.

I had though the reason for xterm's -C option, and other things with
similar effect, was to make stuff that would normally scribble on the
raw framebuffer, ignoring the X session, show up in a window where it
wouldn't corrupt the screen.

As such, you don't want to run contool (or xterm -C, or anything else
of the sort) on any machine but the one whose screen you're on.  When
you're using an X terminal, this means you don't want to run them, at
all.

That should deal with point 1. :-)  Point 2 is more interesting.

Back when I was trying out an X terminal, what I normally did was to
log out of the telnet session as soon as the X session was in full
swing.  This cures the talk problem[$].  As for errors from the X
session itself, what I did at the time was to leave the telnet window
around until everything was running; then when I brought it back to log
out, I would see any complaints.  What I have since done, since we
started using xdm, is to have my X startup scripts save their output
and error in files.

[$] Actually, I cured the talk problem more thoroughly by hacking talkd
    so that it announces the talk request to all the ttys it sees the
    user logged in on, not just the first one.

> This brings me to the question, then:  is there an easy way to
> connect a tty (other than the console) to another process?  [...]
> The ioctl( ,TIOCCONS, ) gets the console; it is common to all the
> "console" programs/options I have seen.  It would seem possible that
> there should be some other option which would similarly grab a
> tty--allow redirection of input to that already-opened tty (from
> which the X session is spawned, recall) to the pty 'contool' has
> established.  But ioctl has an excessive number of options (scattered
> all over the man pages), and I'm not even sure if it is this or fcntl
> I should be looking at.

I have never seen such a thing in any system.  I'm fairly sure it
doesn't exist in Berkeley through 4.3 or SunOS through 3.5; I think
(but am not even "fairly sure") that it doesn't exist in SunOS 4.1.

What TIOCCONS does:

	+----------+
	| Physical | <---before--------<-- data sent to /dev/console
	| Console  |              /
	+----------+           after
	             -------<---
	            /
	           L
	/dev/ttyp?  <-----> user program (normally a shell)
	   ^ v
	/dev/ptyp?  <-----> controller program (xterm, telnetd, etc)

(Something similar happens for input to /dev/console, but we don't need
to worry about that here.)

What you want is one of three things:

1)	  shell ---------->----after--
	   ^                 \        \
	/dev/ttyp? <---before/         +--> /dev/ttyp?
	   ^                           |      ^ v
	/dev/ptyp?                or just   /dev/ptyp?
	   ^ v                         |      ^ v
	telnetd (to X terminal)         -->  contool

2)	  shell
	   ^ v
	/dev/ttyp? -------->----after\      /dev/ttyp?
	   ^                  \       \        ^ v
	/dev/ptyp? <----before/        ---> /dev/ptyp?
	   ^ v                                 ^ v
	telnetd                              contool

3)	  shell
	   ^ v
	/dev/ttyp?
	   ^ v
	/dev/ptyp? -------->----after\
	   ^                  \       \
	telnetd    <----before/        --->  contool

(In each case, the possibility of redirecting data flowing the other
way - upwards in my diagrams - is potentially an option.)

The second one requires some fairly serious changes to the pseudo-tty
driver; it violates the idea that ptys form nice ttyXX/ptyXX pairs.  I
won't go into it further.

The third one is, I suspect, what you were trying to write with dup2.
The problem is twofold: one half is that as you surmised, the problem
is that the dup2 is modifying the file descriptor connections for only
the process that calls it: your neo-contool is incapable of modifying
telnetd's file descriptor setup.  The other half is that you were
opening the wrong half of the pty pair: you were opening the ttyXX half
rather than the ptyXX half.  (You can't open the ptyXX half anyway; the
controller devices are exclusive-acess.)

The first one is sort of possible.  It is possible to make contool
output enough information to allow the startup script to identify the
/dev/ttyXX device necessary; the script can then redirect its output
and error.  Perhaps something like (Bourne shell syntax)

	consoletty=`contool -autobackground -printtty`
	exec >$consoletty 2>$consoletty

(The -autobackground option is presumed to make contool put itself into
the background when it's ready for output to be redirected.)

> Another possibility is to use an 'freopen';

freopen is just the conceptual analog of dup2 in the world of stdio.
It has the same problems when applied here.

> 'stat' seems to return the i-node--if this is correct from the
> spawned process which actually calls 'contool'--and if I understand
> this correctly, that is actually what is needed to be able to access
> the same file/device.

This is true as far as it goes.  The inode is the thing on disk (well,
one of the things on disk) that corresponds to /dev/ttyp?; in the case
of a device (like pseudo ttys) all the inode really contains[#] is a
pair of numbers (small integers) that tell the kernel how to find the
driver for the device.  It really doesn't give you anything you can't
get by manipulating the corresponding thing in /dev.

[#] Well, that's all that's of interest here.

> At this point (probably partly due to inadequate background!), I am
> hopelessly confused, as you can tell.

You have made quite good progress for a first plunge.  I'd be glad to
explain anything that's still not clear, but I doubt it's really of
interest to the X list, as it winds up talking about UNIX more than
about X, so it would probably be better to take it to private email.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu