我正在用 C 重写 shell,但遇到了一个问题。
在编写命令时 - 例如 echo "this
- 我们收到一个新提示(在 zsh 中为“dquote>”),我们可以使用“Ctrl + c”退出它并返回到我们最后的命令提示符。
我被困在那里了;我只是无法退出我的读取功能(听“dquote>”),我尝试在按“ctrl + c”时在标准输出上写入 EOF,但它没有读取它。
我切换到非规范模式。
我用 signal(SIGINT, sig_hand);
然后我在捕获信号时执行这部分代码:
static void sig_hand(int sig)
{
if (g_shell.is_listen_bracket) // if is the first prompt or no
putchar(4); // EOT
else
{
putstr("\n");
print_prompt();
}
}
和我的阅读功能:
int j;
char command[ARG_MAX];
char buff[3];
j = -1;
while (1)
{
bzero(buff, 3);
read(0, buff, 3);
if (buff[0] == 4 && !buff[1] && !buff[2])
return (ctrl_d(shell));
else if (isprint(buff[0]) && !buff[1] && !buff[2]) // if is between 32 and 126 (ascii)
{
command[++j] = buff[0];
putchar(buff[0]);
}
}
command[++j] = '\0';
return (strdup(command));
所以我的代码等待“read(0, buff, 3);”,我想在按 ctrl + c 时退出它。
感谢您的帮助!
最佳答案
不要将 EOF
视为可以“打印到 stdout
”的字符,它是文件处理的一种状态可以进入,这意味着没有更多数据传入。要将您的 stdout
置于 EOF
状态,您必须调用 close()
- 这很可能不是您想要的。
注意 - 0x04
实际上是 EOT
,即传输结束。
无论如何,您为什么要将 EOT
发送到应用程序的 stdout
?如果它的行为方式与您想象的一样,那么终端仿真器(或连接到标准输出的任何东西)将退出 - 而不是您的 shell,并且它肯定不会从“等待”恢复您的 shell更多输入”状态到“等待输入”状态。
您需要在信号处理程序中处理^C
,并适当调整shell的状态,使其放弃当前的输入模式并重新绘制基本提示符。
编辑:您需要记住的是,您的“shell”正在将文本(输出)和控制字符写入终端模拟器 - 终端模拟器正在将文本(输入)和控制字符写入到你的“外壳”。
如果您想将提示从 dquote>
恢复为 mysh$
,那么您必须通过编写新的提示来更新终端它。
要跟踪您当前正在做什么,使用 State Machine 可能最有意义。方法。您可能有几个州,包括:
INPUT_WAITING
INPUT_WAITING_CONT
COMMAND_RUN
当处于INPUT_WAITING
状态时,您将打印mysh$
提示,并处理输入。
当收到换行符时,您需要决定“我们是否拥有所有信息?”,如果没有,则进入 INPUT_WAITING_CONT
状态,或者进入 COMMAND_RUN
说明是否这样做。
INPUT_WAIT_CONT
状态将打印出 dquote>
提示,并采取类似的操作...“我们有足够的信息吗?”是:COMMAND_RUN
,否:INPUT_WAIT_CONT
。
然后,当用户按 ^C
或当命令执行完成。
关于c - 在C中按 "Ctrl + c"时退出读监听,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42960298/