diff options
Diffstat (limited to 'minecproxy/signal-handler.c')
-rw-r--r-- | minecproxy/signal-handler.c | 123 |
1 files changed, 63 insertions, 60 deletions
diff --git a/minecproxy/signal-handler.c b/minecproxy/signal-handler.c index ba92382..5369670 100644 --- a/minecproxy/signal-handler.c +++ b/minecproxy/signal-handler.c @@ -33,74 +33,77 @@ static void signalfd_read(struct uring_task *task, int res) struct signal_ev *signal = container_of(task, struct signal_ev, task); struct server *server, *stmp; static unsigned count = 0; - siginfo_t *si; + siginfo_t *sia, *si; assert_return(task); assert_task_alive(DBG_SIG, task); - si = (siginfo_t *)task->tbuf->buf; - if (res != sizeof(*si)) - die("error in signalfd (%i)", res); - - switch (si->si_signo) { - case SIGUSR1: { - struct dns_async *dns; - - debug(DBG_SIG, "Got a SIGUSR1"); - if (si->si_code != SI_ASYNCNL || !si->si_ptr) { - error("SIGUSR1: unexpected values in siginfo"); - goto out; - } - - dns = si->si_ptr; - if (!dns->cb) { - error("DNS callback not set"); - goto out; + if (res == 0 || res % sizeof(*si)) + die("error in signalfd (%i vs %zu)", res, sizeof(*si)); + + sia = (siginfo_t *)(task->tbuf->buf); + for (unsigned i = 0; i < res / sizeof(*si); i++) { + si = &sia[i]; + switch (si->si_signo) { + case SIGUSR1: { + struct dns_async *dns; + + debug(DBG_SIG, "Got a SIGUSR1"); + if (si->si_code != SI_ASYNCNL || !si->si_ptr) { + error("SIGUSR1: unexpected values in siginfo"); + goto out; + } + + dns = si->si_ptr; + if (!dns->cb) { + error("DNS callback not set (%p)", dns); + goto out; + } + + debug(DBG_DNS, "DNS lookup complete, dns: %p, dns->cb: %p", dns, + dns->cb); + dns->cb(dns); + break; } - debug(DBG_DNS, "DNS lookup complete, dns: %p, dns->cb: %p", dns, - dns->cb); - dns->cb(dns); - break; - } - - case SIGUSR2: - debug(DBG_SIG, "got a SIGUSR2"); - dump_tree(); - break; - - case SIGTERM: - debug(DBG_SIG, "Got a SIGINT/SIGHUP"); - verbose("got a signal to quit"); - sd_notifyf(0, "STOPPING=1\nSTATUS=Received signal, exiting"); - exit(EXIT_SUCCESS); - break; - - case SIGINT: - case SIGHUP: - count++; - if (count > 5) { + case SIGUSR2: + debug(DBG_SIG, "got a SIGUSR2"); dump_tree(); - exit(EXIT_FAILURE); + break; + + case SIGTERM: + debug(DBG_SIG, "Got a SIGINT/SIGHUP"); + verbose("got a signal to quit"); + sd_notifyf(0, "STOPPING=1\nSTATUS=Received signal, exiting"); + exit(EXIT_SUCCESS); + break; + + case SIGINT: + case SIGHUP: + count++; + if (count > 5) { + dump_tree(); + exit(EXIT_FAILURE); + } + + verbose("got a signal to dump tree"); + sd_notifyf(0, "STOPPING=1\nSTATUS=Received signal, exiting"); + dump_tree(); + signal_delete(); + ptimer_delete(); + igmp_delete(); + announce_delete(); + idle_delete(); + server_cfg_monitor_delete(); + list_for_each_entry_safe(server, stmp, &cfg->servers, list) + server_delete(server); + uring_delete(); + return; + + default: + error("got an unknown signal: %i", si->si_signo); + break; } - - verbose("got a signal to dump tree"); - sd_notifyf(0, "STOPPING=1\nSTATUS=Received signal, exiting"); - dump_tree(); - signal_delete(); - ptimer_delete(); - igmp_delete(); - announce_delete(); - idle_delete(); - server_cfg_monitor_delete(); - list_for_each_entry_safe(server, stmp, &cfg->servers, list) - server_delete(server); - uring_delete(); - return; - - default: - error("got an unknown signal: %i", si->si_signo); - break; } out: |