2015-05-20 18 views
0

我正在使用busybox在嵌入式Linux上工作。作爲我的應用程序的一部分,我有一個rc.init腳本E80-startmyprog。該腳本正在調用我的程序編程。在busybox上使用嵌入式linux上的system()時,SIGHUP信號處理程序重置爲默認值

trap "" HUP 
startmyprog >${LOGFILE} 2>&1 </dev/null & 

startmyprog() { 
    prog 
} 

在我的程序中,我可以看到信號處理程序被設置爲忽略SIGHUP。我檢查與

struct sigaction act; 
sigaction(1, NULL, &act); 
printf("action %p\n", act.sa_sigaction); // prints out 1 -> SIG_IGN 

現在我在程序一段時間,我要開始另一個進程,給它一些輸入並檢查它是否印有「是」在標準輸出上。我正在使用系統來做到這一點。

const int ret = system("[ `echo input | second_process` == yes ]"); 

正常行爲是WIFEXITED(ret)是真實的,並且WEXITSTATUS(ret)爲0或1

但是在某些情況下與不幸定時WIFSIGNALED(ret)是真實WTERMSIG(ret)是1(SIGHUP)。

調試顯示如果我execl("second_process", "second_process", (char*)NULL) second_process中的信號處理程序狀態正確設置爲SIGHUP = ignore。但是如果我使用system,則second_process具有SIGHUP = default。

我的問題是:

這是怎麼回事?誰在啓動時重置SIGHUP信號處理程序?它是殼嗎?有沒有辦法阻止? (在sh手冊頁我沒有看到一個命令行選項,看起來如此。)

我知道我可以做一個解決方法並設置pipe,fork,exec second_process,將輸入寫入管道,從管道讀取輸出和解析輸出,但與一個系統相比,這是一個很大的內容,並且很有可能我會錯過某些東西並弄錯它。

+0

嘗試'strace -ff -o/tmp/foo程序' - 這會在你的程序中運行strace,遵循分支,並在/tmp/foo.NNNNN中存儲每個進程的跟蹤結果。我想你會發現系統(3)不會重置SIGHUP處理程序,但也許是別的。 –

+0

@GilHamilton好點。以前我曾經運行過strace,但僅用於其他測試。我把你的建議strace。日誌顯示產生的sh調用rt_sigaction:'rt_sigaction(SIGHUP,{0x10000000,[],0},{SIG_DFL,[],SA_NOCLDSTOP},16)= 0'。 –

回答

0

更深的挖掘是在Linux運行的busybox的來源我發現了殼busybox在初始化期間調用signal(SIGHUP, SIG_DFL);。這會將嘆息處理程序重置爲默認值。因此,shell本身及其運行的程序(隨-c ...提供)正在使用默認的SIGHUP處理程序運行。

我看不到繞過重置SIGHUP信號處理程序的代碼路徑,所以看起來我無法達到我想要的system()

1

我不認爲這正是發生了什麼事情。當你在shell中鍵入'trap'時,你要求它列出它爲該信號建立的動作。當你調用子shell時,你沒有給它任何動作,所以它不會顯示任何動作(它不知道你給它的父項),但這並不意味着它已經重置了SIGHUP狀態。

試試這個小腳本證明SIGHUP是被忽略,即使「陷阱」顯示什麼:

trap "" HUP 
echo "TRAPs in parent" 
trap 
sh -c 'echo "TRAPs in child"; trap; sleep 5; echo "Still here. Traps: "; trap' & 
child=$! 
sleep 1 
kill -HUP $child 
echo 'Killed child' 
+0

好的,所以我和我用bash觀察到的結果的比較與我用c程序和'system'觀察到的結果不一樣。我對此感到抱歉,並且會刪除bash比較部分。 –

相關問題