2015-11-13 105 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,如果不是,則退出循環。