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