下面有一个简单的程序,它接受HUP并继续执行execv。问题是执行execv调用之后,代码继续从HUP到来的地方。我想,在execv之后代码必须从main退出而不是从main的开头重新开始。
char* a;
char** args;
void hup_func(){
printf("aaaa\n");
if(execv(a,args))
printf("bbb\n");
}
int main(int argc,char* argv[]){
signal(SIGHUP,hup_func);
args=argv;
a=args[0];
printf("%s\n",a);
while(1){
printf("test\n");
sleep(10);
}
return 0;
}
该程序的名称是deneme1。代码的输出是我发送HUP时的输出;
./deneme1
test
test
aaa
bbbb
test.
但是我想要它,当我发送HUP时,它必须从主要的开始开始。像那样
./deneme1
test
test
aaa
bbb
./deneme1
test
...
我希望它在HUP之后的主要开头返回,而不是之前的地方
答案 0 :(得分:2)
您没有向execv
发送正确的参数,因此该函数正在退出时出错。因此,您只是退出信号处理程序,而不是使用该过程的新副本覆盖该过程。
execv
的参数签名是:
int execv(const char *path, char *const argv[]);
第二个参数应该是const
指向char
的数组,最后一个元素是NULL
指针。您为第二个参数传递的char* a
不是正确的类型。
最后,execv
不被视为asynchronous signal-safe function,因为它是姐妹函数execve
。你应该使用后者。对于任何printf
系列函数也是如此...如果您需要写入终端,请改用write
。
更新:我重新运行了您的更新代码。程序正在重新正常启动,但问题是信号掩码是从原始进程继承的,该进程由对execv
的调用覆盖。由于您从信号处理程序中运行execv
,SIGHUP
将在重叠过程中被阻止,您将无法向流程发送任何其他SIGHUP
信号。要撤消此操作,您需要在使用SIGHUP
分配信号处理程序后立即使用sigprocmask()
取消阻止signal()
信号。
例如,将main
更改为:
int main(int argc,char* argv[])
{
sigset_t signal_mask;
signal(SIGHUP,hup_func);
//unblock the SIGHUP signal if it's blocked
sigaddset(&signal_mask, SIGHUP);
sigprocmask(SIG_UNBLOCK, &signal_mask, NULL);
args=argv;
a=args[0];
printf("%s\n",a);
while(1){
printf("test\n");
sleep(10);
}
return 0;
}
我已经在Ubuntu 12.04上编译并运行它,它现在运行得很好。
答案 1 :(得分:0)
问题是当执行execv调用时,代码继续从HUP到来的地方
您的代码中没有错误检查,很可能execv()
调用失败。
尝试修改它:
char** gargv;
void hup_func() {
execvp(*gargv, gargv);
abort(); // must never get here
}
int main(int argc,char* argv[]) {
// ...
gargv = argv;
// ...
答案 2 :(得分:0)
@Jason指出, execv 失败了。用这段代码测试自己。
#include<signal.h>
char* a;
char **args;
void hup_func(){
printf("receivied SIGHUP\n");
execv(a,a);
printf("execv failed\n");
}
int main(int argc,char* argv[]){
int b =0;
printf("setting signal handler for SIGHUP\n");
signal(SIGHUP,hup_func);
args=argv;
a=argv[0];
printf("Before entering while %s\n",a);
while(1){
printf("In while %d\n",++b);
sleep(1);
}
return 0;
}
然后替换
execv(a,a);
与
execv(a,args);