【发布时间】:2016-01-08 23:19:23
【问题描述】:
我正在用 C 编写一个简单的 shell。
但是,我发现我的程序无法正确处理 Ctrl+Z 信号。我的程序如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
void interpreter() {
char input[256];
int i;
char dir[PATH_MAX+1];
char *argv[256];
int argc = 0;
char *token;
if (getcwd(dir, PATH_MAX+1) == NULL) {
//error occured
exit(0);
}
printf("[shell:%s]$ ", dir);
fgets(input,256,stdin);
if (strlen(input) == 0) {
exit(0);
}
input[strlen(input)-1] = 0;
if (strcmp(input,"") == 0) {
return;
}
token = strtok(input, " ");
while(token && argc < 255) {
argv[argc++] = token;
token = strtok(NULL, " ");
}
argv[argc] = 0;
pid_t forknum = fork();
if (forknum != 0) {
int status;
waitpid(forknum, &status, WUNTRACED);
} else {
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTSTP, SIG_DFL);
setenv("PATH","/bin:/usr/bin:.",1);
execvp(argv[0], argv);
if (errno == ENOENT) {
printf("%s: command not found\n", argv[0]);
} else {
printf("%s: unknown error\n", argv[0]);
}
exit(0);
}
}
int main() {
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
while(1) {
interpreter();
}
}
我在主进程中忽略了上述信号。
当我启动cat(1) 然后点击Ctrl+Z 时,下一行输入仍将被cat(1) 程序而不是我的主进程捕获.这意味着我的主进程什么也不做,但如果我唤醒cat(1) 程序,它将立即输出我输入的内容。此后一切恢复正常。
我不知道如何解决这个问题。我还不确定我是否说清楚了。
【问题讨论】:
-
这很不清楚:下一行输入仍然会转到 cat 而不是我的 main...
-
让我举个例子。猫程序暂停后,我输入“猫”,应该启动另一只猫但没有任何反应。如果我唤醒之前的cat程序,它会立即输出“cat”。
-
你能发布完整的代码、预期的行为和你得到的行为吗?
-
@FilipeGonçalves 我已经发布了完整的代码。输入:“cat”“ctrl-d”“cat”,预期行为:一只猫开始然后暂停,一只新猫开始,现在行为:一只猫开始然后暂停。
-
吹毛求疵:没有
Ctrl-Z信号之类的东西。Ctrl-Z只是一个普通的键盘组合,让终端设备驱动发送SIGTSTP到前台进程组;但它可以作为终端设置的一部分进行更改(请参阅tcsetattr(3))。