|
发表于 2023-10-8 18:04:39
|
显示全部楼层
首先,让我们分析一下你提供的代码。这段代码是一个简单的 shell 程序,它设置了一个信号处理函数 `sigint_handler` 来处理 `SIGINT` 信号(通常由 Ctrl+C 产生)。当接收到 `SIGINT` 信号时,`sigint_handler` 函数会打印一个换行符和 "myshell1> " 提示符。
问题是:为什么按下 Ctrl+C 后,只显示 "myshell1> ",而不显示 "myshell2> "?
这是因为在 `sigint_handler` 函数中,你已经打印了 "myshell1> " 提示符。当信号处理函数返回时,程序会继续执行 `main` 函数中被中断的系统调用。在这种情况下,`fgets` 函数被中断,因此它会返回一个错误。由于你设置了 `SA_RESTART` 标志,`fgets` 函数会自动重新启动,而不是返回错误。这意味着程序会继续等待用户输入,而不是执行下一行 `printf("myshell2> ")` 代码。
要解决这个问题,你可以在 `sigint_handler` 函数中设置一个全局变量,表示是否接收到了 `SIGINT` 信号。然后,在 `main` 函数中检查这个变量,如果接收到了信号,就打印 "myshell2> " 提示符。以下是修改后的代码:
- #include <stdio.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <unistd.h>
- #define MAX_ARGS 10
- volatile sig_atomic_t sigint_received = 0;
- void sigint_handler(int sig) {
- printf("\n");
- printf("myshell1> ");
- fflush(stdout);
- sigint_received = 1;
- }
- int main() {
- char *args[MAX_ARGS];
- char buffer[1024];
- int i, j, k, status;
- pid_t pid;
- // Set up signal handler for Ctrl+C
- struct sigaction sa;
- sa.sa_handler = sigint_handler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_RESTART;
- if (sigaction(SIGINT, &sa, NULL) == -1) {
- perror("sigaction");
- exit(1);
- }
- while (1) {
- if (sigint_received) {
- printf("myshell2> ");
- fflush(stdout);
- sigint_received = 0;
- } else {
- printf("myshell> ");
- fflush(stdout);
- }
- // Read the command line
- if (fgets(buffer, 1024, stdin) == NULL) {
- // Ctrl+D was pressed, exit the shell
- printf("\n");
- exit(0);
- }
- }
- }
复制代码
现在,当你按下 Ctrl+C 时,程序应该会显示 "myshell1> ",然后显示 "myshell2> "。 |
|