c - 编写我自己的 shell - 无法正确处理 ctrl+c (SIGINT)

标签 c linux bash shell signal-handling

我正在编写自己的简单 shell。我需要做的一件事是通过保留在 shell 中并在按下 ctrl+c 时在新行上打印提示来控制 SIGINT 信号。目前,我已经能够处理该信号,并且 shell 在提示后简单地打印 ^C 。但是,光标仍保留在同一行上。我想做的是让 shell 在提示符后打印 ^C,移至下一行,然后打印新的提示符。

我找到了this question ,它解决了完全相同的问题。我的问题是我的 main 调用另一个运行提示循环的函数。我尝试了许多不同的方法来尝试在主循环函数和提示循环函数中实现上面链接中给出的解决方案,但都没有运气。这是到目前为止我的代码:

Main.c

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "MyShell.h"

void ctrl_C_handler();

int main(int argc, char **argv) {

    signal(SIGINT, ctrl_C_handler);
    my_shell_loop();

    return EXIT_SUCCESS;
}

void ctrl_C_handler() { 
    //Catches the SIGINT signal fine without anything happening in this function
    //I cannot figure out how to have MyShell print a fresh prompt on a new line 
    //after ctrl+C is pressed
}

MyShellLoop.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "MyShell.h"

char *get_time();

void my_shell_loop() {
    char *line;
    char **args;
    int status;

    char *prompt = (char *) malloc(17);

    do {
        strcpy(prompt, get_time());
        strcat(prompt, " # ");
        printf("%s", prompt);
        line = read_command();
        args = split_command(line);
        status = execute_command(args);

        free(line);
        free(args);
    } while (status);

    free(prompt);
}

编辑

使用:

void ctrl_C_handler() { 
    signal(SIGINT, ctrl_C_handler);
    printf("\n");
    my_shell_loop();
}

第一次按下 ctrl+c 时会按照需要的方式进行操作,但之后再按下 ctrl+c 时会按照之前的方式进行操作。

最佳答案

signal仅为收到的第一个适当信号附加处理程序。调用之后,处理程序将被分离。一种常见的方法是让处理程序重新附加自身,如 int foo() { signal(SIGINT, &foo); do_the_stuff(); } 中所示。 .

但是, signal is non-portable 。 POSIX 建议使用 sigaction 相反。

关于c - 编写我自己的 shell - 无法正确处理 ctrl+c (SIGINT),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36319350/

相关文章:

java - 通过 Dijkstra 算法中私有(private)方法的 JUnit 测试用例

bash - 在 slurm 处理的 bash 脚本中评论

c - X86 中的 C 函数需要多少堆栈和堆(以字节为单位)

C 指针 - 交换

c - 从 C 列出 Linux 中的目录

linux - 我如何并行grep

c - 获取已安装程序的编译信息

linux - 使用 bash 遍历文件(和目录)名称

Daemon 可以使用 STDOUT 启动外部进程吗?

linux - 将 Git 同步到服务器