首先,让我们分析一下你提供的代码。这段代码是一个简单的 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> "。 |