在子进程中接收 SIGTSTP 信号,不同的子进程表现会有所不同?

huangapple go评论108阅读模式
英文:

enter SIGTSTP signal in child process, different child process behaves differently?

问题

I'm implement my own shell on MAC, in my own shell, when I enter "Control+Z" or "Control+C", it should ignores them. but when running the command such as "sleep 10" or "cat". It behaves as default.

However, in my implementation, it behaves weird.

void sig_handler(int signo) {
    if (signo == SIGINT || signo == SIGQUIT || signo == SIGTSTP)  {
       // ignores
    } else {
        // other signals, behaves default
        signal(signo, SIG_DFL);
        raise(signo);
    }
}

int main() {
    
    signal(SIGINT, sig_handler);
    signal(SIGTSTP, sig_handler);
    signal(SIGQUIT, sig_handler);

    while (1){
         printf(">> ");
         fflush(stdout);
          
         //parse the input; skip the code for simplicity
         cmd = parse_input();
         // for example, cmd = {"cat", NULL}; or cmd = {"sleep", "60", NULL}, or cmd = {"ls", NULL}

            pid_t child_pid;
            pid = fork();
            if (pid < 0) {
                perror("error: fork");
                exit(EXIT_FAILURE);
            }
            if (pid == 0) {
                child_pid = pid;
                execvp(cmds[0][0], cmds[0]);
                perror("error: exec");
                exit(EXIT_FAILURE);
            } else {
                int status;
                waitpid(child_pid, &status, WUNTRACED | WCONTINUED);
            }
         
    }

}

when I run the program with the following user input, it displays as follows

>> cat
^Z>> ls

>> 

I first enter cat, then enter Control+Z, the terminal goes back to waiting for user input. But when I enter ls next, it's supposed to list all files in the current directory, but it just shows a newline, and when I hit "return" again, it goes back to waiting for user input. Only then, it seems back to a normal shell prompt.

>> sleep 10
^Z>> ls
file1 file2 file3
>>

Instead of cat, we use sleep, and the program seems to handle "Control+Z" as expected.

Any help

英文:

I'm implement my own shell on MAC, in my own shell, when I enter "Control+Z" or "Control+C", it should ignores them. but when running the command such as "sleep 10" or "cat". It behaves as default.

However, in my implementation, it behaves weird.

void sig_handler(int signo) {
    if (signo == SIGINT || signo == SIGQUIT || signo == SIGTSTP)  {
       // ignores
    } else {
        // other signals, behaves default
        signal(signo, SIG_DFL);
        raise(signo);
    }
}

int main() {
    
    signal(SIGINT, sig_handler);
    signal(SIGTSTP, sig_handler);
    signal(SIGQUIT, sig_handler);

    while (1){
         printf(&quot;&gt;&gt; &quot;);
         fflush(stdout);
          
         //parse the input; skip the code for simplicity
         cmd = parse_input();
         // for example, cmd = {&quot;cat&quot;, NULL}; or cmd = {&quot;sleep&quot;, &quot;60&quot;, NULL}, or cmd = {&quot;ls&quot;, NULL}

            pid_t child_pid;
            pid = fork();
            if (pid &lt; 0) {
                perror(&quot;error:fork&quot;);
                exit(EXIT_FAILURE);
            }
            if (pid == 0) {
                child_pid = pid;
                execvp(cmds[0][0], cmds[0]);
                perror(&quot;error:exe&quot;);
                exit(EXIT_FAILURE);
            } else {
                int status;
                waitpid(child_pid, &amp;status, WUNTRACED | WCONTINUED);
            }
         
    }

}

when I run the program with the following user input, it displays as follows

&gt;&gt; cat
^Z&gt;&gt; ls

&gt;&gt; 

I first enter cat, then enter control+Z, the terminal goes back to waiting for use enter prompt. But when enter ls next, it supposed to list all files in current directory, but it just shows a newline, and when I hit "return again, it goes back to waiting for user to enter prompt. Only then, it seems back to normal shell prompt.

&gt;&gt; sleep 10
^Z&gt;&gt; ls
file1 file2 fil3
&gt;&gt;

instead of cat, we use sleep, the program seems handle "control+Z" as expected .

Any help

答案1

得分: 1

From the documentation of signals:

> During an execve(2), the dispositions of
handled signals are reset to the default; the dispositions of
ignored signals are left unchanged.

Since you're handling these signals with the sig_handler() function, they get reset to the default disposition when you do execvp(cmds[0][0], cmds[0]);. (How could it make sense not to reset them, since the function doesn't exist in the cat and ls programs?)

So you should ignore them, not handle them:

signal(SIGTSTP, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
英文:

From the documentation of signals:

> During an execve(2), the dispositions of
handled signals are reset to the default; the dispositions of
ignored signals are left unchanged.

Since you're handling these signals with the sig_handler() function, they get reset to the default disposition when you do execvp(cmds[0][0], cmds[0]);. (How could it make sense not to reset them, since the function doesn't exist in the cat and ls programs?)

So you should ignore them, not handle them:

    signal(SIGINT, SIG_IGN);
    signal(SIGTSTP, SIG_IGN);
    signal(SIGQUIT, SIG_IGN);

huangapple
  • 本文由 发表于 2023年3月8日 14:37:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/75670020.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定