2010-06-04 33 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