简体   繁体   English

Shell CTRL-C忽略

[英]Shell CTRL-C ignore

I want to the following in my implementation of shell. 我要在我的Shell实施中执行以下操作。

When shell is launched, the prompt is printed. 启动外壳程序时,将显示提示。 When I click CTRL + C it should ignore the signal and print the prompt on new line. 当我单击CTRL + C时,它应该忽略该信号,并在新行上打印提示。 No enter key should pressed. 请勿按下回车键。

When I launch an external program like top, I should be able to kill it with CTRL + C and get back to my shell. 当启动诸如top之类的外部程序时,我应该能够使用CTRL + C杀死它并返回我的shell。

Finally, when I launch a program like 'python', I want to be able to click CTRL + C and only receive KeyboardInterrupt and >> printed on new line as in real shell. 最后,当我启动类似“ python”的程序时,我希望能够单击CTRL + C并只接收KeyboardInterrupt和>>印刷在新行中,就像在真正的shell中一样。 Currently, I get this: 目前,我得到这个:

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

Where you can see that Shell> is printed in the middle of CTRL + C interrupt. 您可以在其中看到Shell>在CTRL + C中断的中间打印。 A relevant excerpt of code is: 相关的代码摘录为:

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);
    }
}

You will have to create a new process group for your executed command and make it the foreground process group. 您将必须为执行的命令创建一个新的进程组,并使其成为前台进程组。

ie between fork() and execve() in the child process: 即在子进程中的fork()execve()之间:

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

When the child terminates and waitpid() in your shell returns, you have to reset the foreground process group: 当子进程终止并且shell中的waitpid()返回时,您必须重置前台进程组:

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

Explanation: The processes in the foreground process group may read from the terminal and receive the signals from keyboard-input ( Ctrl - C , Ctrl - Z , etc.). 说明:前台进程组中的进程可以从终端读取并从键盘输入( Ctrl - CCtrl - Z等)接收信号。 When a new command is executed by your shell, it is still in the same process group as the shell, which is also the foreground process group. 当外壳程序执行新命令时,它仍与外壳程序位于同一进程组中,该进程组也是前台进程组。 So you have to create a new process group for your executed command (setpgid) and make it the foreground process group (tcsetpgrp). 因此,您必须为执行的命令(setpgid)创建一个新的进程组,并使其成为前台进程组(tcsetpgrp)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM