[comp.unix.internals] SIGCONT occurs after a SIGTERM

coleman@cam.nist.gov (Sean Sheridan Coleman X5672) (02/12/91)

Please explain to me why a SIGCONT is sent to a process after
SIGTERM is sent to my process. It doesn't compute because TERM
means to terminate the the process. I catch SIGCONT because I 
do some reconnecting for serial drivers after my process is
stopped from a cntl-Z. Below is a piece of the code and a
some output from the program. 

Here I stop the program with a ^Z and restart using fg %1.
SIGCONT is sent in this situation correctly.

<deputy /home/central/coleman/real_prog/net.dir/net_log> % net l logfile
^Z Signal caught is 18

Stopped (signal)
<deputy /home/central/coleman/real_prog/net.dir/net_log> % jobs
[1]  + Stopped (signal)     net l logfile
<deputy /home/central/coleman/real_prog/net.dir/net_log> % fg %1
net l logfile
 Signal caught is 19
^C Signal caught is 2



From another window, I used kill -TERM  to kill this process.
SIGTERM is received first but then SIGCONT is sent for no known
reason.

<deputy /home/central/coleman/real_prog/net.dir/net_log> % !ne
net l logfile
 Signal caught is 15
 Signal caught is 19
No devices are available to use for logging


Here is the signal handler:

Note: device,device_file and device_name are global

sig_handler(sig)
int sig;
{
	extern int device;
	extern FILE *device_file;
	extern char *device_name;	
	char *strip_add_dev_name();

	printf(" Signal caught is %d\n",sig);
	switch(sig)
	{
	 	case SIGINT:
		case SIGTERM:
			unlock_dev(strip_add_dev_name(ttyname(device),0));
			exit(1);
		case SIGTSTP:			
			unlock_dev(strip_add_dev_name(ttyname(device),0));
			close(device);
			kill(0,SIGSTOP);
			break;
		case SIGCONT:	
			if(device_file != NULL)
			{
				rewind(device_file);
				device = get_device(device_file);
			}
			else
			{
				if((device = chk_device(device_name)) < 0)
				{
					printf("No devices are available to use for logging\n");
					exit(1);
				}
			}

		 default:
			break;
				
	}
}


Thanks

Sean Coleman
coleman@bldrdoc.gov
NIST
Boulder, CO

pfalstad@tan.Princeton.EDU (Paul Falstad) (02/12/91)

coleman@cam.nist.gov (Sean Sheridan Coleman X5672) wrote:
>Please explain to me why a SIGCONT is sent to a process after
>SIGTERM is sent to my process. It doesn't compute because TERM
>means to terminate the the process. I catch SIGCONT because I 

This is caused by the following code in csh's sh.proc.c:

         if (signum == SIGTERM || signum == SIGHUP)
            (void) killpg((pid_t) pp->p_jobid, SIGCONT);

