Exit read listening when pressing "Ctrl + c" in C

时间:2017-03-22 18:50:27

标签: c stdout stdin ctrl

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 !

1 个答案:

答案 0 :(得分:0)

不要将EOF视为可以' 打印到stdout '的字符,这是一个状态,文件句柄可以在,它意味着没有更多的数据。要将stdout置于EOF州,您必须致电close() - 这很可能不是您想要的。

注意 - 0x04实际上是EOT,传输结束。

在任何情况下,您为什么要将EOT发送到您应用的stdout?如果它的行为方式与您认为的那样,那么终端模拟器(或连接到您的标准输出的任何东西)将会退出 - 而不是您的shell,并且它肯定不会将您的shell恢复为' 等待更多输入'陈述' 等待输入'状态。

您需要处理信号处理程序中的^C,并适当调整shell的状态,让它放弃当前的输入模式并重绘基本提示。

修改:你需要记住的是你的贝壳'正在将文本(输出)和控制字符写入终端模拟器 - 终端模拟器正在将文本(输入)和控制字符写入“shell”。

如果您要将提示从dquote>还原为mysh$,那么必须通过向其发送新提示来更新终端。

要跟踪您当前正在做的事情,最有必要使用State Machine方法。您可能有一些州,包括:

  1. INPUT_WAITING
  2. INPUT_WAITING_CONT
  3. COMMAND_RUN
  4. 当处于INPUT_WAITING状态时,您将打印mysh$提示符并处理输入。 收到换行后,您会决定 我们是否拥有所有信息?'在没有进入INPUT_WAITING_CONT状态之前,或者如果你进入COMMAND_RUN状态。

    INPUT_WAIT_CONT州会打印出dquote>提示,并采取类似行动...... '我们是否有足够的信息?'是的:COMMAND_RUN,否:INPUT_WAIT_CONT

    然后,当用户按下INPUT_WAIT或命令执行完成时,您将恢复到mysh$状态并重新绘制^C提示符。< / p>