From d2bec49931decfd893c03c28382816cac28ed59e Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Tue, 15 Jun 2021 16:59:24 -0400 Subject: [PATCH] Send PINGs when server is quiet and die if no response Every time we receive from the server, reset a timer. The first time the timer triggers, send a PING. The second time the timer triggers, die from ping timeout. I'm not sure about these two intervals: 2 minutes of idle before a PING, 30s for the server to respond to the PING. --- chat.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/chat.c b/chat.c index 9332ca8..15142e6 100644 --- a/chat.c +++ b/chat.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -329,6 +330,7 @@ int main(int argc, char *argv[]) { uiInitLate(); signal(SIGHUP, signalHandler); signal(SIGINT, signalHandler); + signal(SIGALRM, signalHandler); signal(SIGTERM, signalHandler); signal(SIGCHLD, signalHandler); sig_t cursesWinch = signal(SIGWINCH, signalHandler); @@ -348,6 +350,7 @@ int main(int argc, char *argv[]) { fcntl(execPipe[1], F_SETFD, FD_CLOEXEC); } + bool ping = false; struct pollfd fds[] = { { .events = POLLIN, .fd = STDIN_FILENO }, { .events = POLLIN, .fd = irc }, @@ -367,6 +370,25 @@ int main(int argc, char *argv[]) { if (signals[SIGHUP]) self.quit = "zzz"; if (signals[SIGINT] || signals[SIGTERM]) break; + if (nfds > 0 && fds[1].revents) { + ping = false; + struct itimerval timer = { + .it_value.tv_sec = 2 * 60, + .it_interval.tv_sec = 30, + }; + int error = setitimer(ITIMER_REAL, &timer, NULL); + if (error) err(EX_OSERR, "setitimer"); + } + if (signals[SIGALRM]) { + signals[SIGALRM] = 0; + if (ping) { + errx(EX_UNAVAILABLE, "ping timeout"); + } else { + ircFormat("PING nyaa\r\n"); + ping = true; + } + } + if (signals[SIGCHLD]) { signals[SIGCHLD] = 0; for (int status; 0 < waitpid(-1, &status, WNOHANG);) {