There is a good reason for this.  If you kill a stopped process, it
will not die until you send it a SIGCONT (unless you use SIGKILL).
It is counterintuitive for a process not to die when you type
"kill <process>", so somebody just threw in these two lines to have it
send a SIGCONT as well.  For the shell's kill code to not check to see if the
process is actually stopped before sending it a SIGCONT is just sloppy;
also singling out only SIGTERM and SIGHUP for this special treatment is a real
hack IMHO (unless I'm missing something).  Use /bin/kill <pid> which does
not do this.

--
Paul Falstad, pfalstad@phoenix.princeton.edu | 10 PRINT "PRINCETON CS"
[Your blood pressure just went up.]          | 20 GOTO 10
Princeton University would like to apologize to everyone for this article.
            "It seems inappropriate to use comp.unix.wizards
             as an AI interface to TFM."  - Tom Christiansen

richard@locus.com (Richard M. Mathews) (02/12/91)

coleman@cam.nist.gov (Sean Sheridan Coleman X5672) writes:

>Please explain to me why a SIGCONT is sent to a process after
>SIGTERM is sent to my process. It doesn't compute because TERM
>means to terminate the the process. I catch SIGCONT because I 
>do some reconnecting for serial drivers after my process is
>stopped from a cntl-Z. Below is a piece of the code and a
>some output from the program. 

This is yet another example of C Shell brain damage.  The shell thinks
it is going to do you a favor.  When it sends SIGTERM or SIGHUP it follows
it with a SIGCONT.  The "problem" that the shell is trying to solve is
that a signal sent to a stopped process won't get processed until the
process resumes -- since you apparently wanted the process to die, the
shell sends a SIGCONT just to make sure the process will be able to get
to your signal right away.  Wrong answer.  It doesn't solve the problem
in general for all signals, and it creates about as much confusion as
it tries to avoid.

The solution is don't catch SIGCONT.  Your SIGTSTP handler knows when
the program resumes anyway because the line after the "kill" which
caused it to suspend itself will not be reached until the program is
resumed.  Taking the code you have for SIGCONT, and putting it there
is the "normal" way to do things.

Richard M. Mathews			 Freedom for Lithuania
richard@locus.com				Laisve!
lcc!richard@seas.ucla.edu
...!{uunet|ucla-se|turnkey}!lcc!richard

src@scuzzy.in-berlin.de (Heiko Blume) (02/14/91)

richard@locus.com (Richard M. Mathews) writes:
>The solution is don't catch SIGCONT.  Your SIGTSTP handler knows when
>the program resumes anyway because the line after the "kill" which
>caused it to suspend itself will not be reached until the program is
>resumed.

which fails miserably when you get the uncatchable SIGSTOP.
*yes*, i do use SIGSTOP, there are programs that disable
the SIGTSTP feature, and i won't let those go unsuspended.
-- 
      Heiko Blume <-+-> src@scuzzy.in-berlin.de <-+-> (+49 30) 691 88 93
                    public source archive [HST V.42bis]:
        scuzzy Any ACU,f 38400 6919520 gin:--gin: nuucp sword: nuucp
                     uucp scuzzy!/src/README /your/home

allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (02/15/91)

As quoted from <7103@fs1.cam.nist.gov> by coleman@cam.nist.gov (Sean Sheridan Coleman X5672):
+---------------
| Please explain to me why a SIGCONT is sent to a process after
| SIGTERM is sent to my process. It doesn't compute because TERM
+---------------

Being suspended, it wouldn't execute the signal handler unless it were
continued.  Also, I think the exit processing in the kernel needs this.
(So why does the SIGCONT handler run after the SIGTERM handler?  Because
signal handlers are invoked in signal-number order.)

++Brandon
(BSD folks feel free to correct me.)
-- 
Me: Brandon S. Allbery			    VHF/UHF: KB8JRR on 220, 2m, 440
Internet: allbery@NCoast.ORG		    Packet: KB8JRR @ WA8BXN
America OnLine: KB8JRR			    AMPR: KB8JRR.AmPR.ORG [44.70.4.88]
uunet!usenet.ins.cwru.edu!ncoast!allbery    Delphi: ALLBERY

lm@slovax.Eng.Sun.COM (Larry McVoy) (02/21/91)

In article <2588@inews.intel.com> bhoughto@hopi.intel.com (Blair P. Houghton) writes:
>In article <10007@dog.ee.lbl.gov> torek@elf.ee.lbl.gov (Chris Torek) writes:
>>Signals are not queued.
>
>Something's stacking them up.
>
>[description of the delayed receipt of a signal]

There is a one deep stack for signals.  I think that Chris meant to say that
multiple instances of the same signal will all get coalesced into one as
long as the signal has not yet been delivered.

Think of Unix as a virtual processor, system calls are instructions, and
signals are interrupts.  In a processor, noone stacks interrupts.  The
only promise is that one of N will get delivered, N - 1 are all lost.
---
Larry McVoy, Sun Microsystems     (415) 336-7627       ...!sun!lm or lm@sun.com