Почему kill () - SIGCONT не перезапускает приостановленный процесс? - PullRequest
0 голосов
/ 23 апреля 2020

Я пытаюсь построить свою раковину. Вот один из сценариев: я ввожу команду «sleep 10», работающую на переднем плане, и нажимаю Ctrl-z, чтобы остановить ее и перевести в фоновый режим. После того, как я поставил команду "ls &" в фоновом режиме, теперь есть два задания в фоновом режиме, я добавил kill () -SIGCONT, чтобы возобновить "sleep 10", но ничего не происходит. есть идеи?

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
#include <sys/mman.h>

sigset_t mask_all, mask_one, prev_one;

pid_t pid = 0;

void handler()
{   
    //int olderrno = errno;
    sigset_t mask_all, prev_all;
    sigfillset(&mask_all);

    pid_t pid;
    int status;
    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
        sigprocmask(SIG_BLOCK, &mask_all, &prev_all);
        if(pid == -1)
            printf("handler-pid: %d has been reaped\n, no need again", pid);
        else
            printf("handler-pid: %d has been reaped\n", pid);
        sigprocmask(SIG_SETMASK, &prev_all, NULL);
    }
}
void send_signal(int signum)
{
    kill(pid, signum);
}

void init_signals()
{
    signal(SIGCHLD, handler);
    signal(SIGTSTP, send_signal);
}


void start_foreground_job(char** argv)
{   
    //signal(SIGCHLD, SIG_DFL);


    sigprocmask(SIG_BLOCK, &mask_one, &prev_one);
    pid = fork();
    if(pid==0)
    {   
        sigprocmask(SIG_SETMASK, &prev_one, NULL);
        printf("This is child %d\n", pid);
        setpgid(0,0);
        signal(SIGTSTP, SIG_DFL);

        if((execve(argv[0], argv, NULL))<0)//envp
        {
            fprintf(stderr, "%s: Command not found.\n", argv[0]);
            exit(0);
        }
    }
    sigprocmask(SIG_SETMASK, &prev_one, NULL);
    pause();
    //printf("pid: %d was stopped\n", p);

}

void start_background_job(char** argv)
{   
    //signal(SIGCHLD, handler);

    sigprocmask(SIG_BLOCK, &mask_one, &prev_one);
    if( fork() ==0)
    {   
        //printf("%d\n", getpid());
        sigprocmask(SIG_SETMASK, &prev_one, NULL);
        printf("This is child %d\n", getpid());
        setpgid(0,0);
        signal(SIGTSTP, SIG_DFL);

        if((execve(argv[0], argv, NULL))<0)
        {
            fprintf(stderr, "%s: Command not found.\n", argv[0]);// discard all changed!!!
            exit(0);
        }
    }
    //sigprocmask(SIG_BLOCK, &mask_all, NULL);
    sigprocmask(SIG_SETMASK, &prev_one, NULL);
}


int main()
{
    init_signals();

    sigfillset(&mask_all);
    sigemptyset(&mask_one);
    sigaddset(&mask_one, SIGCHLD);

    pid_t stdin_PGID;

    setpgid(0,0);

        /* Get the PGIDs for stdin. */
    stdin_PGID = tcgetpgrp(STDIN_FILENO);
    if (stdin_PGID == -1) {
        printf("Could not get PGID for stdin.n");
        return(EXIT_FAILURE);
    }
    else if (tcsetpgrp(STDIN_FILENO, stdin_PGID) == -1) {
        printf("Could not set PGID.n");
        return(EXIT_FAILURE);
    }

    printf("The PGID has been changed to %d %d \n", stdin_PGID,getpgid(getpid()));


    printf("my prompt> \n");

    char* argv1[] = {"/bin/sleep", "5", NULL};

    start_foreground_job(argv1);

    printf("my prompt> \n");

    char* argv2[] = {"/bin/ls", NULL};

    start_background_job(argv2);

    printf("stopped child %d\n", pid);
    kill(pid,SIGCONT);

    sleep(1);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...