in io/signal.cpp [148:230]
static int fire_signal(void*, EventLoop*)
{
#ifdef __APPLE__
int ret = kevent(sgfd, nullptr, 0, _events, LEN(_events), &tm);
if (ret <= 0) {
LOG_ERRNO_RETURN(0, 0, "SignalFD read failed");
}
for (int i = 0; i < ret; i++) {
if (_events[i].filter == EVFILT_SIGNAL) {
auto signum = _events[i].ident;
if (signum > SIGNAL_MAX)
LOG_ERROR_RETURN(EINVAL, -1, "signal number ` too big (` maximum)", signum, SIGNAL_MAX);
auto h = sighandlers[signum];
if (h == nullptr) continue;
if (!sigismember(&infoset, signum))
{
((sighandler_t)h)(signum);
} else {
siginfo_t siginfo;
memset(&siginfo, 0, sizeof(siginfo_t));
reinterpret_cast<decltype(sigaction::sa_sigaction)>(h)(signum, &siginfo, nullptr);
}
} else if (_events[i].flags & EV_ERROR) {
LOG_WARN("EV_ERROR found in events, data: `", _events[i].data);
}
}
return 0;
#else
struct signalfd_siginfo fdsi;
ssize_t ret = read(sgfd, &fdsi, sizeof(fdsi));
if (ret != sizeof(fdsi))
{
if (ret < 0)
LOG_ERRNO_RETURN(0, 0, "SignalFD read failed");
if (ret == 0) {
LOG_ERROR_RETURN(0, 0, "SignalFD readable happend but nothing to read");
} else {
LOG_ERROR_RETURN(0, 0, "SignalFD partial read");
}
}
auto no = fdsi.ssi_signo;
if (no > SIGNAL_MAX)
LOG_ERROR_RETURN(EINVAL, -1, "signal number ` too big (` maximum)", no, SIGNAL_MAX);
auto h = sighandlers[no];
if (h == nullptr)
return 0;
if (!sigismember(&infoset, no))
{
((sighandler_t)h)(no);
return 0;
}
siginfo_t siginfo;
#define ASSIGN(field) siginfo.si_##field = fdsi.ssi_##field
ASSIGN(signo);
ASSIGN(errno);
ASSIGN(code);
// ASSIGN(trapno);
ASSIGN(pid);
ASSIGN(uid);
ASSIGN(status);
ASSIGN(utime);
ASSIGN(stime);
// ASSIGN(value);
ASSIGN(int);
// ASSIGN(ptr);
siginfo.si_ptr = (void*)fdsi.ssi_ptr;
ASSIGN(overrun);
// ASSIGN(timerid);
// ASSIGN(addr);
siginfo.si_addr = (void*)fdsi.ssi_addr;
ASSIGN(band);
ASSIGN(fd);
// ASSIGN(addr_lsb);
#undef ASSIGN
reinterpret_cast<decltype(sigaction::sa_sigaction)>(h)(no, &siginfo, nullptr);
return 0;
#endif
}