Handle signals consistently in the event loop
parent
9d769111ae
commit
414f928ac5
3
chat.h
3
chat.h
|
@ -20,6 +20,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdnoreturn.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ void selfJoin(const char *join);
|
||||||
|
|
||||||
void eventWait(const char *argv[static 2]);
|
void eventWait(const char *argv[static 2]);
|
||||||
void eventPipe(const char *argv[static 2]);
|
void eventPipe(const char *argv[static 2]);
|
||||||
void eventLoop(void);
|
noreturn void eventLoop(void);
|
||||||
|
|
||||||
struct Tag {
|
struct Tag {
|
||||||
size_t id;
|
size_t id;
|
||||||
|
|
49
event.c
49
event.c
|
@ -14,16 +14,18 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdnoreturn.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "chat.h"
|
#include "chat.h"
|
||||||
|
|
||||||
|
@ -86,8 +88,7 @@ static void pipeRead(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sigchld(int sig) {
|
static void handleChild(void) {
|
||||||
(void)sig;
|
|
||||||
int status;
|
int status;
|
||||||
pid_t pid = wait(&status);
|
pid_t pid = wait(&status);
|
||||||
if (pid < 0) err(EX_OSERR, "wait");
|
if (pid < 0) err(EX_OSERR, "wait");
|
||||||
|
@ -99,16 +100,31 @@ static void sigchld(int sig) {
|
||||||
spawn.wait = false;
|
spawn.wait = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sigint(int sig) {
|
static void handleInterrupt(void) {
|
||||||
(void)sig;
|
|
||||||
input(TagStatus, "/quit");
|
input(TagStatus, "/quit");
|
||||||
uiExit();
|
uiExit();
|
||||||
exit(EX_OK);
|
exit(EX_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventLoop(void) {
|
static sig_atomic_t sig[NSIG];
|
||||||
signal(SIGINT, sigint);
|
static void handler(int n) {
|
||||||
signal(SIGCHLD, sigchld);
|
sig[n] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
noreturn void eventLoop(void) {
|
||||||
|
sigset_t mask;
|
||||||
|
sigemptyset(&mask);
|
||||||
|
struct sigaction sa = {
|
||||||
|
.sa_handler = handler,
|
||||||
|
.sa_mask = mask,
|
||||||
|
.sa_flags = SA_RESTART,
|
||||||
|
};
|
||||||
|
sigaction(SIGCHLD, &sa, NULL);
|
||||||
|
sigaction(SIGINT, &sa, NULL);
|
||||||
|
|
||||||
|
struct sigaction curses;
|
||||||
|
sigaction(SIGWINCH, &sa, &curses);
|
||||||
|
assert(!(curses.sa_flags & SA_SIGINFO));
|
||||||
|
|
||||||
int irc = ircConnect();
|
int irc = ircConnect();
|
||||||
|
|
||||||
|
@ -118,6 +134,17 @@ void eventLoop(void) {
|
||||||
{ -1, POLLIN, 0 },
|
{ -1, POLLIN, 0 },
|
||||||
};
|
};
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
if (sig[SIGCHLD]) handleChild();
|
||||||
|
if (sig[SIGINT]) handleInterrupt();
|
||||||
|
if (sig[SIGWINCH]) {
|
||||||
|
curses.sa_handler(SIGWINCH);
|
||||||
|
uiRead();
|
||||||
|
uiDraw();
|
||||||
|
}
|
||||||
|
sig[SIGCHLD] = 0;
|
||||||
|
sig[SIGINT] = 0;
|
||||||
|
sig[SIGWINCH] = 0;
|
||||||
|
|
||||||
nfds_t nfds = 2;
|
nfds_t nfds = 2;
|
||||||
if (spawn.wait) nfds = 1;
|
if (spawn.wait) nfds = 1;
|
||||||
if (spawn.pipe) {
|
if (spawn.pipe) {
|
||||||
|
@ -127,10 +154,8 @@ void eventLoop(void) {
|
||||||
|
|
||||||
int ready = poll(fds, nfds, -1);
|
int ready = poll(fds, nfds, -1);
|
||||||
if (ready < 0) {
|
if (ready < 0) {
|
||||||
if (errno != EINTR) err(EX_IOERR, "poll");
|
if (errno == EINTR) continue;
|
||||||
uiRead();
|
err(EX_IOERR, "poll");
|
||||||
uiDraw();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fds[0].revents) ircRead();
|
if (fds[0].revents) ircRead();
|
||||||
|
|
Loading…
Reference in New Issue