Lab 3 — Signals, Signal Masks, and Signal Handling
CMPS 3600 • Fall 2025
CMPS 3600 • Fall 2025
This lab introduces POSIX signals on Linux: basic signal handling, signal masks, and using
kill(2)
to generate signals between a parent and child process.
You’ll practice registering handlers with sigaction
, masking with sigprocmask
/sigset_t
, and synchronizing with sigsuspend
.
sigaction
(POSIX interface).sigfillset
, sigdelset
).sigprocmask
.sigsuspend
to atomically swap a mask and wait for a signal.kill
and reason about race conditions and deadlock.startstop.c
; POSIX signal handling; week 3 examplesUse man 7 signal, man 2 sigaction, man 2 kill, etc.
$ cd ~
$ cd cs3600
$ ./lab-start.sh
$ cd 3
$ cp /home/fac/dfanucchi/public_html/cs3600/examples/3/*.c .
$ cp /home/fac/dfanucchi/public_html/cs3600/examples/3/Makefile .
$ make
Read the headers and comments in each example; run them as directed to build intuition before coding vrlab3.c
.
vrlab3.c
)Create the vrlab3.c file, it is not included this week.
Your program forks one child. The child logs messages around a sigsuspend
wait; the parent sends SIGTERM
then SIGUSR1
to the child, and waits for the child to exit.
sigfillset
, sigdelset
sigprocmask
sigaction
sigsuspend
kill
, wait
open
, write
, close
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
sigset_t mask
; fill it with all signals via sigfillset
.sigprocmask(SIG_BLOCK, &mask, ...)
.SIGUSR1
handler using sigaction
before fork()
.fork()
a child.
log
, write "Go CSUB"
, prepare a mask that blocks all signals except SIGUSR1
(sigdelset(&unblock_usr1, SIGUSR1)
), then call sigsuspend(&unblock_usr1)
. In the handler, append " (got the signal) "
to the log and return. After sigsuspend
returns, write "Roadrunners!"
, close the log, and exit(0)
.SIGTERM
then SIGUSR1
to the child via kill
, then wait(&status)
. Print the child’s exit status.SIGUSR1
during sigsuspend
. If the child never unmasks SIGUSR1
, the parent and child will deadlock (parent waits in wait()
; child waits for a blocked signal).$ make
$ ./vrlab3
child terminated with code 0
$ cat log
Go CSUB (got the signal) Roadrunners!
strace
$ strace -e trace=signal -f ./vrlab3 2> err
child terminated with code 0
$ cat err
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], NULL, 8) = 0
rt_sigaction(SIGUSR1, {0x400ba5, ~[RTMIN RT_1], SA_RESTORER|SA_RESTART, 0x7fdbcbbd21e0}, NULL, 8) = 0
Process [CHILD pid] attached
[pid PARENT] kill(CHILD, SIGTERM) = 0
[pid PARENT] kill(CHILD, SIGUSR1) = 0
Process [PARENT pid] suspended
[pid CHILD ] rt_sigsuspend(~[USR1 RTMIN RT_1]) = ? ERESTARTNOHAND (To be restarted_
[pid CHILD ] --- SIGUSR1 --- (User defined signal 1) @ 0 (0) ---
[pid CHILD ] rt_sigreturn(0x3) = -1 EINTR (Interrupted system call)
Process [PARENT pid] resumed
Process [CHILD pid] detached
$ cat log
Go CSUB (got the signal) Roadrunners!
rt_sigaction(2)
, rt_sigpending(2)
, rt_sigprocmask(2), rt_sigreturn(2)
, rt_sigsuspend(2)
, rt_sigtimedwait(2)
. Don't be concerned about realtime signals for this lab.~/cs3600/3/vrlab3.c
~/cs3600/3/Makefile