Shell CTRL-C忽略

时间:2016-01-25 15:46:14

标签: c linux bash shell signals

我想在shell的实现中使用以下内容。

启动shell时,会打印提示。当我单击 CTRL + C 时,它应忽略该信号并在新行上打印提示。按下没有输入键。

当我启动像top这样的外部程序时,我应该能够用 CTRL + C 杀死它并返回我的shell。

最后,当我启动像'python'这样的程序时,我想能够点击 CTRL + C 并且只能接收KeyboardInterrupt和>>印在新线上,如同真实的外壳。目前,我明白了:

Shell> python
Type "help", "copyright", "credits" or "license" for more information.
>>>
Shell>
KeyboardInterrupt
>>>
Shell>
KeyboardInterrupt
>>>
Shell>
KeyboardInterrupt
>>>

你可以在哪里看到Shell>打印在 CTRL + C 中断的中间。相关的代码摘录是:

void signal_handler(int dummy) {
    #ifdef DEBUG
        printf("CTRL-C is disabled.\n");
    #endif
    printf("\n");
}

int main(int argc, char **argv) {
    char *command;
    char **args;
    int status;

    /* Register a signal handler for Ctrl-C */
    sigset(SIGINT, signal_handler);

    while (1) {
        printf("Shell> ");
        command = read_command();
        args = tokenize_command(command);
        status = execute(args);

        #ifdef DEBUG
            printf("The newest status code was: %d\n", status);
        #endif

        free(command);
        free(args);
    }
}

1 个答案:

答案 0 :(得分:2)

您必须为执行的命令创建一个新的进程组,并将其作为前台进程组。

即。在子进程中fork()execve()之间:

setpgid(0, 0);
tcsetpgrp(fileno(stdin), getpgrp());

当子进程终止并且shell中的waitpid()返回时,您必须重置前台进程组:

tcsetpgrp(fileno(stdin), getpgrp()); // Called in the shell main process

说明:前台进程组中的进程可以从终端读取并从键盘输入接收信号( Ctrl - C Ctrl - Z 等)。当shell执行新命令时,它仍然与shell处于同一进程组中,而shell也是前台进程组。因此,您必须为执行的命令(setpgid)创建一个新的进程组,并使其成为前台进程组(tcsetpgrp)。