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, sigdelsetsigprocmasksigactionsigsuspendkill, waitopen, 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