【问题标题】:Catch CTRL-\ signal捕捉 CTRL-\ 信号
【发布时间】:2015-11-13 23:27:43
【问题描述】:

我有一个用户定义的 shell 项目,我正在尝试实现 cat 命令,但允许用户单击 CTRL-/ 以显示下一个 x 行。我是信号新手,所以我认为我在某处有一些语法错误......

在主...

    while (fgets(buf, sizeof(buf), file) != NULL){ //CITE
        //print out first four lines
        if (j == 0){
          for (i = 0; i < 4; i++){
            printf("%s", buf);
            fgets(buf, sizeof(buf), file);
          }
          j++;
        }
        signal(SIGQUIT, sig_int);
        //now check for user input for the next x lines
        if (keepRunning){
          for (i = 0; i < 4; i++){
            printf("%s", buf);
            if (i < 3){
              if (fgets(buf, sizeof(buf), file) == NULL){
                fclose(file);
                return 0;
              }
            }
          }
          keepRunning = 0;
        }

然后我定义了以下 sig_int 函数...

static volatile int keepRunning = 0;
void sig_int(int sig){
  keepRunning = 1;
}

【问题讨论】:

  • 唯一的问题是,在没有收到信号的情况下,您不会在任何地方减速或停下来。例如,您可以使用pause();它仅在收到信号时返回。然后,您将使用它来代替 if (keepRunning) 块(包括条件)。您可能希望让其他信号唤醒程序并退出循环,但如果您不为它们设置信号处理程序,这将自动发生。也就是说,在pause() 返回后(它总是返回错误状态并且errno 设置为EINTR),您可以检查keepRunning 现在是否为1,如果不是则退出循环。
  • 太棒了!谢谢!但是现在每次输入 CRTL-\ 后都会打印 `^`,有没有办法防止这种情况发生?
  • 可能是stty -echoctl。这是终端驱动问题,不是程序问题。
  • 我可以从其他帖子中看到,但该代码应该放在哪里?
  • 我建议:stty -echoctl; ./your_program; stty echoctl。或者决定您不需要回显控制字符并在您的.profile 或等效项中执行stty -echoctl。

标签: c if-statement signals interrupt ctrl


【解决方案1】:

主要问题是当没有收到信号时,您不会在任何地方减速或停下来。例如,您可以使用pause();它仅在收到信号时返回。然后,您将使用它来代替 if (keepRunning) 块(包括条件)。

或者,您可以修改终端模式,以便在输入字符时发送字符(“原始”模式),并在继续之前尝试读取字符。但是,如果您这样做,您有责任确保在尽可能多的情况下程序退出之前重置终端模式。好消息是在 raw 模式下键盘不会产生任何信号,但您必须担心来自其他地方的信号。

您可能希望让其他信号唤醒程序并退出循环,但如果您不为它们设置信号处理程序,这将自动发生。也就是说,在pause() 返回后(它总是返回错误状态并且errno 设置为EINTR),您可以检查keepRunning 现在是否为1,如果不是则退出循环。

【讨论】:

    猜你喜欢
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多