2010-06-04 68 views
1

我試圖在我的編程在inittab中運行時執行固件升級。我的程序將運行2個命令。一種是從tarball中提取安裝程序腳本,另一種是執行安裝程序腳本。在我的代碼中,我正在使用system()函數調用。這些是下面的2個命令字符串,停止/ etc/inittab中的進程殺死衍生進程。在rc.local中不會發生

system ("tar zvxf tarball.tar.gz -C/installer.sh 2>&1"); 

    system("nohup installer.sh tarball >/dev/null 2>&1 &"); 

安裝程序腳本要求tarball是一個參數。我試過使用sudo,但我仍然有同樣的問題。我試過沒有成功的nohup。執行固件升級時,安裝程​​序腳本必須殺死我的程序,但安裝程序腳本將保持活動狀態。

如果我的程序是從我的目標設備上的命令行或rc.local運行的,那麼我的升級正常運行,即當我的程序被終止時,我的安裝程序腳本會繼續。

但是我需要從/ etc/inittab運行我的程序,所以如果它死了,它可以重新生成。要在inittab中停止我的程序,安裝程序腳本將散列出來並執行「telinit q」。這是我的程序死去的地方(但那就是我想要的),但它也會殺死我的安裝程序腳本。

有誰知道爲什麼會發生這種情況,我能做些什麼來解決它?

在此先感謝。

回答

0

我猜這裏發生的事情是,init不僅將SIGTERM/SIGKILL發送給進程,而且發送給整個進程組。它這樣做是爲了確保一個過程的所有孩子都得到適當的清理。當你的程序調用system()時,它將在內部做一個fork()/ exec()。這個新分叉的進程與您編程時位於同一個進程組中,因此它也會被殺死。

你可以嘗試做一個

system("setsid nohup installer.sh tarball >/dev/null 2>&1 &"); 

運行您的安裝腳本在一個新的會話。如果你的系統不提供setsid命令行工具,你可以簡單地寫你自己的。 setsid只是setsid()系統調用的一個小包裝。

+0

太棒了!非常感謝你。過去幾天我一直在摔跤。我不得不將ARM版本的「setsid」複製到我的目標上,但它可以起到一定的作用。 乾杯! – Paul 2010-06-07 11:41:22