linux-sysprog · intermediate · ~12 min
Combine handler + flag + main-loop check for clean termination.
Implement graceful shutdown: a SIGTERM handler that just sets a flag, and a work loop that checks that flag each iteration and stops cleanly when asked to.
Implement two functions:
int install_graceful_term(void);
int do_work_until_term(int max_iters);
install_graceful_term: no parameters. The global volatile sig_atomic_t g_shutdown is provided.do_work_until_term: max_iters, the maximum number of work iterations to run.install_graceful_term installs a SIGTERM handler that sets g_shutdown to 1. Returns 0 on success, -1 on failure.do_work_until_term runs up to max_iters iterations (one unit of work each), but stops early if g_shutdown is set. Returns the number of iterations actually completed (max_iters if no SIGTERM arrived, fewer otherwise).install_graceful_term() -> 0, g_shutdown == 0
do_work_until_term(5) -> 5 (no SIGTERM, ran fully)
raise(SIGTERM) -> g_shutdown == 1
do_work_until_term(100) -> 0 (flag already set, exits immediately)
g_shutdown is already set, the loop completes 0 iterations.max_iters.sigaction to install the handler; the handler must only set the flag.systemd sends SIGTERM, waits a grace period, then SIGKILL. Your service has one chance to clean up.
install_graceful_term takes nothing (uses the global g_shutdown); do_work_until_term takes max_iters.
install_graceful_term returns 0/-1; do_work_until_term returns the iterations completed before g_shutdown was set (max_iters if never set).
Handler sets g_shutdown = 1 only. The work loop checks g_shutdown each iteration and stops when set.
#include <signal.h>
#include <stdio.h>
volatile sig_atomic_t g_shutdown = 0;
int install_graceful_term(void) {
/* TODO */
return -1;
}
int do_work_until_term(int max_iters) {
/* TODO */
return -1;
}
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.