Обработка сигналов UNIX.Подождите в обработчике SIGCHLD.С - PullRequest
2 голосов
/ 13 марта 2019

У меня есть родительские и дочерние процессы. В родительском я установил обработчик сигнала для SIGCHLD. Я посылаю SIGTSTP сигнал ребенку, что триггеры SIGCHLD и в обработчике SIGLLD SIGCHLD в родительском я вызываю функцию ожидания, чтобы получить статус остановленного ребенка. Но вместо того, чтобы немедленно вернуться, он блокируется. Затем я отправляю сигнал SIGCONT дочернему элементу, и ожидание возврата с ошибкой, установленной на системный вызов Interuppted. Я не могу понять, что мне не хватает.

pid_t pid;


static void sig_chld(int signo);


int main() {

    struct sigaction act, savechld;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;


    act.sa_handler = sig_chld;
    if (sigaction(SIGCHLD, &act, &savechld) < 0){
        return errno;
    }

    pid = fork();
    switch (pid){
        case -1:{
            perror("fork failed");
            return errno;
        }
        case 0:{    //child
            if (sigaction(SIGCHLD, &savechld, NULL) < 0)
                return errno;

            execlp(path, name_of_executable, (char*)NULL);
            return errno;
        }
        default:{
            for (;;)
                pause();
        }
    }
    return 0;
}



void sig_chld(int signo) {
    int statol;
    if (wait(&statol) < 0){
        perror("waitt error");
        exit(errno);
    }

    if (WIFSTOPPED(statol)){
        puts("Child is stopped");
    } else if (WIFEXITED(statol)){
        puts("Child exited");
    } else if (WIFCONTINUED(statol)){
        puts("Child continued");
    } else if (WIFSIGNALED(statol)){
        puts("Child is signaled");
        int sig = WTERMSIG(statol);
        psignal(sig, NULL);
    }
}

1 Ответ

5 голосов
/ 13 марта 2019

Вы должны использовать waitpid() вместо wait(), и вам нужно указать параметр WUNTRACED, чтобы также остановить детей, о которых сообщалось с waitpid(), например:

if (waitpid(-1, &statol, WUNTRACED) < 0) {

Сейчасwaitpid() должен немедленно вернуться, и ваш макрос WIFSTOPPED(&statol) должен быть верным.

...