how can I determine controlling tty if no file descriptor is open onto it? (System V r[23])

Daniel R. Levy levy at ttrdc.UUCP
Fri May 13 04:30:14 AEST 1988


[Please skip this if you've already seen it once.  My first attempt fell on
the floor.]

I am trying to write a program UNDER SYSTEM V RELEASE 2 AND 3 which
disassociates itself from the controlling terminal (using setpgrp() after
redirecting all file descriptors still open onto the terminal, into a file),
tries to exec() a machine binary or shell script, and if that doesn't work
sends an error message to the terminal and exits.

The reason I want this is so I can put a command in background a la nohup,
BUT, unlike nohup, even if the command turns interrupt/quit/hangup signal
catching back on, or a gremlin tries to kill -9 my entire login process group
(like one $#@!! version of telnet I am using does upon logout), it will not
be affected by goings-on at the terminal.

However, I am having a problem with always getting an error message back to
the terminal from which the command was issued.  It does no good to try to
write to "/dev/tty" once one has divorced from the controlling terminal.
In fact, even if a file descriptor is kept open onto "/dev/tty" during the
setpgrp(), writing onto it afterward fails with errno==ENXIO (No such device
or address).   Now, of course, if I knew the explicit name of the
ex-controlling terminal, I could open that and send the error message to it.

In many cases, I can indeed determine that name as the program begins, and
save it.  If there is still a file descriptor open onto the terminal (e.g.,
fd 2, error output) I can use ttyname() to determine what it was attached to.
If there is no file descriptor open onto the terminal (the user has redirected
them all), I am still in luck if the program is a direct child of the login
shell.  I can use getppid() to find out what that pid is, and search through
/etc/utmp to determine the controlling terminal associated with it.  However,
if neither of these is the case (user redirected stdout and stderr, and put
the program into background [stdin is closed] from a non-login shell), I am
stuck.  I _could_ run /bin/ps -u <my_username> and parse through the process
geneology to find out what terminal I was attached to (or rather, the terminal
my parent process is still attached to).  But this can be slow, especially if
ps decides it must rebuild /etc/ps_data (my user may have logged out by the
time that finishes and would miss the error message, which could have warned
him of a typo in the command).  A shotgun write to all terminals the user is
logged onto is not really desireable, as the user might be running a graphics
application on one of them.

Is there any better way to do this that I am overlooking?  Wizards please
send suggestions by email, flamers please cat your flame > /dev/null.  Thanks
in advance.

Oh yes, as I indicated above, this is for SYSTEM V RELEASE 2 and 3.  I really
would like any suggested solution to work on both.  I don't really care how it
would be done under BSD.
-- 
|------------Dan Levy------------|  Path: ihnp4,<most AT&T machines>!ttrdc!levy
|              AT&T              |  Weinberg's Principle:  An expert is a
|       Data Systems Group       |  person who avoids the small errors while
|--------Skokie, Illinois--------|  sweeping on to the grand fallacy.



More information about the Comp.unix.wizards mailing list