2013-03-06 114 views
1

工作這個程序CTRL-C處理程序無法正常

#include <stdio.h> 
#include <signal.h> 
#include <stdlib.h> 
#include <windows.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <string.h> 
#include <fcntl.h> 

void INThandler(int);    

int main(void) 
{ 
    signal(SIGINT, INThandler);  

    char data[128]; 

    int n; 

    while((n=read(0, data, 128)) > 0) 
    { 
    if(data[n] = '\n') break; 
    } 

    data[n] ='\0'; 

    printf("%s", data); 

    return 0; 
} 

void INThandler(int sig) 
{ 
    char c; 

    signal(sig, SIG_IGN);    
    printf("OUCH, did you hit Ctrl-C?\n"  
      "Do you really want to quit? [y/n] "); 
    c = getchar();      
    if (c == 'y' || c == 'Y')   
     exit(0);      
    else 
     signal(SIGINT, INThandler); 
} 

無法處理CTRL-C,但在那輸入終止。 如果我更換由

while (1)       
Sleep(1); 

的處理函數被調用和工程處理程序安裝和收益之間的一切,但我想有閱讀()在那裏。

編輯:這個節目回首,我發現我有

if(data[n] = '\n') break; 

我寫了「=」而不是「==」,但使用後,它不能正確和我的工作不明白爲什麼。它不應該是檢測'\ n'的比較嗎? 另外,我搞砸了緩衝區,但我不能保持輸入,如果我打CTRL-C。

回答

0

這是因爲您使用的read(2)的執行不允許。下面是當我編譯你的程序,執行它,然後按^ C我得到什麼:

$ ./program 
^COUCH, did you hit Ctrl-C? 
Do you really want to quit? [y/n] y 
$ 

,或者如果我回答n並輸入一些數據:

$ ./program 
^COUCH, did you hit Ctrl-C? 
Do you really want to quit? [y/n] n 
test 
test 
$ 

由於read(2)是一個系統調用,它取決於您使用的系統。我使用Linux(3.2.0-4-686-pae),在這裏它的行爲是正確的。也許你應該考慮使用scanf(3)fread(3)而不是stdio(3)而不是你正在使用的平臺(我認爲是win32)?或者也可以使用不同的實現方式,例如從CygwinMinGW

+0

我明白了,所以它取決於SO。到目前爲止,我沒有使用Windows的問題,然後在Unix上進行測試。謝謝。 – Aleister 2013-03-06 13:35:47

1

示例代碼並沒有考慮到佔兩個問題:

  1. read()將中止它的工作,如果它的進程收到的信號(見man 2 read
  2. 它只能保證一些功能,他們可以可以從信號處理函數中調用(參見man 7 signal)。 printf()getch()不要不是屬於這組「保存」功能。

第一個問題可以通過更多不同的方式來解決,以處理read()返回的值。我應該計算已經讀取了多少數據,以及傳遞給read()的緩衝區的一些智能調整。

關於第二個問題,read()write()是選擇執行信號處理程序的輸入/輸出功能的功能,因爲它們被上面提到的手冊頁列爲「保存」功能。

相關問題