代码之家  ›  专栏  ›  技术社区  ›  leanid.chaika

如何在Linux(Android)上启用与BSD兼容的系统调用在eIntr错误时重新启动(使用标志sa_restart)

  •  0
  • leanid.chaika  · 技术社区  · 6 年前

    我想让操作系统自动重启所有系统调用(比如open,read,write,等等…),就像在bsd中一样。我发现 sigaction 具有 重启 旗帜。如果我理解正确,我应该启用标志 重启 对于系统中的每个信号处理器,除了( 西格利克 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);
    
    

    我的解决方案正确吗?我有更简单或优雅的解决方案吗?提前谢谢。

    0 回复  |  直到 6 年前