summaryrefslogtreecommitdiff
path: root/minecproxy/signal-handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'minecproxy/signal-handler.c')
-rw-r--r--minecproxy/signal-handler.c123
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: