c - 在带有 busybox 的嵌入式 linux 上使用 system() 时,SIGHUP 信号处理程序重置为默认值

标签 c linux sh busybox

我正在使用 busybox 开发嵌入式 linux。作为我的应用程序的一部分,我有一个 rc.init 脚本 E80-startmyprog。该脚本正在调用我的程序 prog。

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

现在在我的程序中的某个时间我需要启动另一个进程,给它一些输入并检查它是否在标准输出上打印"is"。我正在使用系统来做到这一点。

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 手册页中,我还没有看到这样的命令行选项。)

我知道我可以做一个解决方法并设置一个管道、fork、exec second_process、将输入写入管道、从管道读取输出并解析输出,但与系统一个衬里相比,这是很多东西,而且有很好的我有可能会错过一些东西并弄错。

最佳答案

我不认为这正是正在发生的事情。当您在 shell 中键入“trap”时,您是在要求它列出为该信号建立的操作。当你调用一个子 shell 时,你没有给它任何 Action ,所以它不会显示任何(它不知道你给了它的父级什么)但这并不意味着它已经重置了 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'

关于c - 在带有 busybox 的嵌入式 linux 上使用 system() 时,SIGHUP 信号处理程序重置为默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30351750/

相关文章:

c - 使用管道在 C 中写入 openssl 的 stdio

c - 在 C 中使用 UDP 套接字的 Echo 服务器客户端

客户端读取另一个文件后没有读取任何数据

linux - bash脚本: options - case: range of multiple numbers

linux - 根据大小对文件(包括子目录中的文件)进行排序,并打印文件名和大小

c - 无符号位移运算符 [C11]

c - ANSI C 中字符的位操作

linux - 使用 sed 命令替换文件中的行

linux - bash 根据末尾的序列号删除重复文件

linux - 如何将 "curl -Is link | head -n 1"与文件中的多个链接一起使用