C 在带busybox的嵌入式linux上使用system()时,SIGHUP信号处理程序重置为默认值
我正在使用busybox开发嵌入式linux。作为应用程序的一部分,我有一个rc.init脚本E80 startmyprog。该脚本正在调用我的程序progC 在带busybox的嵌入式linux上使用system()时,SIGHUP信号处理程序重置为默认值,c,linux,sh,busybox,C,Linux,Sh,Busybox,我正在使用busybox开发嵌入式linux。作为应用程序的一部分,我有一个rc.init脚本E80 startmyprog。该脚本正在调用我的程序prog trap“HUP startmyprog>${LOGFILE}2>&1信号 现在,在我的程序中的某个时候,我需要启动另一个进程,给它一些输入,并检查它是否在标准输出上打印“是”。我正在使用这个系统来做这件事 const int ret=system(“[`echo input | second_process`==yes]”); 正常行
trap“HUP
startmyprog>${LOGFILE}2>&1信号
现在,在我的程序中的某个时候,我需要启动另一个进程,给它一些输入,并检查它是否在标准输出上打印“是”。我正在使用这个系统来做这件事
const int ret=system(“[`echo input | second_process`==yes]”);
正常行为是WIFEXITED(ret)
为真,而WEXITSTATUS(ret)
为0或1
但在某些情况下,如果时间不正确,WIFSIGNALED(ret)
为真,WTERMSIG(ret)
为1(SIGHUP)
调试表明,如果Iexecl(“第二个\u进程”、“第二个\u进程”、(char*)NULL)
第二个\u进程中的信号处理程序状态正确设置为SIGHUP=ignore。但如果我使用系统
,则第二个\u进程具有SIGHUP=default
我的问题是:
那里发生了什么事?谁在启动时重置SIGHUP信号处理程序?是贝壳吗?有没有办法防止这种情况发生?(在sh手册页中,我没有看到命令行选项看起来如此。)
我知道我可以做一个变通方法,设置管道、fork、exec second_进程、将输入写入管道、从管道读取输出和解析输出,但与system one liner相比,这是很多东西,我很有可能会错过一些东西并出错。我不认为这正是发生的事情。当您在shell中键入“trap”时,您要求它列出为该信号建立的操作。当您调用子shell时,您没有给它任何操作,因此它不会显示任何操作(它不知道您给它的父级提供了什么),但这并不意味着它已经重置了SIGHUP状态 试试这个小脚本,它可以证明SIGHUP仍然被忽略,即使“trap”没有显示任何内容:
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'
深入研究Linux上运行的busybox的源代码,我发现busybox中的shell正在调用
信号(SIGHUP,SIG_DFL)代码>在初始化期间。这将sighup处理程序重置为默认值。因此,shell本身及其运行的程序(随-c…
提供)使用默认的SIGHUP处理程序运行
我看不到绕过重置SIGHUP信号处理程序的代码路径,因此我似乎无法通过system()
实现我想要的功能,因此我与bash的比较与我在c程序和system
中观察到的不一样。很抱歉出现这种混乱,我将删除bash比较部分。请尝试strace-ff-o/tmp/foo程序
——这将在您的程序上运行strace,跟踪fork,并将每个进程的跟踪结果存储在/tmp/foo.nnn中。我想您会发现系统(3)没有重置SIGHUP处理程序,尽管可能还有其他的事情值得一提。之前,我确实运行了strace,但仅用于其他一些测试。我重播了你的建议。日志显示生成的sh调用rt_sigaction:rt_sigaction(SIGHUP,{0x10000000,[],0},{SIG_DFL,[],sau NOCLDSTOP},16)=0
。