2015-11-13 57 views
0

我有一个用户定义的shell项目,我试图实现cat命令,但允许用户点击CTRL-/来显示下一个x行。我是新来的信号,所以我觉得我有一些语法错误的地方...Catch CTRL- signal

主...

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; 
} 
+0

唯一的问题是,当信号没有收到时,您不会减速或停止任何地方。例如,你可以使用'pause()';它只在收到信号时才会返回。然后,您将使用它来代替'if(keepRunning)'块(包括条件)。您可能希望让其他信号唤醒程序并退出循环,但如果您没有为它们设置信号处理程序,则会自动发生。也就是说,在'pause()'返回后(它总是返回一个错误状态,'errno'设置为EINTR),你可以检查'keepRunning'现在是否为1,如果不是,则退出循环。 –

+0

太棒了!谢谢!但是现在每次输入CRTL- \后都会打印'^ \',有没有办法阻止这种情况? –

+0

可能是'stty -echoctl'。这是终端驱动程序问题,而不是程序问题。 –

回答

0

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

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

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