[net.unix-wizards] USG 5.0 r2: can my program tell if it is in background/nohup'd?

rcj@burl.UUCP (R. Curtis Jackson) (08/09/84)

Is there any way for me to make some test and see if I am running in
the background?  I have an assembler package that calls m4(1), runs
my own yacc/lex preprocessor, passes pseudocode onto a meta-assembler,
and conditionally calls a linkage editor.  I catch SIGINT because I
need to do tempfile cleanup, but when this package is run nohup'd in
the background and the user hits a delete or break in his login shell,
the interrupt punches through nohup (nohup does nothing with signal 2)
and kills the nohup'd process!!

This is not good.

These assemblies are large and may take 20 minutes.  Try not hitting
delete or break for 20 minutes on Unix and you'll see that this can
be both irritating and impossible.

Thanks for any help/pointers,
-- 

He gave the novice a long, icy stare and quietly growled, "RTFM".

The MAD Programmer -- 919-228-3313 (Cornet 291)
alias: Curtis Jackson	...![ ihnp4 ulysses cbosgd we13 ]!burl!rcj
			...![ ihnp4 cbosgd akgua masscomp ]!clyde!rcj

sherm@phoenix.UUCP (Paul A. Sherman) (08/10/84)

>    Is there any way for me to make some test and see if I am running in
>    the background?  I have an assembler package that calls m4(1), runs
>    my own yacc/lex preprocessor, passes pseudocode onto a meta-assembler,
>    and conditionally calls a linkage editor.  I catch SIGINT because I
>    need to do tempfile cleanup, but when this package is run nohup'd in
>    the background and the user hits a delete or break in his login shell,
>    the interrupt punches through nohup (nohup does nothing with signal 2)
>    and kills the nohup'd process!!

Although nohup doesn't do anything with signal 2, putting something in the
background with "&" normally ignores it.  You are causing it not to be ignored
when you call your own routine to handle SIGINT.

What you should do is check to see if SIGINT was already being ignored
when you try to handle it.  (This indicates that you're in the background.)
If it was being ignored, reset it to that state.

	if (signal(SIGINT, clean_routine) == SIG_IGN)
		signal(SIGINT, SIG_IGN);

Paul Sherman	AT&T Information Systems, Lincroft, NJ     phoenix!sherm
-- 

bsa@ncoast.UUCP (The WITNESS) (08/13/84)

Unless a drastic change took place in /bin/sh in USG5.0, "nohup" is a shell
script.  All it does is traps SIGHUP and "exec"s $*.  Try grabbing a copy of
/bin/nohup and modifying it.  If all else fails, ours is (yank it & modify):
-----------------------
trap "" 1 15
if test -t 2>&1  ; then
	echo "Sending output to 'nohup.out'"
	exec nice -5 $* >>nohup.out 2>&1
else
	exec nice -5 $* 2>&1
fi
-----------------------
Have fun!

--bsa
-- 
      Brandon Allbery: decvax!cwruecmp{!atvax}!bsa: R0176@CSUOHIO.BITNET
					       ^ Note name change!
	 6504 Chestnut Road, Independence, OH 44131 <> (216) 524-1416

"The more they overthink the plumbin', the easier 'tis tae stop up the drain."

mcferrin@inuxc.UUCP (P McFerrin) (08/15/84)

I can give you a couple of hints to determine if you are running in backgroun
with or without hohup.

Usually---- a background process and a nohupped process will have its
stdin to /dev/null which is NOT a tty.  Use isatty(3c) to determine this
(under ttyname(3c).

Another tip is that the hangup signal is ignored for nohupped process.
You can determine this by executing a signal system call in attempting
to set the 'func' to SIG_DFL, signal returnes the previous value of 'func'
which you can check to see if it is SIG_IGN.  I do this sort of thing
on a terminal lock program which I make sure that the hangup signal is NOT
ignored so that I can die whenever the terminal is hung up.

guy@rlgvax.UUCP (Guy Harris) (08/17/84)

> Another tip is that the hangup signal is ignored for nohupped process.
> You can determine this by executing a signal system call in attempting
> to set the 'func' to SIG_DFL, signal returnes the previous value of 'func'
> which you can check to see if it is SIG_IGN.

This opens a small window in which your signal catcher for SIGHUP is
SIG_DFL, so that a SIGHUP coming in during that window blows the process
away.  Better to set it to SIG_IGN and test the return value; of course,
that leaves a window in which a SIGHUP will be ignored, but there's no
way to close that window unless you're running BSD UNIX or some other
system which can "hold" signals until the signal action is changed.

ALL code that catches SIGINT, SIGQUIT, or SIGHUP (the three signals which are
generated by the terminal and which are ignored in background processes)
in a process that can be &'ed or "nohup"ed should do something like:

	if (signal(SIGxxx, SIG_IGN) != SIG_IGN)
		(void) signal(SIGxxx, catcher);

(possibly saving the result of the first test if it catches that signal in
several places).  That way, any &'ed or "nohup"ed process will not catch
the signal.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy