Lecture 28 – Nov 15th, 2019
Setup
- Log in to clyde.
- Copy
~steve/ex/sig
to your home directory.
Task
cd
intosig
and look atblock.c
. It installs a signal handler forSIGINT
, masksSIGINT
, sleeps for three seconds, and then unmasksSIGINT
.Run
$ make
to compileblock
. Run$ ./block
and let it sit until it exits. Nothing should be printed.Run it again, but this time, press
ctrl-C
a few times while it is sleeping. See how many times the message printed from the signal handler happens. (Note that although we cannot useprintf(3)
from a signal handler, we can usewrite(2)
.)Now, take a look at
sig.c
. Modify the code such that whenctrl-C
is pressed,interrupt_count
is incremented and whenctrl-\
is pressed (which sendsSIGQUIT
),done
is set to1
to exit the loop. Make sure to uncomment the loop.To do this, you’ll need to use
sigaction(2)
twice to install a signal handler forSIGINT
andSIGQUIT
. You can use the same function or two different functions. I suggest copying the relevant code fromblock.c
.- Build and run
./sig
. Try pressingctrl-C
a few times and then pressctrl-\
. It should print the number of times you pressedctrl-C
. - Run
./block
in a short loop$ for i in {1..3}; do ./block; done
and press
ctrl-C
while it is running.You’ll notice that after
SIGINT
is unmasked and the program exits, thefor
loop keeps running andblock
will be run again. This is because the signal handler caught and handled the signal so Bash didn’t know that it had exited due to a signal. Change the
sa_flags
to beSA_RESTART | SA_RESETHAND
. This will reset the signal handler to the default behavior as soon as the signal is delivered to the handler.Add
raise(sig)
at the end of the handler to raise the signal again.Rerun the loop from part 4 above and press
ctrl-C
. This time, it should exit immediately.