I'm rewriting a shell in C and I fell on a problem.
When writing a command — for example echo "this
— we got a new prompt ("dquote>", in zsh) and we can exit it with "Ctrl + c" and get back to our last command prompt.
I'm stuck there; I just can't get out of my read function (listen on "dquote>"), I tried to write on stdout an EOF when pressing "ctrl + c" but it doesn't read it.
I switched to non-canonical mode.
I catch signal with signal(SIGINT, sig_hand);
then i execute this part of code when signal is catched:
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();
}
}
and my read function:
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));
So my code waiting on "read(0, buff, 3);", and i want to quit it when pressing ctrl + c.
Thanks for helping !
答案 0 :(得分:0)
不要将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
。
然后,当用户按下INPUT_WAIT
或命令执行完成时,您将恢复到mysh$
状态并重新绘制^C
提示符。< / p>