[英]Ctrl-C eaten by getchar()
我一直在尋找解決我問題的方法很長一段時間,這就是我轉向你的原因:
考慮一下這段代碼:
static char done = 0;
static void sigHandler(void)
{
done = 1;
}
int user_input()
{
return (getchar() == 'q') ? 0 : 1;
}
int main(void)
{
signal(SIGTERM, sigHandler);
signal(SIGINT, sigHandler);
while (user_input() != 0 && !done)
usleep(1000);
printf("exiting\n");
return 0;
}
預期行為:當用戶輸入q然后輸入時,程序退出。 如果按下CTRL + C ,它將被sigHandler函數捕獲,該函數將標志'done'設置為1並退出程序。
觀察到的行為: CTRL + C字符被getchar()調用吃掉,並且從不執行sigHandler函數。 按下CTRL + C然后按Enter鍵時,將調用sigHandler函數並退出程序。
有經驗和知識的人可以幫助我嗎?
感謝您的輸入 :)
代碼實際上正在按預期工作 - 直到從user_input()
返回之后才測試done
標志,這就是為什么你需要在control-C之后輸入一個額外的字符。
如果你想在獲得control-C時中止對getchar
的調用,那么你可能不得不做一些丑陋的事情,例如使用setjmp
/ longjmp
。
Ctrl-C字符被
getchar()
調用吃掉,並且從不執行sigHandler函數。
getchar
不會吃掉Ctrl-C; 它導致傳遞信號並運行sigHandler
。 這設置done
並返回。 只有這樣才會調用getchar
,它會占用換行符, 然后檢查done
,以便程序退出。
順便說一下,信號處理程序接受一個int
參數,而不是void
。
有一種方法可以在不訴諸丑陋的黑客的情況下中止呼叫(與Paul R所說的相反)。 你應該使用sa_flags
設置為0
而不是signal()
sigaction()
signal()
。
此外,信號(2)手冊說:
避免使用 :改為使用sigaction (2)。
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
static char done = 0;
static void sigHandler(int signum)
{
done = 1;
}
int user_input()
{
return (getchar() == 'q') ? 0 : 1;
}
int main(void)
{
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = sigHandler;
sa.sa_flags = 0;// not SA_RESTART!;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
while (user_input() != 0 && !done)
usleep(1000);
printf("exiting\n");
return 0;
}
通常,在捕獲並處理信號之后,大多數(我不確定是否全部)系統調用將重新啟動。 這樣,在處理了sigint信號之后,你的getchar函數將繼續,好像什么都沒發生一樣。 您可以通過使用sa_flags=0
調用sigaction來更改此行為。
這樣,在處理SIGINT之后, getchar
將返回-1
並且errno將被設置為“Interrupted system call”(我現在不記得常量名稱)。
您還必須重寫user_input()函數來處理返回-1時的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.