我正在玩C中的信號。我的主要功能基本上要求使用fgets(name, 30, stdin)
進行一些輸入,然後坐在那裏等待。我用alarm(3)
設置了一個鬧鐘,然後我重新分配了SIGALRM來調用函數myalarm
,該函數簡單地調用system("say PAY ATTENTION")
。但是在鬧鈴響起後,fgets()
停止等待輸入,我的主要fn繼續。即使我將myalarm
更改爲只設置了一些變量並且什麼也不做,會發生這種情況。爲什麼alarm()會導致fgets()停止等待?
void myalarm(int sig) {
//system("say PAY ATTENTION");
int x = 0;
}
int catch_signal(int sig, void (*handler)(int)) { // when a signal comes in, "catch" it and "handle it" in the way you want
struct sigaction action; // create a new sigaction
action.sa_handler = handler; // set it's sa_handler attribute to the function specified in the header
sigemptyset(&action.sa_mask); // "turn all the signals in the sa_mask off?" "set the sa_mask to contian no signals, i.e. nothing is masked?"
action.sa_flags = 0; // not sure, looks like we aren't using any of the available flags, whatever they may be
return sigaction(sig, &action, NULL); // here is where you actually reassign- now when sig is received, it'll do what action tells it
}
int main() {
if(catch_signal(SIGINT, diediedie)== -1) {
fprintf(stderr, "Can't map the SIGINT handler");
exit(2);
}
if(catch_signal(SIGALRM, myalarm) == -1) {
fprintf(stderr, "Can't map the SIGALAM handler\n");
exit(2);
}
alarm(3);
char name[30];
printf("Enter your name: ");
fgets(name, 30, stdin);
printf("Hello, %s\n", name);
return 0;
}
爲什麼alarm()
使fgets()
停止等待輸入?
編輯:爲我的catch_signal
函數添加了代碼,並且根據其中一個註釋,使用sigaction
而不是signal
,但問題依然存在。
請參閱'man 7 signal',子標題爲「通過信號處理程序中斷系統調用和庫函數」 – Retr0id
我看到這一點:「如果對信號處理程序中斷了以下某個接口的阻塞呼叫,如果使用SA_RESTART標誌,則在信號處理程序返回後調用將自動重新啓動;否則調用將失敗,並顯示錯誤EINTR ...「並且fgets()未被列爲可重新啓動的函數之一。我試圖做的是不可能的? –
'fgets()'在引擎蓋下使用'read'系統調用。順便說一句,在我的系統上它不會中斷(Arch Linux x86_64) – Retr0id