2015-04-04 404 views
2

我一直在研究一個在JNI中執行其功能的Android應用程序。我的問題是在logcat顯示直到按下按鈕的函數中。我找到發生問題:如何修復讀取popen()時掛起的fgets()?

FILE *logcat = popen("su -c logcat threadtime", "r"); 

while (isRunning(running, env, thiz)) 
    if (fgets(&line, sizeof(line), logcat) != NULL) //<--- HERE 
     appendLogWithToken(logger, line, env, thiz); 

我做了一些調試,發現該fgets()休眠,直到接收到另一條線路。我已搜索並找到類似的問題,但沒有工作答案。是否還有其他函數返回null並且不等待輸入,或者是否可以修復?

+1

'fgets()'讀取(掛起)直到它獲取EOF(不再有數據並且管道的寫入結束被關閉),或者直到更多的數據到達 - 這就是設計。 logcat是退出還是永久存在?如果你想要非阻塞I/O,你可以在底層文件描述符上使用'fcntl()'來使管道非阻塞,但是你需要知道你在做什麼('clearerr()'成爲朋友)。我懷疑你有一些設計缺陷,或者你沒有仔細考慮過。您不會顯示'pclose(logcat);',例如 - 何時關閉該文件? – 2015-04-04 20:56:09

+0

在第一次檢查logcat打開或不與「if(logcat!= NULL)」 – 2015-04-04 20:57:24

+0

這將是骯髒的,但我首先使用'fileno(3)'獲取文件描述符,然後調用'select(2)或者「輪詢(2)」來檢查是否有數據。然後是一個非線性分隔符,期望讀取函數像'read(2)'來實際讀取數據。 – holgac 2015-04-04 20:57:56

回答

0

喬納森給出了一個很好的解釋,爲什麼會出現這種情況。

你的情況的一個簡單的修復就是使用logcat -d。 添加-d選項將在當前緩衝區的末尾發送EOF,並允許fgets繼續(而不是用於監視緩衝區的默認選項)

+0

感謝這工作。 – Ingvars 2015-04-04 21:48:01