levy@ttrdc.UUCP (Daniel R. Levy) (05/13/88)
[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.