Я хочу попросить ОС автоматически перезапустить все системные вызовы (например, open, read, write и т. Д.) При ошибке EINTR в Linux (Android), как это работает в BSD. Я нашел sigaction с флагом SA_RESTART . Теперь, если я правильно понимаю, я должен включить флаг SA_RESTART для каждого обработчика сигнала в системе, кроме ( SIGKILL и SIGSTOP ). Вот мое решение:
auto EnableBSDStyleSyscallRestartOnEINTR = [](int sig) -> bool {
int status;
struct sigaction act;
status = sigaction(sig, nullptr, &act);
if (status == -1) {
LoggerError("error get sigaction for signal: %d", sig);
return false;
}
if (act.sa_flags & SA_RESTART) {
return true;
}
act.sa_flags |= SA_RESTART;
status = sigaction(sig, &act, nullptr);
if (status != 0) {
LoggerError("can't update sigaction for signal: %d", sig);
return false;
}
return true;
};
const auto listOfSignals = {
SIGHUP,
SIGINT,
SIGQUIT,
SIGILL,
SIGTRAP,
SIGABRT,
SIGIOT,
SIGBUS,
SIGFPE,
// SIGKILL - do not use with sigaction http://man7.org/linux/man-pages/man2/sigaction.2.html
// SIGUSR1
SIGSEGV,
// SIGUSR2
SIGPIPE,
SIGALRM,
SIGTERM,
SIGSTKFLT,
SIGCHLD,
SIGCONT,
// SIGSTOP - do not use with sigaction http://man7.org/linux/man-pages/man2/sigaction.2.html
SIGTSTP,
SIGTTIN,
SIGTTOU,
SIGURG,
SIGXCPU,
SIGXFSZ,
SIGVTALRM,
SIGPROF,
SIGWINCH,
SIGIO,
SIGPWR,
SIGSYS,
SIGSWI
};
bool all_good = true;
for (int sig : listOfSignals) {
all_good &= EnableBSDStyleSyscallRestartOnEINTR(sig);
}
assert(all_good);
Правильно ли мое решение? Могу ли я найти более простое или элегантное решение? Заранее спасибо.